diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 695ca1dec2..0e28470b07 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -189,6 +189,8 @@ class ProjectsController < ApplicationController if User.current.allowed_to_view_all_time_entries?(@project) @total_hours = TimeEntry.visible.where(cond).sum(:hours).to_f + end + if User.current.allowed_to?(:view_estimated_hours, @project) @total_estimated_hours = Issue.visible.where(cond).sum(:estimated_hours).to_f end diff --git a/app/models/issue.rb b/app/models/issue.rb index 84907a475f..26ecf1a6e5 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -490,7 +490,6 @@ class Issue < ActiveRecord::Base 'start_date', 'due_date', 'done_ratio', - 'estimated_hours', 'custom_field_values', 'custom_fields', 'lock_version', @@ -520,6 +519,9 @@ class Issue < ActiveRecord::Base 'deleted_attachment_ids', :if => lambda {|issue, user| issue.attachments_deletable?(user)}) + safe_attributes 'estimated_hours', + :if => lambda {|issue, user| user.allowed_to?(:view_estimated_hours, issue.project)} + def safe_attribute_names(user=nil) names = super names -= disabled_core_fields diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index aa8dc9034a..9144ad8299 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -47,19 +47,6 @@ class IssueQuery < Query :groupable => true), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date", :groupable => true), QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), - QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", - :totalable => true), - QueryColumn.new( - :total_estimated_hours, - :sortable => - lambda do - "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" \ - " WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')}" \ - " AND subtasks.root_id = #{Issue.table_name}.root_id" \ - " AND subtasks.lft >= #{Issue.table_name}.lft" \ - " AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" - end, - :default_order => 'desc'), QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true), TimestampQueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc', :groupable => true), @@ -205,12 +192,9 @@ class IssueQuery < Query add_available_filter "closed_on", :type => :date_past add_available_filter "start_date", :type => :date add_available_filter "due_date", :type => :date - add_available_filter "estimated_hours", :type => :float - - if User.current.allowed_to?(:view_time_entries, project, :global => true) - add_available_filter "spent_time", :type => :float, :label => :label_spent_time + if User.current.allowed_to?(:view_estimated_hours, nil, :global => true) + add_available_filter "estimated_hours", :type => :float end - add_available_filter "done_ratio", :type => :integer if User.current.allowed_to?(:set_issues_private, nil, :global => true) || @@ -283,9 +267,30 @@ class IssueQuery < Query @available_columns = self.class.available_columns.dup @available_columns += issue_custom_fields.visible.collect {|cf| QueryCustomFieldColumn.new(cf)} + if User.current.allowed_to?(:view_estimated_hours, project, :global => true) + # insert the columns after due_date or at the end + index = @available_columns.rindex {|column| column.name == :due_date} + index = (index ? index + 1 : -1) + + @available_columns.insert index, QueryColumn.new(:estimated_hours, + :sortable => "#{Issue.table_name}.estimated_hours", + :totalable => true + ) + index = (index.negative? ? index : index + 1) + @available_columns.insert index, QueryColumn.new(:total_estimated_hours, + :sortable => -> { + "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" \ + " WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')} AND" \ + " subtasks.root_id = #{Issue.table_name}.root_id AND" \ + " subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" + }, + :default_order => 'desc' + ) + end + if User.current.allowed_to?(:view_time_entries, project, :global => true) - # insert the columns after total_estimated_hours or at the end - index = @available_columns.find_index {|column| column.name == :total_estimated_hours} + # insert the columns after total_estimated_hours or the columns after due_date or at the end + index = @available_columns.rindex {|column| column.name == :total_estimated_hours || column.name == :due_date } index = (index ? index + 1 : -1) subselect = "SELECT SUM(hours) FROM #{TimeEntry.table_name}" + @@ -307,8 +312,9 @@ class IssueQuery < Query " WHERE (#{TimeEntry.visible_condition(User.current)})" + " AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt" + index = (index.negative? ? index : index + 1) @available_columns.insert( - index + 1, + index, QueryColumn.new(:total_spent_hours, :sortable => "COALESCE((#{subselect}), 0)", :default_order => 'desc', diff --git a/app/models/journal.rb b/app/models/journal.rb index 919a07dd2e..16a9699be4 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -111,6 +111,8 @@ class Journal < ActiveRecord::Base detail.custom_field && detail.custom_field.visible_by?(project, user) elsif detail.property == 'relation' Issue.find_by_id(detail.value || detail.old_value).try(:visible?, user) + elsif detail.property == 'attr' && detail.prop_key == 'estimated_hours' + user.allowed_to?(:view_estimated_hours, project) else true end diff --git a/app/views/issues/show.api.rsb b/app/views/issues/show.api.rsb index 6f23ca4b47..0ca0de6c05 100644 --- a/app/views/issues/show.api.rsb +++ b/app/views/issues/show.api.rsb @@ -16,8 +16,10 @@ api.issue do api.due_date @issue.due_date api.done_ratio @issue.done_ratio api.is_private @issue.is_private - api.estimated_hours @issue.estimated_hours - api.total_estimated_hours @issue.total_estimated_hours + if User.current.allowed_to?(:view_estimated_hours, @project) + api.estimated_hours @issue.estimated_hours + api.total_estimated_hours @issue.total_estimated_hours + end if User.current.allowed_to?(:view_time_entries, @project) api.spent_hours(@issue.spent_hours) api.total_spent_hours(@issue.total_spent_hours) diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index c7cd5689c7..acb97aec8f 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -68,7 +68,7 @@ unless @issue.disabled_core_fields.include?('done_ratio') rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :legend => "#{@issue.done_ratio}%"), :class => 'progress' end - unless @issue.disabled_core_fields.include?('estimated_hours') + if User.current.allowed_to?(:view_estimated_hours, @project) && !@issue.disabled_core_fields.include?('estimated_hours') rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours' end if User.current.allowed_to?(:view_time_entries, @project) && @issue.total_spent_hours > 0 diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index a1035927fa..ac68964684 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -97,26 +97,29 @@ <% end %> - <% if User.current.allowed_to?(:view_time_entries, @project) %> + <% allowed_to_view_time_entries, allowed_to_view_estimated_hours = User.current.allowed_to?(:view_time_entries, @project), User.current.allowed_to?(:view_estimated_hours, @project) %> + <% if allowed_to_view_time_entries || allowed_to_view_estimated_hours %>
- <% if User.current.allowed_to?(:log_time, @project) %> + <% if User.current.allowed_to?(:log_time, @project) %> <%= link_to l(:button_log_time), new_project_time_entry_path(@project) %> | - <% end %> + <% end %> <%= link_to(l(:label_details), project_time_entries_path(@project)) %> | <%= link_to(l(:label_report), report_project_time_entries_path(@project)) %>
+ <% end %>