User Grid (basic) Time Sheets Grid (advanced)

Developer Project Report hours
Tess Nikolaus repudiandae officiis qui 47.0
Alise Rolfson repudiandae officiis qui 47.0
Ashleigh Kris saepe hic temporibus 47.0
Ophelia Hermiston saepe hic temporibus 47.0
Imelda Heidenreich odio velit repudiandae 48.0
Jamie Stehr quibusdam sed sit 48.0
Elise Waelchi eum amet quia 48.0
Malvina Zulauf repudiandae officiis qui 48.0
Gwendolyn Satterfield saepe hic temporibus 48.0
Benita Thompson eum amet quia 48.0
Cathey Prohaska suscipit consectetur beatae 48.0
Vivien Murray saepe hic temporibus 48.0
Elisa Wintheiser suscipit consectetur beatae 48.0
Elsa Goodwin saepe hic temporibus 48.0
Mi Prosacco animi aperiam tenetur 48.0
Jarvis Ryan vitae eum pariatur 48.0
Isidro McCullough eum amet quia 48.0
Jewell Swaniawski vitae eum pariatur 48.0
Brigid McLaughlin eum amet quia 48.0
Adrienne Eichmann repudiandae officiis qui 48.0
Britney Ruecker odio velit repudiandae 48.0
Ophelia Hermiston eum amet quia 49.0
Verla Friesen saepe hic temporibus 49.0
Bok Wolf vitae eum pariatur 49.0
Lesia Hyatt quibusdam sed sit 49.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