From 043cb37b161d712e1c6fe7b9aa41d7af356cf795 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Tue, 1 Apr 2008 19:40:40 +0000 Subject: [PATCH] Add predefined date ranges to the time report in the same way as the details view (closes #972). It nows defaults to 'All time'. This patch also fixes time report periods (columns) computation. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1318 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/timelog_controller.rb | 135 +++++++++++---------- app/views/timelog/_date_range.rhtml | 16 +++ app/views/timelog/details.rhtml | 18 +-- app/views/timelog/report.rhtml | 26 ++-- test/functional/timelog_controller_test.rb | 18 ++- 5 files changed, 108 insertions(+), 105 deletions(-) create mode 100644 app/views/timelog/_date_range.rhtml diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 8cfe225d1..7e2b55872 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -53,16 +53,11 @@ class TimelogController < ApplicationController @criterias.uniq! @criterias = @criterias[0,3] - @columns = (params[:period] && %w(year month week).include?(params[:period])) ? params[:period] : 'month' + @columns = (params[:columns] && %w(year month week).include?(params[:columns])) ? params[:columns] : 'month' - if params[:date_from] - begin; @date_from = params[:date_from].to_date; rescue; end - end - if params[:date_to] - begin; @date_to = params[:date_to].to_date; rescue; end - end - @date_from ||= Date.civil(Date.today.year, 1, 1) - @date_to ||= (Date.civil(Date.today.year, Date.today.month, 1) >> 1) - 1 + retrieve_date_range + @from ||= TimeEntry.minimum(:spent_on, :include => :project, :conditions => @project.project_condition(Setting.display_subprojects_issues?)) || Date.today + @to ||= TimeEntry.maximum(:spent_on, :include => :project, :conditions => @project.project_condition(Setting.display_subprojects_issues?)) || Date.today unless @criterias.empty? sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ') @@ -74,7 +69,7 @@ class TimelogController < ApplicationController sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id" sql << " WHERE (%s)" % @project.project_condition(Setting.display_subprojects_issues?) sql << " AND (%s)" % Project.allowed_to_condition(User.current, :view_time_entries) - sql << " AND spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@date_from.to_time), ActiveRecord::Base.connection.quoted_date(@date_to.to_time)] + sql << " AND spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@from.to_time), ActiveRecord::Base.connection.quoted_date(@to.to_time)] sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek" @hours = ActiveRecord::Base.connection.select_all(sql) @@ -91,22 +86,23 @@ class TimelogController < ApplicationController end @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f} - end - - @periods = [] - date_from = @date_from - # 100 columns max - while date_from < @date_to && @periods.length < 100 - case @columns - when 'year' - @periods << "#{date_from.year}" - date_from = date_from >> 12 - when 'month' - @periods << "#{date_from.year}-#{date_from.month}" - date_from = date_from >> 1 - when 'week' - @periods << "#{date_from.year}-#{date_from.cweek}" - date_from = date_from + 7 + + @periods = [] + # Date#at_beginning_of_ not supported in Rails 1.2.x + date_from = @from.to_time + # 100 columns max + while date_from <= @to.to_time && @periods.length < 100 + case @columns + when 'year' + @periods << "#{date_from.year}" + date_from = (date_from + 1.year).at_beginning_of_year + when 'month' + @periods << "#{date_from.year}-#{date_from.month}" + date_from = (date_from + 1.month).at_beginning_of_month + when 'week' + @periods << "#{date_from.year}-#{date_from.to_date.cweek}" + date_from = (date_from + 7.day).at_beginning_of_week + end end end @@ -116,52 +112,13 @@ class TimelogController < ApplicationController def details sort_init 'spent_on', 'desc' sort_update - - @free_period = false - @from, @to = nil, nil - - if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?) - case params[:period].to_s - when 'today' - @from = @to = Date.today - when 'yesterday' - @from = @to = Date.today - 1 - when 'current_week' - @from = Date.today - (Date.today.cwday - 1)%7 - @to = @from + 6 - when 'last_week' - @from = Date.today - 7 - (Date.today.cwday - 1)%7 - @to = @from + 6 - when '7_days' - @from = Date.today - 7 - @to = Date.today - when 'current_month' - @from = Date.civil(Date.today.year, Date.today.month, 1) - @to = (@from >> 1) - 1 - when 'last_month' - @from = Date.civil(Date.today.year, Date.today.month, 1) << 1 - @to = (@from >> 1) - 1 - when '30_days' - @from = Date.today - 30 - @to = Date.today - when 'current_year' - @from = Date.civil(Date.today.year, 1, 1) - @to = Date.civil(Date.today.year, 12, 31) - end - elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?)) - begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end - begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end - @free_period = true - else - # default - end - - @from, @to = @to, @from if @from && @to && @from > @to cond = ARCondition.new cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) : ["#{TimeEntry.table_name}.issue_id = ?", @issue.id]) + retrieve_date_range + if @from if @to cond << ['spent_on BETWEEN ? AND ?', @from, @to] @@ -238,4 +195,48 @@ private rescue ActiveRecord::RecordNotFound render_404 end + + # Retreive the date range based on predefined ranges or specific from/to param dates + def retrieve_date_range + @free_period = false + @from, @to = nil, nil + + if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?) + case params[:period].to_s + when 'today' + @from = @to = Date.today + when 'yesterday' + @from = @to = Date.today - 1 + when 'current_week' + @from = Date.today - (Date.today.cwday - 1)%7 + @to = @from + 6 + when 'last_week' + @from = Date.today - 7 - (Date.today.cwday - 1)%7 + @to = @from + 6 + when '7_days' + @from = Date.today - 7 + @to = Date.today + when 'current_month' + @from = Date.civil(Date.today.year, Date.today.month, 1) + @to = (@from >> 1) - 1 + when 'last_month' + @from = Date.civil(Date.today.year, Date.today.month, 1) << 1 + @to = (@from >> 1) - 1 + when '30_days' + @from = Date.today - 30 + @to = Date.today + when 'current_year' + @from = Date.civil(Date.today.year, 1, 1) + @to = Date.civil(Date.today.year, 12, 31) + end + elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?)) + begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end + begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end + @free_period = true + else + # default + end + + @from, @to = @to, @from if @from && @to && @from > @to + end end diff --git a/app/views/timelog/_date_range.rhtml b/app/views/timelog/_date_range.rhtml new file mode 100644 index 000000000..ac46fea18 --- /dev/null +++ b/app/views/timelog/_date_range.rhtml @@ -0,0 +1,16 @@ +
<%= l(:label_date_range) %> +

+<%= radio_button_tag 'period_type', '1', !@free_period %> +<%= select_tag 'period', options_for_period_select(params[:period]), + :onchange => 'this.form.onsubmit();', + :onfocus => '$("period_type_1").checked = true;' %> +

+

+<%= radio_button_tag 'period_type', '2', @free_period %> +<%= l(:label_date_from) %> +<%= text_field_tag 'from', @from, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('from') %> +<%= l(:label_date_to) %> +<%= text_field_tag 'to', @to, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('to') %> +<%= submit_tag l(:button_apply), :name => nil, :onclick => '$("period_type_2").checked = true;' %> +

+
diff --git a/app/views/timelog/details.rhtml b/app/views/timelog/details.rhtml index 89793745e..f1e80da1f 100644 --- a/app/views/timelog/details.rhtml +++ b/app/views/timelog/details.rhtml @@ -12,23 +12,7 @@ <% form_remote_tag( :url => {}, :method => :get, :update => 'content' ) do %> <%= hidden_field_tag 'project_id', params[:project_id] %> <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %> - -
<%= l(:label_date_range) %> -

-<%= radio_button_tag 'period_type', '1', !@free_period %> -<%= select_tag 'period', options_for_period_select(params[:period]), - :onchange => 'this.form.onsubmit();', - :onfocus => '$("period_type_1").checked = true;' %> -

-

-<%= radio_button_tag 'period_type', '2', @free_period %> -<%= l(:label_date_from) %> -<%= text_field_tag 'from', @from, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('from') %> -<%= l(:label_date_to) %> -<%= text_field_tag 'to', @to, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('to') %> -<%= submit_tag l(:button_apply), :name => nil, :onclick => '$("period_type_2").checked = true;' %> -

-
+<%= render :partial => 'date_range' %> <% end %>
diff --git a/app/views/timelog/report.rhtml b/app/views/timelog/report.rhtml index 2682a5cb0..2e08e5883 100644 --- a/app/views/timelog/report.rhtml +++ b/app/views/timelog/report.rhtml @@ -5,32 +5,27 @@

<%= l(:label_spent_time) %>

-<% form_remote_tag(:url => {:project_id => @project}, :update => 'content') do %> +<% form_remote_tag(:url => {}, :update => 'content') do %> <% @criterias.each do |criteria| %> <%= hidden_field_tag 'criterias[]', criteria %> <% end %> -
<%= l(:label_date_range) %> -

- <%= l(:label_date_from) %> - <%= text_field_tag 'date_from', @date_from, :size => 10 %><%= calendar_for('date_from') %> - <%= l(:label_date_to) %> - <%= text_field_tag 'date_to', @date_to, :size => 10 %><%= calendar_for('date_to') %> - <%= l(:label_details) %> - <%= select_tag 'period', options_for_select([[l(:label_year), 'year'], - [l(:label_month), 'month'], - [l(:label_week), 'week']], @columns) %> -   - <%= submit_tag l(:button_apply) %> + <%= hidden_field_tag 'project_id', params[:project_id] %> + <%= render :partial => 'date_range' %>

+

<%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'], + [l(:label_month), 'month'], + [l(:label_week), 'week']], @columns), + :onchange => "this.form.onsubmit();" %> -

<%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}), + <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}), :onchange => "this.form.onsubmit();", :style => 'width: 200px', :disabled => (@criterias.length >= 3)) %> <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :date_from => @date_from, :date_to => @date_to, :period => @columns}, :update => 'content'}, :class => 'icon icon-reload' %>

