User Grid (basic) Time Sheets Grid (advanced)

Developer Project Report hours
Verla Friesen eum amet quia 130.0
Shara Labadie animi aperiam tenetur 125.0
Marna Ritchie perspiciatis totam perferendis 125.0
Elise Waelchi vitae eum pariatur 116.0
Gwendolyn Satterfield animi aperiam tenetur 114.0
Lynell Stamm saepe hic temporibus 114.0
Maryanna Medhurst quibusdam sed sit 114.0
Verla Friesen quibusdam sed sit 113.0
Lynell Stamm animi aperiam tenetur 113.0
Brigid McLaughlin animi aperiam tenetur 112.0
Elenora Brakus saepe hic temporibus 112.0
Elli Dietrich odio velit repudiandae 111.0
Ophelia Hermiston repudiandae officiis qui 111.0
Shane Glover repudiandae officiis qui 110.0
Huong McKenzie suscipit consectetur beatae 110.0
Jackson Kozey odio velit repudiandae 110.0
Dahlia Hilll saepe hic temporibus 109.0
Claudette Hagenes perspiciatis totam perferendis 108.0
Ophelia Hermiston quibusdam sed sit 107.0
Arnita Smith doloribus hic corporis 107.0
Elsa Goodwin saepe hic temporibus 106.0
Reinaldo Heidenreich quibusdam sed sit 106.0
Malvina Zulauf quibusdam sed sit 105.0
Tamika Cronin repudiandae officiis qui 105.0
Winfred Franecki odio velit repudiandae 105.0

Grid:

class TimeEntriesGrid < BaseGrid

  #
  # 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_for @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