##// END OF EJS Templates
Extracted time report logic from the controller....
Jean-Philippe Lang -
r7906:caf898d7d13f
parent child
Show More
@@ -0,0 +1,164
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine
19 module Helpers
20 class TimeReport
21 attr_reader :criteria, :columns, :from, :to, :hours, :total_hours, :periods
22
23 def initialize(project, issue, criteria, columns, from, to)
24 @project = project
25 @issue = issue
26
27 @criteria = criteria || []
28 @criteria = @criteria.select{|criteria| available_criteria.has_key? criteria}
29 @criteria.uniq!
30 @criteria = @criteria[0,3]
31
32 @columns = (columns && %w(year month week day).include?(columns)) ? columns : 'month'
33 @from = from
34 @to = to
35
36 run
37 end
38
39 def available_criteria
40 @available_criteria || load_available_criteria
41 end
42
43 private
44
45 def run
46 unless @criteria.empty?
47 sql_select = @criteria.collect{|criteria| @available_criteria[criteria][:sql] + " AS " + criteria}.join(', ')
48 sql_group_by = @criteria.collect{|criteria| @available_criteria[criteria][:sql]}.join(', ')
49 sql_condition = ''
50
51 if @project.nil?
52 sql_condition = Project.allowed_to_condition(User.current, :view_time_entries)
53 elsif @issue.nil?
54 sql_condition = @project.project_condition(Setting.display_subprojects_issues?)
55 else
56 sql_condition = "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
57 end
58
59 sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
60 sql << " FROM #{TimeEntry.table_name}"
61 sql << time_report_joins
62 sql << " WHERE"
63 sql << " (%s) AND" % sql_condition
64 sql << " (spent_on BETWEEN '%s' AND '%s')" % [ActiveRecord::Base.connection.quoted_date(@from), ActiveRecord::Base.connection.quoted_date(@to)]
65 sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
66
67 @hours = ActiveRecord::Base.connection.select_all(sql)
68
69 @hours.each do |row|
70 case @columns
71 when 'year'
72 row['year'] = row['tyear']
73 when 'month'
74 row['month'] = "#{row['tyear']}-#{row['tmonth']}"
75 when 'week'
76 row['week'] = "#{row['tyear']}-#{row['tweek']}"
77 when 'day'
78 row['day'] = "#{row['spent_on']}"
79 end
80 end
81
82 @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
83
84 @periods = []
85 # Date#at_beginning_of_ not supported in Rails 1.2.x
86 date_from = @from.to_time
87 # 100 columns max
88 while date_from <= @to.to_time && @periods.length < 100
89 case @columns
90 when 'year'
91 @periods << "#{date_from.year}"
92 date_from = (date_from + 1.year).at_beginning_of_year
93 when 'month'
94 @periods << "#{date_from.year}-#{date_from.month}"
95 date_from = (date_from + 1.month).at_beginning_of_month
96 when 'week'
97 @periods << "#{date_from.year}-#{date_from.to_date.cweek}"
98 date_from = (date_from + 7.day).at_beginning_of_week
99 when 'day'
100 @periods << "#{date_from.to_date}"
101 date_from = date_from + 1.day
102 end
103 end
104 end
105 end
106
107 def load_available_criteria
108 @available_criteria = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
109 :klass => Project,
110 :label => :label_project},
111 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
112 :klass => Version,
113 :label => :label_version},
114 'category' => {:sql => "#{Issue.table_name}.category_id",
115 :klass => IssueCategory,
116 :label => :field_category},
117 'member' => {:sql => "#{TimeEntry.table_name}.user_id",
118 :klass => User,
119 :label => :label_member},
120 'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
121 :klass => Tracker,
122 :label => :label_tracker},
123 'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
124 :klass => TimeEntryActivity,
125 :label => :label_activity},
126 'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
127 :klass => Issue,
128 :label => :label_issue}
129 }
130
131 # Add list and boolean custom fields as available criteria
132 custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
133 custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
134 @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
135 :format => cf.field_format,
136 :label => cf.name}
137 end if @project
138
139 # Add list and boolean time entry custom fields
140 TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
141 @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
142 :format => cf.field_format,
143 :label => cf.name}
144 end
145
146 # Add list and boolean time entry activity custom fields
147 TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
148 @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
149 :format => cf.field_format,
150 :label => cf.name}
151 end
152
153 @available_criteria
154 end
155
156 def time_report_joins
157 sql = ''
158 sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
159 sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
160 sql
161 end
162 end
163 end
164 end
@@ -1,7 +1,6
1 1 class TimeEntryReportsController < ApplicationController
2 2 menu_item :issues
3 3 before_filter :find_optional_project
4 before_filter :load_available_criterias
5 4
6 5 helper :sort
7 6 include SortHelper
@@ -12,78 +11,12 class TimeEntryReportsController < ApplicationController
12 11 include CustomFieldsHelper
13 12
14 13 def report
15 @criterias = params[:criterias] || []
16 @criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
17 @criterias.uniq!
18 @criterias = @criterias[0,3]
19
20 @columns = (params[:columns] && %w(year month week day).include?(params[:columns])) ? params[:columns] : 'month'
21
22 14 retrieve_date_range
23
24 unless @criterias.empty?
25 sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
26 sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
27 sql_condition = ''
28
29 if @project.nil?
30 sql_condition = Project.allowed_to_condition(User.current, :view_time_entries)
31 elsif @issue.nil?
32 sql_condition = @project.project_condition(Setting.display_subprojects_issues?)
33 else
34 sql_condition = "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
35 end
36
37 sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
38 sql << " FROM #{TimeEntry.table_name}"
39 sql << time_report_joins
40 sql << " WHERE"
41 sql << " (%s) AND" % sql_condition
42 sql << " (spent_on BETWEEN '%s' AND '%s')" % [ActiveRecord::Base.connection.quoted_date(@from), ActiveRecord::Base.connection.quoted_date(@to)]
43 sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
44
45 @hours = ActiveRecord::Base.connection.select_all(sql)
46
47 @hours.each do |row|
48 case @columns
49 when 'year'
50 row['year'] = row['tyear']
51 when 'month'
52 row['month'] = "#{row['tyear']}-#{row['tmonth']}"
53 when 'week'
54 row['week'] = "#{row['tyear']}-#{row['tweek']}"
55 when 'day'
56 row['day'] = "#{row['spent_on']}"
57 end
58 end
59
60 @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
61
62 @periods = []
63 # Date#at_beginning_of_ not supported in Rails 1.2.x
64 date_from = @from.to_time
65 # 100 columns max
66 while date_from <= @to.to_time && @periods.length < 100
67 case @columns
68 when 'year'
69 @periods << "#{date_from.year}"
70 date_from = (date_from + 1.year).at_beginning_of_year
71 when 'month'
72 @periods << "#{date_from.year}-#{date_from.month}"
73 date_from = (date_from + 1.month).at_beginning_of_month
74 when 'week'
75 @periods << "#{date_from.year}-#{date_from.to_date.cweek}"
76 date_from = (date_from + 7.day).at_beginning_of_week
77 when 'day'
78 @periods << "#{date_from.to_date}"
79 date_from = date_from + 1.day
80 end
81 end
82 end
15 @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], @from, @to)
83 16
84 17 respond_to do |format|
85 18 format.html { render :layout => !request.xhr? }
86 format.csv { send_data(report_to_csv(@criterias, @periods, @hours), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
19 format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
87 20 end
88 21 end
89 22
@@ -146,64 +79,4 class TimeEntryReportsController < ApplicationController
146 79 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
147 80 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
148 81 end
149
150 def load_available_criterias
151 @available_criterias = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
152 :klass => Project,
153 :label => :label_project},
154 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
155 :klass => Version,
156 :label => :label_version},
157 'category' => {:sql => "#{Issue.table_name}.category_id",
158 :klass => IssueCategory,
159 :label => :field_category},
160 'member' => {:sql => "#{TimeEntry.table_name}.user_id",
161 :klass => User,
162 :label => :label_member},
163 'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
164 :klass => Tracker,
165 :label => :label_tracker},
166 'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
167 :klass => TimeEntryActivity,
168 :label => :label_activity},
169 'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
170 :klass => Issue,
171 :label => :label_issue}
172 }
173
174 # Add list and boolean custom fields as available criterias
175 custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
176 custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
177 @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
178 :format => cf.field_format,
179 :label => cf.name}
180 end if @project
181
182 # Add list and boolean time entry custom fields
183 TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
184 @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
185 :format => cf.field_format,
186 :label => cf.name}
187 end
188
189 # Add list and boolean time entry activity custom fields
190 TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
191 @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
192 :format => cf.field_format,
193 :label => cf.name}
194 end
195
196 call_hook(:controller_timelog_available_criterias, { :available_criterias => @available_criterias, :project => @project })
197 @available_criterias
198 end
199
200 def time_report_joins
201 sql = ''
202 sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
203 sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
204 # TODO: rename hook
205 call_hook(:controller_timelog_time_report_joins, {:sql => sql} )
206 sql
207 end
208
209 82 end
@@ -126,10 +126,10 module TimelogHelper
126 126 export
127 127 end
128 128
129 def format_criteria_value(criteria, value)
129 def format_criteria_value(criteria_options, value)
130 130 if value.blank?
131 131 l(:label_none)
132 elsif k = @available_criterias[criteria][:klass]
132 elsif k = criteria_options[:klass]
133 133 obj = k.find_by_id(value.to_i)
134 134 if obj.is_a?(Issue)
135 135 obj.visible? ? "#{obj.tracker} ##{obj.id}: #{obj.subject}" : "##{obj.id}"
@@ -137,28 +137,28 module TimelogHelper
137 137 obj
138 138 end
139 139 else
140 format_value(value, @available_criterias[criteria][:format])
140 format_value(value, criteria_options[:format])
141 141 end
142 142 end
143 143
144 def report_to_csv(criterias, periods, hours)
144 def report_to_csv(report)
145 145 decimal_separator = l(:general_csv_decimal_separator)
146 146 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
147 147 # Column headers
148 headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
149 headers += periods
148 headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
149 headers += report.periods
150 150 headers << l(:label_total)
151 151 csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
152 152 c.to_s,
153 153 l(:general_csv_encoding) ) }
154 154 # Content
155 report_criteria_to_csv(csv, criterias, periods, hours)
155 report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours)
156 156 # Total row
157 157 str_total = Redmine::CodesetUtil.from_utf8(l(:label_total), l(:general_csv_encoding))
158 row = [ str_total ] + [''] * (criterias.size - 1)
158 row = [ str_total ] + [''] * (report.criteria.size - 1)
159 159 total = 0
160 periods.each do |period|
161 sum = sum_hours(select_hours(hours, @columns, period.to_s))
160 report.periods.each do |period|
161 sum = sum_hours(select_hours(report.hours, report.columns, period.to_s))
162 162 total += sum
163 163 row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
164 164 end
@@ -168,26 +168,26 module TimelogHelper
168 168 export
169 169 end
170 170
171 def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
171 def report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours, level=0)
172 172 decimal_separator = l(:general_csv_decimal_separator)
173 hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value|
174 hours_for_value = select_hours(hours, criterias[level], value)
173 hours.collect {|h| h[criteria[level]].to_s}.uniq.each do |value|
174 hours_for_value = select_hours(hours, criteria[level], value)
175 175 next if hours_for_value.empty?
176 176 row = [''] * level
177 177 row << Redmine::CodesetUtil.from_utf8(
178 format_criteria_value(criterias[level], value).to_s,
178 format_criteria_value(available_criteria[criteria[level]], value).to_s,
179 179 l(:general_csv_encoding) )
180 row += [''] * (criterias.length - level - 1)
180 row += [''] * (criteria.length - level - 1)
181 181 total = 0
182 182 periods.each do |period|
183 sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
183 sum = sum_hours(select_hours(hours_for_value, columns, period.to_s))
184 184 total += sum
185 185 row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
186 186 end
187 187 row << ("%.2f" % total).gsub('.',decimal_separator)
188 188 csv << row
189 if criterias.length > level + 1
190 report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
189 if criteria.length > level + 1
190 report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours_for_value, level + 1)
191 191 end
192 192 end
193 193 end
@@ -1,13 +1,13
1 <% @hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value| %>
1 <% @report.hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value| %>
2 2 <% hours_for_value = select_hours(hours, criterias[level], value) -%>
3 3 <% next if hours_for_value.empty? -%>
4 4 <tr class="<%= cycle('odd', 'even') %> <%= 'last-level' unless criterias.length > level+1 %>">
5 5 <%= '<td></td>' * level %>
6 <td><%= h(format_criteria_value(criterias[level], value)) %></td>
6 <td><%= h(format_criteria_value(@report.available_criteria[criterias[level]], value)) %></td>
7 7 <%= '<td></td>' * (criterias.length - level - 1) -%>
8 8 <% total = 0 -%>
9 <% @periods.each do |period| -%>
10 <% sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s)); total += sum -%>
9 <% @report.periods.each do |period| -%>
10 <% sum = sum_hours(select_hours(hours_for_value, @report.columns, period.to_s)); total += sum -%>
11 11 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
12 12 <% end -%>
13 13 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
@@ -7,53 +7,53
7 7 <h2><%= l(:label_spent_time) %></h2>
8 8
9 9 <% form_tag({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
10 <% @criterias.each do |criteria| %>
11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
10 <% @report.criteria.each do |criterion| %>
11 <%= hidden_field_tag 'criteria[]', criterion, :id => nil %>
12 12 <% end %>
13 13 <%= render :partial => 'timelog/date_range' %>
14 14
15 15 <p><label for='columns'><%= l(:label_details) %></label>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
16 16 [l(:label_month), 'month'],
17 17 [l(:label_week), 'week'],
18 [l(:label_day_plural).titleize, 'day']], @columns),
18 [l(:label_day_plural).titleize, 'day']], @report.columns),
19 19 :onchange => "this.form.onsubmit();" %>
20 20
21 <label for='criterias'><%= l(:button_add) %></label>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
21 <label for='criterias'><%= l(:button_add) %></label>: <%= select_tag('criteria[]', options_for_select([[]] + (@report.available_criteria.keys - @report.criteria).collect{|k| [l_or_humanize(@report.available_criteria[k][:label]), k]}),
22 22 :onchange => "this.form.submit();",
23 23 :style => 'width: 200px',
24 24 :id => nil,
25 :disabled => (@criterias.length >= 3), :id => "criterias") %>
26 <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns}, :class => 'icon icon-reload' %></p>
25 :disabled => (@report.criteria.length >= 3), :id => "criterias") %>
26 <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @report.columns}, :class => 'icon icon-reload' %></p>
27 27 <% end %>
28 28
29 <% unless @criterias.empty? %>
29 <% unless @report.criteria.empty? %>
30 30 <div class="total-hours">
31 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
31 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@report.total_hours)) %></p>
32 32 </div>
33 33
34 <% unless @hours.empty? %>
34 <% unless @report.hours.empty? %>
35 35 <div class="autoscroll">
36 36 <table class="list" id="time-report">
37 37 <thead>
38 38 <tr>
39 <% @criterias.each do |criteria| %>
40 <th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th>
39 <% @report.criteria.each do |criteria| %>
40 <th><%= l_or_humanize(@report.available_criteria[criteria][:label]) %></th>
41 41 <% end %>
42 <% columns_width = (40 / (@periods.length+1)).to_i %>
43 <% @periods.each do |period| %>
42 <% columns_width = (40 / (@report.periods.length+1)).to_i %>
43 <% @report.periods.each do |period| %>
44 44 <th class="period" width="<%= columns_width %>%"><%= period %></th>
45 45 <% end %>
46 46 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
47 47 </tr>
48 48 </thead>
49 49 <tbody>
50 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
50 <%= render :partial => 'report_criteria', :locals => {:criterias => @report.criteria, :hours => @report.hours, :level => 0} %>
51 51 <tr class="total">
52 52 <td><%= l(:label_total) %></td>
53 <%= '<td></td>' * (@criterias.size - 1) %>
53 <%= '<td></td>' * (@report.criteria.size - 1) %>
54 54 <% total = 0 -%>
55 <% @periods.each do |period| -%>
56 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
55 <% @report.periods.each do |period| -%>
56 <% sum = sum_hours(select_hours(@report.hours, @report.columns, period.to_s)); total += sum -%>
57 57 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
58 58 <% end -%>
59 59 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
@@ -38,72 +38,71 class TimeEntryReportsControllerTest < ActionController::TestCase
38 38 end
39 39
40 40 def test_report_all_projects_one_criteria
41 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
41 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criteria => ['project']
42 42 assert_response :success
43 43 assert_template 'report'
44 assert_not_nil assigns(:total_hours)
45 assert_equal "8.65", "%.2f" % assigns(:total_hours)
44 assert_not_nil assigns(:report)
45 assert_equal "8.65", "%.2f" % assigns(:report).total_hours
46 46 end
47 47
48 48 def test_report_all_time
49 get :report, :project_id => 1, :criterias => ['project', 'issue']
49 get :report, :project_id => 1, :criteria => ['project', 'issue']
50 50 assert_response :success
51 51 assert_template 'report'
52 assert_not_nil assigns(:total_hours)
53 assert_equal "162.90", "%.2f" % assigns(:total_hours)
52 assert_not_nil assigns(:report)
53 assert_equal "162.90", "%.2f" % assigns(:report).total_hours
54 54 end
55 55
56 56 def test_report_all_time_by_day
57 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
57 get :report, :project_id => 1, :criteria => ['project', 'issue'], :columns => 'day'
58 58 assert_response :success
59 59 assert_template 'report'
60 assert_not_nil assigns(:total_hours)
61 assert_equal "162.90", "%.2f" % assigns(:total_hours)
60 assert_not_nil assigns(:report)
61 assert_equal "162.90", "%.2f" % assigns(:report).total_hours
62 62 assert_tag :tag => 'th', :content => '2007-03-12'
63 63 end
64 64
65 65 def test_report_one_criteria
66 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
66 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criteria => ['project']
67 67 assert_response :success
68 68 assert_template 'report'
69 assert_not_nil assigns(:total_hours)
70 assert_equal "8.65", "%.2f" % assigns(:total_hours)
69 assert_not_nil assigns(:report)
70 assert_equal "8.65", "%.2f" % assigns(:report).total_hours
71 71 end
72 72
73 def test_report_two_criterias
74 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
73 def test_report_two_criteria
74 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["member", "activity"]
75 75 assert_response :success
76 76 assert_template 'report'
77 assert_not_nil assigns(:total_hours)
78 assert_equal "162.90", "%.2f" % assigns(:total_hours)
77 assert_not_nil assigns(:report)
78 assert_equal "162.90", "%.2f" % assigns(:report).total_hours
79 79 end
80 80
81 81 def test_report_one_day
82 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
82 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criteria => ["member", "activity"]
83 83 assert_response :success
84 84 assert_template 'report'
85 assert_not_nil assigns(:total_hours)
86 assert_equal "4.25", "%.2f" % assigns(:total_hours)
85 assert_not_nil assigns(:report)
86 assert_equal "4.25", "%.2f" % assigns(:report).total_hours
87 87 end
88 88
89 89 def test_report_at_issue_level
90 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
90 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["member", "activity"]
91 91 assert_response :success
92 92 assert_template 'report'
93 assert_not_nil assigns(:total_hours)
94 assert_equal "154.25", "%.2f" % assigns(:total_hours)
93 assert_not_nil assigns(:report)
94 assert_equal "154.25", "%.2f" % assigns(:report).total_hours
95 95 assert_tag :form,
96 96 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
97 97 end
98 98
99 99 def test_report_custom_field_criteria
100 get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
100 get :report, :project_id => 1, :criteria => ['project', 'cf_1', 'cf_7']
101 101 assert_response :success
102 102 assert_template 'report'
103 assert_not_nil assigns(:total_hours)
104 assert_not_nil assigns(:criterias)
105 assert_equal 3, assigns(:criterias).size
106 assert_equal "162.90", "%.2f" % assigns(:total_hours)
103 assert_not_nil assigns(:report)
104 assert_equal 3, assigns(:report).criteria.size
105 assert_equal "162.90", "%.2f" % assigns(:report).total_hours
107 106 # Custom field column
108 107 assert_tag :tag => 'th', :content => 'Database'
109 108 # Custom field row
@@ -116,16 +115,16 class TimeEntryReportsControllerTest < ActionController::TestCase
116 115 end
117 116
118 117 def test_report_one_criteria_no_result
119 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
118 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criteria => ['project']
120 119 assert_response :success
121 120 assert_template 'report'
122 assert_not_nil assigns(:total_hours)
123 assert_equal "0.00", "%.2f" % assigns(:total_hours)
121 assert_not_nil assigns(:report)
122 assert_equal "0.00", "%.2f" % assigns(:report).total_hours
124 123 end
125 124
126 125 def test_report_all_projects_csv_export
127 126 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30",
128 :criterias => ["project", "member", "activity"], :format => "csv"
127 :criteria => ["project", "member", "activity"], :format => "csv"
129 128 assert_response :success
130 129 assert_equal 'text/csv', @response.content_type
131 130 lines = @response.body.chomp.split("\n")
@@ -139,7 +138,7 class TimeEntryReportsControllerTest < ActionController::TestCase
139 138 def test_report_csv_export
140 139 get :report, :project_id => 1, :columns => 'month',
141 140 :from => "2007-01-01", :to => "2007-06-30",
142 :criterias => ["project", "member", "activity"], :format => "csv"
141 :criteria => ["project", "member", "activity"], :format => "csv"
143 142 assert_response :success
144 143 assert_equal 'text/csv', @response.content_type
145 144 lines = @response.body.chomp.split("\n")
@@ -177,7 +176,7 class TimeEntryReportsControllerTest < ActionController::TestCase
177 176
178 177 get :report, :project_id => 1, :columns => 'day',
179 178 :from => "2011-11-11", :to => "2011-11-11",
180 :criterias => ["member"], :format => "csv"
179 :criteria => ["member"], :format => "csv"
181 180 assert_response :success
182 181 assert_equal 'text/csv', @response.content_type
183 182 lines = @response.body.chomp.split("\n")
@@ -228,7 +227,7 class TimeEntryReportsControllerTest < ActionController::TestCase
228 227
229 228 get :report, :project_id => 1, :columns => 'day',
230 229 :from => "2011-11-11", :to => "2011-11-11",
231 :criterias => ["member"], :format => "csv"
230 :criteria => ["member"], :format => "csv"
232 231 assert_response :success
233 232 assert_equal 'text/csv', @response.content_type
234 233 lines = @response.body.chomp.split("\n")
@@ -269,7 +268,7 class TimeEntryReportsControllerTest < ActionController::TestCase
269 268
270 269 get :report, :project_id => 1, :columns => 'day',
271 270 :from => "2011-11-11", :to => "2011-11-11",
272 :criterias => ["member"], :format => "csv"
271 :criteria => ["member"], :format => "csv"
273 272 assert_response :success
274 273 assert_equal 'text/csv', @response.content_type
275 274 lines = @response.body.chomp.split("\n")
General Comments 0
You need to be logged in to leave comments. Login now