- +<% end %> + <% unless @criterias.empty? %>

<%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %>

@@ -62,4 +57,3 @@ <% end %> <% end %> -<% end %> diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb index fa4432295..9ca1a6cbf 100644 --- a/test/functional/timelog_controller_test.rb +++ b/test/functional/timelog_controller_test.rb @@ -78,17 +78,25 @@ class TimelogControllerTest < Test::Unit::TestCase assert_response :success assert_template 'report' end - + + def test_report_all_time + get :report, :project_id => 1, :criterias => ['project'] + assert_response :success + assert_template 'report' + assert_not_nil assigns(:total_hours) + assert_equal "162.90", "%.2f" % assigns(:total_hours) + end + def test_report_one_criteria - get :report, :project_id => 1, :period => 'week', :date_from => "2007-04-01", :date_to => "2007-04-30", :criterias => ['project'] + get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project'] assert_response :success assert_template 'report' assert_not_nil assigns(:total_hours) assert_equal "8.65", "%.2f" % assigns(:total_hours) - end + end def test_report_two_criterias - get :report, :project_id => 1, :period => 'month', :date_from => "2007-01-01", :date_to => "2007-12-31", :criterias => ["member", "activity"] + get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"] assert_response :success assert_template 'report' assert_not_nil assigns(:total_hours) @@ -96,7 +104,7 @@ class TimelogControllerTest < Test::Unit::TestCase end def test_report_one_criteria_no_result - get :report, :project_id => 1, :period => 'week', :date_from => "1998-04-01", :date_to => "1998-04-30", :criterias => ['project'] + get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project'] assert_response :success assert_template 'report' assert_not_nil assigns(:total_hours) -- 2.39.5