Gem source code Demo source code
Author: Bogdan Gusiev

User Grid (basic) Time Entry Grid (advanced)

Time Entries Grid


Developer Project Report hours
Alise Rolfson perspiciatis totam perferendis 71.0
Bong Witting suscipit consectetur beatae 71.0
Dona Gutkowski quibusdam sed sit 71.0
Grace Kris quibusdam sed sit 72.0
Ashleigh Kris animi aperiam tenetur 72.0
Adrienne Eichmann perspiciatis totam perferendis 72.0
Mi Prosacco suscipit consectetur beatae 72.0
Rossana Schneider vitae eum pariatur 72.0
Benita Thompson vitae eum pariatur 72.0
Dona Gutkowski repudiandae officiis qui 72.0
Desmond Murray quibusdam sed sit 72.0
Tamika Cronin saepe hic temporibus 72.0
Reinaldo Heidenreich suscipit consectetur beatae 72.0
Vivien Murray odio velit repudiandae 72.0
Ethyl Ankunding repudiandae officiis qui 72.0
Lynell Stamm doloribus hic corporis 72.0
Jewell Swaniawski quibusdam sed sit 73.0
Raquel Runolfsson suscipit consectetur beatae 73.0
Jackson Kozey saepe hic temporibus 73.0
Micheal Jenkins perspiciatis totam perferendis 73.0
Nelson Leannon suscipit consectetur beatae 73.0
Jeanne Witting saepe hic temporibus 73.0
Deja Corkery saepe hic temporibus 73.0
Clifton Hintz doloribus hic corporis 73.0
Jewell Kreiger repudiandae officiis qui 73.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 => lambda {Project.all.map {|p| [p.name, p.id]}},
    :multiple => true,
    :include_blank => false
  ) do |value|
    self.where(:time_entries => {:project_id => value})
  end


  filter(:year, :enum,
         :select => lambda { TimeEntry.all.any? ? (TimeEntry.minimum(:date).year..TimeEntry.maximum(:date).year) : []},
    :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 => Date::MONTHNAMES[1..12].enum_for(:each_with_index).collect {|name, index| [name, index + 1]},
         :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)")

end

Controller:

class TimeEntriesController < ApplicationController

  def index
    @time_entries_grid = TimeEntriesGrid.new(params[:g]) do |scope|
      scope.page(params[:page] )
    end
  end
end

View:


<h3>Time Entries Grid</h3>


<div class="left">
  <%= datagrid_form_for @time_entries_grid, url: time_entries_path %>
  <br/>

  <%= datagrid_table(@time_entries_grid) %>
  <%= paginate @time_entries_grid.assets %>

</div>

<div class="right">
  <%= render :partial => "shared/source", :object => @time_entries_grid %>
</div>