##// END OF EJS Templates
Fixes test failure in r4461....
Jean-Philippe Lang -
r4348:37ed02553aee
parent child
Show More
@@ -1,274 +1,274
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class TimelogController < ApplicationController
18 class TimelogController < ApplicationController
19 menu_item :issues
19 menu_item :issues
20 before_filter :find_project, :only => [:new, :create]
20 before_filter :find_project, :only => [:new, :create]
21 before_filter :find_time_entry, :only => [:show, :edit, :update, :destroy]
21 before_filter :find_time_entry, :only => [:show, :edit, :update, :destroy]
22 before_filter :authorize, :except => [:index]
22 before_filter :authorize, :except => [:index]
23 before_filter :find_optional_project, :only => [:index]
23 before_filter :find_optional_project, :only => [:index]
24 accept_key_auth :index, :show, :create, :update, :destroy
24 accept_key_auth :index, :show, :create, :update, :destroy
25
25
26 helper :sort
26 helper :sort
27 include SortHelper
27 include SortHelper
28 helper :issues
28 helper :issues
29 include TimelogHelper
29 include TimelogHelper
30 helper :custom_fields
30 helper :custom_fields
31 include CustomFieldsHelper
31 include CustomFieldsHelper
32
32
33 def index
33 def index
34 sort_init 'spent_on', 'desc'
34 sort_init 'spent_on', 'desc'
35 sort_update 'spent_on' => 'spent_on',
35 sort_update 'spent_on' => 'spent_on',
36 'user' => 'user_id',
36 'user' => 'user_id',
37 'activity' => 'activity_id',
37 'activity' => 'activity_id',
38 'project' => "#{Project.table_name}.name",
38 'project' => "#{Project.table_name}.name",
39 'issue' => 'issue_id',
39 'issue' => 'issue_id',
40 'hours' => 'hours'
40 'hours' => 'hours'
41
41
42 cond = ARCondition.new
42 cond = ARCondition.new
43 if @project.nil?
43 if @project.nil?
44 cond << Project.allowed_to_condition(User.current, :view_time_entries)
44 cond << Project.allowed_to_condition(User.current, :view_time_entries)
45 elsif @issue.nil?
45 elsif @issue.nil?
46 cond << @project.project_condition(Setting.display_subprojects_issues?)
46 cond << @project.project_condition(Setting.display_subprojects_issues?)
47 else
47 else
48 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
48 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
49 end
49 end
50
50
51 retrieve_date_range
51 retrieve_date_range
52 cond << ['spent_on BETWEEN ? AND ?', @from, @to]
52 cond << ['spent_on BETWEEN ? AND ?', @from, @to]
53
53
54 TimeEntry.visible_by(User.current) do
54 TimeEntry.visible_by(User.current) do
55 respond_to do |format|
55 respond_to do |format|
56 format.html {
56 format.html {
57 # Paginate results
57 # Paginate results
58 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
58 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
59 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
59 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
60 @entries = TimeEntry.find(:all,
60 @entries = TimeEntry.find(:all,
61 :include => [:project, :activity, :user, {:issue => :tracker}],
61 :include => [:project, :activity, :user, {:issue => :tracker}],
62 :conditions => cond.conditions,
62 :conditions => cond.conditions,
63 :order => sort_clause,
63 :order => sort_clause,
64 :limit => @entry_pages.items_per_page,
64 :limit => @entry_pages.items_per_page,
65 :offset => @entry_pages.current.offset)
65 :offset => @entry_pages.current.offset)
66 @total_hours = TimeEntry.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f
66 @total_hours = TimeEntry.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f
67
67
68 render :layout => !request.xhr?
68 render :layout => !request.xhr?
69 }
69 }
70 format.api {
70 format.api {
71 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
71 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
72 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
72 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
73 @entries = TimeEntry.find(:all,
73 @entries = TimeEntry.find(:all,
74 :include => [:project, :activity, :user, {:issue => :tracker}],
74 :include => [:project, :activity, :user, {:issue => :tracker}],
75 :conditions => cond.conditions,
75 :conditions => cond.conditions,
76 :order => sort_clause,
76 :order => sort_clause,
77 :limit => @entry_pages.items_per_page,
77 :limit => @entry_pages.items_per_page,
78 :offset => @entry_pages.current.offset)
78 :offset => @entry_pages.current.offset)
79
79
80 render :template => 'timelog/index.apit'
80 render :template => 'timelog/index.apit'
81 }
81 }
82 format.atom {
82 format.atom {
83 entries = TimeEntry.find(:all,
83 entries = TimeEntry.find(:all,
84 :include => [:project, :activity, :user, {:issue => :tracker}],
84 :include => [:project, :activity, :user, {:issue => :tracker}],
85 :conditions => cond.conditions,
85 :conditions => cond.conditions,
86 :order => "#{TimeEntry.table_name}.created_on DESC",
86 :order => "#{TimeEntry.table_name}.created_on DESC",
87 :limit => Setting.feeds_limit.to_i)
87 :limit => Setting.feeds_limit.to_i)
88 render_feed(entries, :title => l(:label_spent_time))
88 render_feed(entries, :title => l(:label_spent_time))
89 }
89 }
90 format.csv {
90 format.csv {
91 # Export all entries
91 # Export all entries
92 @entries = TimeEntry.find(:all,
92 @entries = TimeEntry.find(:all,
93 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
93 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
94 :conditions => cond.conditions,
94 :conditions => cond.conditions,
95 :order => sort_clause)
95 :order => sort_clause)
96 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv')
96 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv')
97 }
97 }
98 end
98 end
99 end
99 end
100 end
100 end
101
101
102 def show
102 def show
103 respond_to do |format|
103 respond_to do |format|
104 # TODO: Implement html response
104 # TODO: Implement html response
105 format.html { render :nothing => true, :status => 406 }
105 format.html { render :nothing => true, :status => 406 }
106 format.api { render :template => 'timelog/show.apit' }
106 format.api { render :template => 'timelog/show.apit' }
107 end
107 end
108 end
108 end
109
109
110 def new
110 def new
111 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
111 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
112 @time_entry.attributes = params[:time_entry]
112 @time_entry.attributes = params[:time_entry]
113
113
114 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
114 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
115 render :action => 'edit'
115 render :action => 'edit'
116 end
116 end
117
117
118 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
118 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
119 def create
119 def create
120 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
120 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
121 @time_entry.attributes = params[:time_entry]
121 @time_entry.attributes = params[:time_entry]
122
122
123 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
123 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
124
124
125 if @time_entry.save
125 if @time_entry.save
126 respond_to do |format|
126 respond_to do |format|
127 format.html {
127 format.html {
128 flash[:notice] = l(:notice_successful_update)
128 flash[:notice] = l(:notice_successful_update)
129 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
129 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
130 }
130 }
131 format.api { render :template => 'timelog/show.apit', :status => :created, :location => time_entry_url(@time_entry) }
131 format.api { render :template => 'timelog/show.apit', :status => :created, :location => time_entry_url(@time_entry) }
132 end
132 end
133 else
133 else
134 respond_to do |format|
134 respond_to do |format|
135 format.html { render :action => 'edit' }
135 format.html { render :action => 'edit' }
136 format.api { render_validation_errors(@time_entry) }
136 format.api { render_validation_errors(@time_entry) }
137 end
137 end
138 end
138 end
139 end
139 end
140
140
141 def edit
141 def edit
142 @time_entry.attributes = params[:time_entry]
142 @time_entry.attributes = params[:time_entry]
143
143
144 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
144 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
145 end
145 end
146
146
147 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
147 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
148 def update
148 def update
149 @time_entry.attributes = params[:time_entry]
149 @time_entry.attributes = params[:time_entry]
150
150
151 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
151 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
152
152
153 if @time_entry.save
153 if @time_entry.save
154 respond_to do |format|
154 respond_to do |format|
155 format.html {
155 format.html {
156 flash[:notice] = l(:notice_successful_update)
156 flash[:notice] = l(:notice_successful_update)
157 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
157 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
158 }
158 }
159 format.api { head :ok }
159 format.api { head :ok }
160 end
160 end
161 else
161 else
162 respond_to do |format|
162 respond_to do |format|
163 format.html { render :action => 'edit' }
163 format.html { render :action => 'edit' }
164 format.api { render_validation_errors(@time_entry) }
164 format.api { render_validation_errors(@time_entry) }
165 end
165 end
166 end
166 end
167 end
167 end
168
168
169 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
169 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
170 def destroy
170 def destroy
171 if @time_entry.destroy && @time_entry.destroyed?
171 if @time_entry.destroy && @time_entry.destroyed?
172 respond_to do |format|
172 respond_to do |format|
173 format.html {
173 format.html {
174 flash[:notice] = l(:notice_successful_delete)
174 flash[:notice] = l(:notice_successful_delete)
175 redirect_to :back
175 redirect_to :back
176 }
176 }
177 format.api { head :ok }
177 format.api { head :ok }
178 end
178 end
179 else
179 else
180 respond_to do |format|
180 respond_to do |format|
181 format.html {
181 format.html {
182 flash[:notice] = l(:notice_unable_delete_time_entry)
182 flash[:error] = l(:notice_unable_delete_time_entry)
183 redirect_to :back
183 redirect_to :back
184 }
184 }
185 format.api { render_validation_errors(@time_entry) }
185 format.api { render_validation_errors(@time_entry) }
186 end
186 end
187 end
187 end
188 rescue ::ActionController::RedirectBackError
188 rescue ::ActionController::RedirectBackError
189 redirect_to :action => 'index', :project_id => @time_entry.project
189 redirect_to :action => 'index', :project_id => @time_entry.project
190 end
190 end
191
191
192 private
192 private
193 def find_time_entry
193 def find_time_entry
194 @time_entry = TimeEntry.find(params[:id])
194 @time_entry = TimeEntry.find(params[:id])
195 unless @time_entry.editable_by?(User.current)
195 unless @time_entry.editable_by?(User.current)
196 render_403
196 render_403
197 return false
197 return false
198 end
198 end
199 @project = @time_entry.project
199 @project = @time_entry.project
200 rescue ActiveRecord::RecordNotFound
200 rescue ActiveRecord::RecordNotFound
201 render_404
201 render_404
202 end
202 end
203
203
204 def find_project
204 def find_project
205 if issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])
205 if issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])
206 @issue = Issue.find(issue_id)
206 @issue = Issue.find(issue_id)
207 @project = @issue.project
207 @project = @issue.project
208 elsif project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])
208 elsif project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])
209 @project = Project.find(project_id)
209 @project = Project.find(project_id)
210 else
210 else
211 render_404
211 render_404
212 return false
212 return false
213 end
213 end
214 rescue ActiveRecord::RecordNotFound
214 rescue ActiveRecord::RecordNotFound
215 render_404
215 render_404
216 end
216 end
217
217
218 def find_optional_project
218 def find_optional_project
219 if !params[:issue_id].blank?
219 if !params[:issue_id].blank?
220 @issue = Issue.find(params[:issue_id])
220 @issue = Issue.find(params[:issue_id])
221 @project = @issue.project
221 @project = @issue.project
222 elsif !params[:project_id].blank?
222 elsif !params[:project_id].blank?
223 @project = Project.find(params[:project_id])
223 @project = Project.find(params[:project_id])
224 end
224 end
225 deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
225 deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
226 end
226 end
227
227
228 # Retrieves the date range based on predefined ranges or specific from/to param dates
228 # Retrieves the date range based on predefined ranges or specific from/to param dates
229 def retrieve_date_range
229 def retrieve_date_range
230 @free_period = false
230 @free_period = false
231 @from, @to = nil, nil
231 @from, @to = nil, nil
232
232
233 if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
233 if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
234 case params[:period].to_s
234 case params[:period].to_s
235 when 'today'
235 when 'today'
236 @from = @to = Date.today
236 @from = @to = Date.today
237 when 'yesterday'
237 when 'yesterday'
238 @from = @to = Date.today - 1
238 @from = @to = Date.today - 1
239 when 'current_week'
239 when 'current_week'
240 @from = Date.today - (Date.today.cwday - 1)%7
240 @from = Date.today - (Date.today.cwday - 1)%7
241 @to = @from + 6
241 @to = @from + 6
242 when 'last_week'
242 when 'last_week'
243 @from = Date.today - 7 - (Date.today.cwday - 1)%7
243 @from = Date.today - 7 - (Date.today.cwday - 1)%7
244 @to = @from + 6
244 @to = @from + 6
245 when '7_days'
245 when '7_days'
246 @from = Date.today - 7
246 @from = Date.today - 7
247 @to = Date.today
247 @to = Date.today
248 when 'current_month'
248 when 'current_month'
249 @from = Date.civil(Date.today.year, Date.today.month, 1)
249 @from = Date.civil(Date.today.year, Date.today.month, 1)
250 @to = (@from >> 1) - 1
250 @to = (@from >> 1) - 1
251 when 'last_month'
251 when 'last_month'
252 @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
252 @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
253 @to = (@from >> 1) - 1
253 @to = (@from >> 1) - 1
254 when '30_days'
254 when '30_days'
255 @from = Date.today - 30
255 @from = Date.today - 30
256 @to = Date.today
256 @to = Date.today
257 when 'current_year'
257 when 'current_year'
258 @from = Date.civil(Date.today.year, 1, 1)
258 @from = Date.civil(Date.today.year, 1, 1)
259 @to = Date.civil(Date.today.year, 12, 31)
259 @to = Date.civil(Date.today.year, 12, 31)
260 end
260 end
261 elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
261 elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
262 begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
262 begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
263 begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
263 begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
264 @free_period = true
264 @free_period = true
265 else
265 else
266 # default
266 # default
267 end
267 end
268
268
269 @from, @to = @to, @from if @from && @to && @from > @to
269 @from, @to = @to, @from if @from && @to && @from > @to
270 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
270 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
271 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
271 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
272 end
272 end
273
273
274 end
274 end
General Comments 0
You need to be logged in to leave comments. Login now