User Grid (basic) Time Sheets Grid (advanced)

Developer Project Report hours
Crissy Brekke saepe hic temporibus 35.0
Benita Thompson vitae eum pariatur 35.0
Jackson Kozey suscipit consectetur beatae 35.0
Kaye Greenfelder doloribus hic corporis 35.0
Ethyl Ankunding animi aperiam tenetur 34.0
Vernia Dietrich animi aperiam tenetur 34.0
Myrtle O'Conner suscipit consectetur beatae 34.0
Shane Glover suscipit consectetur beatae 34.0
Britney Ruecker vitae eum pariatur 34.0
Rebecca Rempel odio velit repudiandae 34.0
Jamison Hagenes quibusdam sed sit 34.0
Arnita Smith quibusdam sed sit 33.0
Jamie Stehr odio velit repudiandae 33.0
Milagros Lemke doloribus hic corporis 33.0
Grace Kris saepe hic temporibus 33.0
Sylvester Hane perspiciatis totam perferendis 33.0
Malvina Zulauf odio velit repudiandae 32.0
Kaye Greenfelder animi aperiam tenetur 32.0
Wiley Wuckert vitae eum pariatur 32.0
Raquel Runolfsson saepe hic temporibus 32.0
Dona Gutkowski perspiciatis totam perferendis 31.0
Lynell Stamm perspiciatis totam perferendis 31.0
Dorthey Turner animi aperiam tenetur 31.0
Malvina Zulauf quibusdam sed sit 31.0
Jamie Stehr animi aperiam tenetur 31.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