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

Developer Project Company Report hours
Elida Zulauf doloribus hic corporis
Microsoft
79.0
Carlota Gottlieb odio velit repudiandae
Apple
79.0
Jamison Hagenes doloribus hic corporis
Microsoft
79.0
Isidro McCullough perspiciatis totam perferendis
Apple
78.0
Dorthey Turner vitae eum pariatur
Google
78.0
Reinaldo Heidenreich repudiandae officiis qui
Google
78.0
Micheal Jenkins vitae eum pariatur
Google
78.0
Benita Thompson quibusdam sed sit
Apple
78.0
Palmira Fay animi aperiam tenetur
Google
78.0
Thaddeus Stanton odio velit repudiandae
Apple
78.0
Raquel Runolfsson odio velit repudiandae
Apple
78.0
Eleonore Wisozk suscipit consectetur beatae
Google
78.0
Lynell Stamm repudiandae officiis qui
Google
78.0
Milagros Lemke eum amet quia
Google
78.0
Crissy Brekke vitae eum pariatur
Google
78.0
Jon Lindgren perspiciatis totam perferendis
Apple
78.0
Myrtle O'Conner vitae eum pariatur
Google
78.0
Marna Ritchie suscipit consectetur beatae
Google
78.0
Almeta Adams animi aperiam tenetur
Google
77.0
Wiley Wuckert repudiandae officiis qui
Google
77.0
Deja Corkery quibusdam sed sit
Apple
77.0
Palmira Fay perspiciatis totam perferendis
Apple
77.0
Kaye Greenfelder suscipit consectetur beatae
Google
77.0
Johnny Spinka odio velit repudiandae
Apple
77.0
Kaye Greenfelder odio velit repudiandae
Apple
77.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