Users (Basic) Time Sheets (Advanced) Issues (API)

Developer Project Company Report hours
Vivien Murray doloribus hic corporis
Microsoft
72.0
Desmond Murray quibusdam sed sit
Apple
72.0
Deja Corkery quibusdam sed sit
Apple
72.0
Tamika Cronin perspiciatis totam perferendis
Apple
72.0
Kaye Greenfelder eum amet quia
Google
72.0
Alex Legros suscipit consectetur beatae
Google
72.0
Elida Zulauf saepe hic temporibus
Microsoft
72.0
Palmira Fay doloribus hic corporis
Microsoft
72.0
Treena Wolf animi aperiam tenetur
Google
72.0
Cristopher Dooley vitae eum pariatur
Google
72.0
Adrienne Eichmann repudiandae officiis qui
Google
72.0
Grace Kris suscipit consectetur beatae
Google
72.0
Joelle Hodkiewicz vitae eum pariatur
Google
72.0
Dorthey Turner doloribus hic corporis
Microsoft
72.0
Elenora Brakus eum amet quia
Google
72.0
Blake Hoppe odio velit repudiandae
Apple
73.0
Penney Schowalter quibusdam sed sit
Apple
73.0
Rebecca Rempel doloribus hic corporis
Microsoft
73.0
Myrtle O'Conner quibusdam sed sit
Apple
73.0
Wiley Wuckert perspiciatis totam perferendis
Apple
73.0
Raquel Runolfsson repudiandae officiis qui
Google
73.0
Brigid McLaughlin eum amet quia
Google
73.0
Carlota Gottlieb perspiciatis totam perferendis
Apple
73.0
Lillie Hamill saepe hic temporibus
Microsoft
73.0
Rossana Schneider perspiciatis totam perferendis
Apple
73.0

Grid:

class TimeEntriesGrid < ApplicationGrid

  #
  # Scope
  #

  scope do
    User.select(
      "users.name",
      "projects.name as project_name",
      "accounts.name as account_name",
      "sum(time_entries.hours) as report_hours"
    ).joins(
      time_entries: {project: :account}
    ).group("projects.name", "users.name", "accounts.name").
    order("users.name")
  end


  #
  # Filters
  #

  filter(
    :project_id, :enum,
    :select => :project_id_select,
    :multiple => true,
    :include_blank => false
  ) do |value|
    self.where(:time_entries => {:project_id => value})
  end


  filter(
    :year, :enum,
    :select => :year_select,
    :include_blank => false,
    :default => lambda {Date.today.year}
  ) do |value|
    self.where([
      "extract(year from time_entries.date) = ?",
      value.to_i
    ])
  end

  filter(
    :month, :enum,
    :select => :month_select,
    :include_blank => false,
    :default => lambda {Date.today.month}
  ) do |value|

    self.where([
      "extract(month from time_entries.date) = ?",
      value.to_i
    ])
  end


  #
  # Columns
  #

  column(:user_name, :header => "Developer", :order => "users.name") do
    self.name
  end
  column(:project_name, :header => "Project", :order => "projects.name")
  column(
    :account_name,
    :header => "Company",
    :order => "accounts.name",
  ) do |model|
    format(model.account_name) do
      render :partial => "time_entries/company", :locals => {:model => model}
    end
  end

  column(:report_hours, order: "sum(time_entries.hours)")

  protected

  def year_select
    TimeEntry.all.any? ? (TimeEntry.minimum(:date).year..TimeEntry.maximum(:date).year) : []
  end
  def month_select
    Date::MONTHNAMES[1..12].enum_for(:each_with_index).collect {|name, index| [name, index + 1]}
  end

  def project_id_select
    Project.all.map {|p| [p.name, p.id]}
  end
end

Controller:

class TimeEntriesController < ApplicationController

  def index
    @time_entries_grid = TimeEntriesGrid.new(params[:g]) do |scope|
      scope.page(params[:page] )
    end
  end
end

View:

.grid-index-grid
  %div{class: 'overflow-x-auto p-4'}
    = datagrid_form_with model: @time_entries_grid, url: time_entries_path
    %br/
    = datagrid_table(@time_entries_grid)
    = paginate @time_entries_grid.assets, window: 2
  %div
    = render :partial => "shared/source", :object => @time_entries_grid