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

Developer Project Company Report hours
Clifton Hintz doloribus hic corporis
Microsoft
73.0
Crissy Brekke saepe hic temporibus
Microsoft
73.0
Jewell Kreiger repudiandae officiis qui
Google
73.0
Lesia Hyatt odio velit repudiandae
Apple
73.0
Nelson Leannon suscipit consectetur beatae
Google
73.0
Claudette Hagenes perspiciatis totam perferendis
Apple
73.0
Salley Kilback quibusdam sed sit
Apple
73.0
Jackson Kozey saepe hic temporibus
Microsoft
73.0
Alise Rolfson suscipit consectetur beatae
Google
73.0
Ashleigh Kris animi aperiam tenetur
Google
72.0
Grace Kris quibusdam sed sit
Apple
72.0
Ethyl Ankunding repudiandae officiis qui
Google
72.0
Lynell Stamm doloribus hic corporis
Microsoft
72.0
Adrienne Eichmann perspiciatis totam perferendis
Apple
72.0
Mi Prosacco suscipit consectetur beatae
Google
72.0
Vivien Murray odio velit repudiandae
Apple
72.0
Rossana Schneider vitae eum pariatur
Google
72.0
Benita Thompson vitae eum pariatur
Google
72.0
Tamika Cronin saepe hic temporibus
Microsoft
72.0
Dona Gutkowski repudiandae officiis qui
Google
72.0
Desmond Murray quibusdam sed sit
Apple
72.0
Reinaldo Heidenreich suscipit consectetur beatae
Google
72.0
Arnita Smith perspiciatis totam perferendis
Apple
71.0
Alise Rolfson perspiciatis totam perferendis
Apple
71.0
Jackson Kozey eum amet quia
Google
71.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