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

Developer Project Company Report hours
Britney Ruecker animi aperiam tenetur
Google
64.0
Cristopher Dooley vitae eum pariatur
Google
64.0
Tess Nikolaus vitae eum pariatur
Google
64.0
Gonzalo Blanda saepe hic temporibus
Microsoft
64.0
Evangelina Pfeffer animi aperiam tenetur
Google
64.0
Tamera Bogan eum amet quia
Google
64.0
Kaye Greenfelder quibusdam sed sit
Apple
64.0
Sixta Bashirian saepe hic temporibus
Microsoft
64.0
Terisa Ruecker saepe hic temporibus
Microsoft
64.0
Palmira Fay suscipit consectetur beatae
Google
65.0
Reinaldo Heidenreich doloribus hic corporis
Microsoft
65.0
Elenora Brakus animi aperiam tenetur
Google
65.0
Almeta Adams quibusdam sed sit
Apple
65.0
Vivien Murray repudiandae officiis qui
Google
65.0
Tami Gibson animi aperiam tenetur
Google
65.0
Elisa Wintheiser repudiandae officiis qui
Google
65.0
Evangelina Pfeffer quibusdam sed sit
Apple
65.0
Treena Wolf saepe hic temporibus
Microsoft
65.0
Arnita Smith eum amet quia
Google
65.0
Mi Prosacco suscipit consectetur beatae
Google
65.0
Shara Labadie eum amet quia
Google
65.0
Elisa Wintheiser quibusdam sed sit
Apple
65.0
Juliana Hauck vitae eum pariatur
Google
65.0
German Murphy repudiandae officiis qui
Google
66.0
Jamie Stehr vitae eum pariatur
Google
66.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