##// END OF EJS Templates
Fixed: time report doesn't take account of the project for time calculations...
Jean-Philippe Lang -
r572:184be9d0e3af
parent child
Show More
@@ -1,173 +1,174
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class TimelogController < ApplicationController
19 19 layout 'base'
20 20
21 21 before_filter :find_project
22 22 before_filter :authorize, :only => :edit
23 23 before_filter :check_project_privacy, :except => :edit
24 24
25 25 helper :sort
26 26 include SortHelper
27 27
28 28 def report
29 29 @available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
30 30 :values => @project.versions,
31 31 :label => :label_version},
32 32 'category' => {:sql => "#{Issue.table_name}.category_id",
33 33 :values => @project.issue_categories,
34 34 :label => :field_category},
35 35 'member' => {:sql => "#{TimeEntry.table_name}.user_id",
36 36 :values => @project.users,
37 37 :label => :label_member},
38 38 'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
39 39 :values => Tracker.find(:all),
40 40 :label => :label_tracker},
41 41 'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
42 42 :values => Enumeration::get_values('ACTI'),
43 43 :label => :label_activity}
44 44 }
45 45
46 46 @criterias = params[:criterias] || []
47 47 @criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
48 48 @criterias.uniq!
49 49
50 50 @columns = (params[:period] && %w(year month week).include?(params[:period])) ? params[:period] : 'month'
51 51
52 52 if params[:date_from]
53 53 begin; @date_from = params[:date_from].to_date; rescue; end
54 54 end
55 55 if params[:date_to]
56 56 begin; @date_to = params[:date_to].to_date; rescue; end
57 57 end
58 58 @date_from ||= Date.civil(Date.today.year, 1, 1)
59 59 @date_to ||= Date.civil(Date.today.year, Date.today.month+1, 1) - 1
60 60
61 61 unless @criterias.empty?
62 62 sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
63 63 sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
64 64
65 65 sql = "SELECT #{sql_select}, tyear, tmonth, tweek, SUM(hours) AS hours"
66 66 sql << " FROM #{TimeEntry.table_name} LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
67 sql << " WHERE spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@date_from.to_time), ActiveRecord::Base.connection.quoted_date(@date_to.to_time)]
67 sql << " WHERE #{TimeEntry.table_name}.project_id = %s" % @project.id
68 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)]
68 69 sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek"
69 70
70 71 @hours = ActiveRecord::Base.connection.select_all(sql)
71 72
72 73 @hours.each do |row|
73 74 case @columns
74 75 when 'year'
75 76 row['year'] = row['tyear']
76 77 when 'month'
77 78 row['month'] = "#{row['tyear']}-#{row['tmonth']}"
78 79 when 'week'
79 80 row['week'] = "#{row['tyear']}-#{row['tweek']}"
80 81 end
81 82 end
82 83 end
83 84
84 85 @periods = []
85 86 date_from = @date_from
86 87 # 100 columns max
87 88 while date_from < @date_to && @periods.length < 100
88 89 case @columns
89 90 when 'year'
90 91 @periods << "#{date_from.year}"
91 92 date_from = date_from >> 12
92 93 when 'month'
93 94 @periods << "#{date_from.year}-#{date_from.month}"
94 95 date_from = date_from >> 1
95 96 when 'week'
96 97 @periods << "#{date_from.year}-#{date_from.cweek}"
97 98 date_from = date_from + 7
98 99 end
99 100 end
100 101
101 102 render :layout => false if request.xhr?
102 103 end
103 104
104 105 def details
105 106 sort_init 'spent_on', 'desc'
106 107 sort_update
107 108
108 109 @entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause)
109 110
110 111 @total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours }
111 112 @owner_id = logged_in_user ? logged_in_user.id : 0
112 113
113 114 send_csv and return if 'csv' == params[:export]
114 115 render :action => 'details', :layout => false if request.xhr?
115 116 end
116 117
117 118 def edit
118 119 render_404 and return if @time_entry && @time_entry.user != logged_in_user
119 120 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
120 121 @time_entry.attributes = params[:time_entry]
121 122 if request.post? and @time_entry.save
122 123 flash[:notice] = l(:notice_successful_update)
123 124 redirect_to :action => 'details', :project_id => @time_entry.project, :issue_id => @time_entry.issue
124 125 return
125 126 end
126 127 @activities = Enumeration::get_values('ACTI')
127 128 end
128 129
129 130 private
130 131 def find_project
131 132 if params[:id]
132 133 @time_entry = TimeEntry.find(params[:id])
133 134 @project = @time_entry.project
134 135 elsif params[:issue_id]
135 136 @issue = Issue.find(params[:issue_id])
136 137 @project = @issue.project
137 138 elsif params[:project_id]
138 139 @project = Project.find(params[:project_id])
139 140 else
140 141 render_404
141 142 return false
142 143 end
143 144 end
144 145
145 146 def send_csv
146 147 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
147 148 export = StringIO.new
148 149 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
149 150 # csv header fields
150 151 headers = [l(:field_spent_on),
151 152 l(:field_user),
152 153 l(:field_activity),
153 154 l(:field_issue),
154 155 l(:field_hours),
155 156 l(:field_comments)
156 157 ]
157 158 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
158 159 # csv lines
159 160 @entries.each do |entry|
160 161 fields = [l_date(entry.spent_on),
161 162 entry.user.name,
162 163 entry.activity.name,
163 164 (entry.issue ? entry.issue.id : nil),
164 165 entry.hours,
165 166 entry.comments
166 167 ]
167 168 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
168 169 end
169 170 end
170 171 export.rewind
171 172 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
172 173 end
173 174 end
General Comments 0
You need to be logged in to leave comments. Login now