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

Developer Project Company Report hours
Crissy Brekke perspiciatis totam perferendis
Apple
84.0
Clifton Hintz repudiandae officiis qui
Google
83.0
Bok Wolf eum amet quia
Google
83.0
Jewell Swaniawski perspiciatis totam perferendis
Apple
83.0
Rossana Schneider quibusdam sed sit
Apple
83.0
Jamison Hagenes suscipit consectetur beatae
Google
83.0
Jewell Kreiger odio velit repudiandae
Apple
83.0
Lynell Stamm animi aperiam tenetur
Google
82.0
Kellie Cassin suscipit consectetur beatae
Google
82.0
Brigid McLaughlin eum amet quia
Google
82.0
Desmond Murray odio velit repudiandae
Apple
82.0
Wen Daniel odio velit repudiandae
Apple
82.0
Tess Nikolaus repudiandae officiis qui
Google
82.0
German Murphy doloribus hic corporis
Microsoft
82.0
Myriam Von quibusdam sed sit
Apple
82.0
Myriam Von saepe hic temporibus
Microsoft
82.0
Dahlia Hilll suscipit consectetur beatae
Google
82.0
Elsa Goodwin vitae eum pariatur
Google
82.0
Alex Legros doloribus hic corporis
Microsoft
82.0
Malvina Zulauf saepe hic temporibus
Microsoft
82.0
Pearlie McGlynn doloribus hic corporis
Microsoft
81.0
Clifton Hintz quibusdam sed sit
Apple
81.0
Carlota Gottlieb suscipit consectetur beatae
Google
81.0
Blake Hoppe repudiandae officiis qui
Google
81.0
Adrienne Eichmann saepe hic temporibus
Microsoft
81.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