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

Developer Project Company Report hours
Carlota Gottlieb doloribus hic corporis
Microsoft
80.0
Salley Kilback vitae eum pariatur
Google
80.0
Maryanna Medhurst repudiandae officiis qui
Google
80.0
Pearlie McGlynn animi aperiam tenetur
Google
80.0
Adrienne Eichmann perspiciatis totam perferendis
Apple
80.0
Gonzalo Blanda perspiciatis totam perferendis
Apple
80.0
Thaddeus Stanton animi aperiam tenetur
Google
80.0
Wen Daniel odio velit repudiandae
Apple
81.0
Royce Spencer saepe hic temporibus
Microsoft
81.0
Benita Thompson suscipit consectetur beatae
Google
81.0
Carlota Gottlieb vitae eum pariatur
Google
81.0
Milagros Lemke eum amet quia
Google
81.0
Shane Glover vitae eum pariatur
Google
81.0
Felisa Jaskolski vitae eum pariatur
Google
81.0
Micheal Jenkins repudiandae officiis qui
Google
81.0
Tess Nikolaus saepe hic temporibus
Microsoft
81.0
Li Considine quibusdam sed sit
Apple
81.0
Jewell Kreiger repudiandae officiis qui
Google
81.0
Marna Ritchie saepe hic temporibus
Microsoft
81.0
Juliana Hauck suscipit consectetur beatae
Google
81.0
Shara Labadie quibusdam sed sit
Apple
81.0
Elli Dietrich vitae eum pariatur
Google
82.0
Palmira Fay saepe hic temporibus
Microsoft
82.0
Tess Nikolaus animi aperiam tenetur
Google
82.0
Winfred Franecki eum amet quia
Google
82.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