@@ -20,6 +20,8 class TimelogController < ApplicationController | |||||
20 | menu_item :issues |
|
20 | menu_item :issues | |
21 | before_filter :find_project, :authorize |
|
21 | before_filter :find_project, :authorize | |
22 |
|
22 | |||
|
23 | verify :method => :post, :only => :destroy, :redirect_to => { :action => :details } | |||
|
24 | ||||
23 | helper :sort |
|
25 | helper :sort | |
24 | include SortHelper |
|
26 | include SortHelper | |
25 | helper :issues |
|
27 | helper :issues | |
@@ -198,16 +200,24 class TimelogController < ApplicationController | |||||
198 | end |
|
200 | end | |
199 |
|
201 | |||
200 | def edit |
|
202 | def edit | |
201 |
render_40 |
|
203 | render_403 and return if @time_entry && !@time_entry.editable_by?(User.current) | |
202 | @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today) |
|
204 | @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today) | |
203 | @time_entry.attributes = params[:time_entry] |
|
205 | @time_entry.attributes = params[:time_entry] | |
204 | if request.post? and @time_entry.save |
|
206 | if request.post? and @time_entry.save | |
205 | flash[:notice] = l(:notice_successful_update) |
|
207 | flash[:notice] = l(:notice_successful_update) | |
206 |
redirect_to :action => 'details', :project_id => @time_entry.project |
|
208 | redirect_to :action => 'details', :project_id => @time_entry.project | |
207 | return |
|
209 | return | |
208 | end |
|
210 | end | |
209 | @activities = Enumeration::get_values('ACTI') |
|
211 | @activities = Enumeration::get_values('ACTI') | |
210 | end |
|
212 | end | |
|
213 | ||||
|
214 | def destroy | |||
|
215 | render_404 and return unless @time_entry | |||
|
216 | render_403 and return unless @time_entry.editable_by?(User.current) | |||
|
217 | @time_entry.destroy | |||
|
218 | flash[:notice] = l(:notice_successful_delete) | |||
|
219 | redirect_to :action => 'details', :project_id => @time_entry.project | |||
|
220 | end | |||
211 |
|
221 | |||
212 | private |
|
222 | private | |
213 | def find_project |
|
223 | def find_project | |
@@ -223,5 +233,7 private | |||||
223 | render_404 |
|
233 | render_404 | |
224 | return false |
|
234 | return false | |
225 | end |
|
235 | end | |
|
236 | rescue ActiveRecord::RecordNotFound | |||
|
237 | render_404 | |||
226 | end |
|
238 | end | |
227 | end |
|
239 | end |
@@ -50,7 +50,7 class TimeEntry < ActiveRecord::Base | |||||
50 |
|
50 | |||
51 | # Returns true if the time entry can be edited by usr, otherwise false |
|
51 | # Returns true if the time entry can be edited by usr, otherwise false | |
52 | def editable_by?(usr) |
|
52 | def editable_by?(usr) | |
53 | usr == self.user |
|
53 | (usr == user && usr.allowed_to?(:edit_own_time_entries, project)) || usr.allowed_to?(:edit_time_entries, project) | |
54 | end |
|
54 | end | |
55 |
|
55 | |||
56 | def self.visible_by(usr) |
|
56 | def self.visible_by(usr) |
@@ -33,7 +33,7 | |||||
33 | <td><b><%=l(:field_category)%> :</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td> |
|
33 | <td><b><%=l(:field_category)%> :</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td> | |
34 | <% if User.current.allowed_to?(:view_time_entries, @project) %> |
|
34 | <% if User.current.allowed_to?(:view_time_entries, @project) %> | |
35 | <td><b><%=l(:label_spent_time)%> :</b></td> |
|
35 | <td><b><%=l(:label_spent_time)%> :</b></td> | |
36 | <td><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td> |
|
36 | <td><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td> | |
37 | <% end %> |
|
37 | <% end %> | |
38 | </tr> |
|
38 | </tr> | |
39 | <tr> |
|
39 | <tr> |
@@ -23,9 +23,16 | |||||
23 | </td> |
|
23 | </td> | |
24 | <td class="comments"><%=h entry.comments %></td> |
|
24 | <td class="comments"><%=h entry.comments %></td> | |
25 | <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td> |
|
25 | <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td> | |
26 | <td align="center"><%= link_to_if_authorized(l(:button_edit), |
|
26 | <td align="center"> | |
27 | {:controller => 'timelog', :action => 'edit', :id => entry}, |
|
27 | <% if entry.editable_by?(User.current) -%> | |
28 | :class => 'icon icon-edit') if entry.editable_by?(User.current) %></td> |
|
28 | <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry}, | |
|
29 | :title => l(:button_edit) %> | |||
|
30 | <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry}, | |||
|
31 | :confirm => l(:text_are_you_sure), | |||
|
32 | :method => :post, | |||
|
33 | :title => l(:button_delete) %> | |||
|
34 | <% end -%> | |||
|
35 | </td> | |||
29 | </tr> |
|
36 | </tr> | |
30 | <% end -%> |
|
37 | <% end -%> | |
31 | </tbdoy> |
|
38 | </tbdoy> |
@@ -20,6 +20,7 ActionController::Routing::Routes.draw do |map| | |||||
20 | map.connect 'projects/:project_id/news/:action', :controller => 'news' |
|
20 | map.connect 'projects/:project_id/news/:action', :controller => 'news' | |
21 | map.connect 'projects/:project_id/documents/:action', :controller => 'documents' |
|
21 | map.connect 'projects/:project_id/documents/:action', :controller => 'documents' | |
22 | map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards' |
|
22 | map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards' | |
|
23 | map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog' | |||
23 | map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages' |
|
24 | map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages' | |
24 |
|
25 | |||
25 | map.with_options :controller => 'repositories' do |omap| |
|
26 | map.with_options :controller => 'repositories' do |omap| |
@@ -49,6 +49,8 Redmine::AccessControl.map do |map| | |||||
49 | map.project_module :time_tracking do |map| |
|
49 | map.project_module :time_tracking do |map| | |
50 | map.permission :log_time, {:timelog => :edit}, :require => :loggedin |
|
50 | map.permission :log_time, {:timelog => :edit}, :require => :loggedin | |
51 | map.permission :view_time_entries, :timelog => [:details, :report] |
|
51 | map.permission :view_time_entries, :timelog => [:details, :report] | |
|
52 | map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member | |||
|
53 | map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin | |||
52 | end |
|
54 | end | |
53 |
|
55 | |||
54 | map.project_module :news do |map| |
|
56 | map.project_module :news do |map| |
@@ -66,6 +66,8 roles_001: | |||||
66 | - :view_calendar |
|
66 | - :view_calendar | |
67 | - :log_time |
|
67 | - :log_time | |
68 | - :view_time_entries |
|
68 | - :view_time_entries | |
|
69 | - :edit_time_entries | |||
|
70 | - :delete_time_entries | |||
69 | - :manage_news |
|
71 | - :manage_news | |
70 | - :comment_news |
|
72 | - :comment_news | |
71 | - :view_documents |
|
73 | - :view_documents | |
@@ -106,6 +108,7 roles_002: | |||||
106 | - :view_calendar |
|
108 | - :view_calendar | |
107 | - :log_time |
|
109 | - :log_time | |
108 | - :view_time_entries |
|
110 | - :view_time_entries | |
|
111 | - :edit_own_time_entries | |||
109 | - :manage_news |
|
112 | - :manage_news | |
110 | - :comment_news |
|
113 | - :comment_news | |
111 | - :view_documents |
|
114 | - :view_documents |
@@ -22,13 +22,56 require 'timelog_controller' | |||||
22 | class TimelogController; def rescue_action(e) raise e end; end |
|
22 | class TimelogController; def rescue_action(e) raise e end; end | |
23 |
|
23 | |||
24 | class TimelogControllerTest < Test::Unit::TestCase |
|
24 | class TimelogControllerTest < Test::Unit::TestCase | |
25 | fixtures :projects, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses |
|
25 | fixtures :projects, :roles, :members, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses | |
26 |
|
26 | |||
27 | def setup |
|
27 | def setup | |
28 | @controller = TimelogController.new |
|
28 | @controller = TimelogController.new | |
29 | @request = ActionController::TestRequest.new |
|
29 | @request = ActionController::TestRequest.new | |
30 | @response = ActionController::TestResponse.new |
|
30 | @response = ActionController::TestResponse.new | |
31 | end |
|
31 | end | |
|
32 | ||||
|
33 | def test_create | |||
|
34 | @request.session[:user_id] = 3 | |||
|
35 | post :edit, :project_id => 1, | |||
|
36 | :time_entry => {:comments => 'Some work on TimelogControllerTest', | |||
|
37 | :activity_id => '10', | |||
|
38 | :spent_on => '2008-03-14', | |||
|
39 | :issue_id => '1', | |||
|
40 | :hours => '7.3'} | |||
|
41 | assert_redirected_to 'projects/ecookbook/timelog/details' | |||
|
42 | ||||
|
43 | i = Issue.find(1) | |||
|
44 | t = TimeEntry.find_by_comments('Some work on TimelogControllerTest') | |||
|
45 | assert_not_nil t | |||
|
46 | assert_equal 7.3, t.hours | |||
|
47 | assert_equal 3, t.user_id | |||
|
48 | assert_equal i, t.issue | |||
|
49 | assert_equal i.project, t.project | |||
|
50 | end | |||
|
51 | ||||
|
52 | def test_update | |||
|
53 | entry = TimeEntry.find(1) | |||
|
54 | assert_equal 1, entry.issue_id | |||
|
55 | assert_equal 2, entry.user_id | |||
|
56 | ||||
|
57 | @request.session[:user_id] = 1 | |||
|
58 | post :edit, :id => 1, | |||
|
59 | :time_entry => {:issue_id => '2', | |||
|
60 | :hours => '8'} | |||
|
61 | assert_redirected_to 'projects/ecookbook/timelog/details' | |||
|
62 | entry.reload | |||
|
63 | ||||
|
64 | assert_equal 8, entry.hours | |||
|
65 | assert_equal 2, entry.issue_id | |||
|
66 | assert_equal 2, entry.user_id | |||
|
67 | end | |||
|
68 | ||||
|
69 | def destroy | |||
|
70 | @request.session[:user_id] = 2 | |||
|
71 | post :destroy, :id => 1 | |||
|
72 | assert_redirected_to 'projects/ecookbook/timelog/details' | |||
|
73 | assert_nil TimeEntry.find_by_id(1) | |||
|
74 | end | |||
32 |
|
75 | |||
33 | def test_report_no_criteria |
|
76 | def test_report_no_criteria | |
34 | get :report, :project_id => 1 |
|
77 | get :report, :project_id => 1 |
General Comments 0
You need to be logged in to leave comments.
Login now