Project

General

Profile

Feature #29286 » 0001-Option-to-set-default-time-entry-activity-per-role.patch

Marius BĂLTEANU, 2018-08-11 15:08

View differences:

app/helpers/timelog_helper.rb
26 26
  def activity_collection_for_select_options(time_entry=nil, project=nil)
27 27
    project ||= time_entry.try(:project)
28 28
    project ||= @project
29
    if project.nil?
30
      activities = TimeEntryActivity.shared.active
31
    else
32
      activities = project.activities
33
    end
29

  
30
    activities = TimeEntryActivity.allowed_activities(project)
34 31

  
35 32
    collection = []
36 33
    if time_entry && time_entry.activity && !time_entry.activity.active?
......
42 39
    collection
43 40
  end
44 41

  
42
  def default_activity(time_entry)
43
    if @project
44
      time_entry.activity_id
45
    else
46
      TimeEntryActivity.default_activity_id(User.current, time_entry.project)
47
    end
48
  end
49

  
45 50
  def select_hours(data, criteria, value)
46 51
    if value.to_s.empty?
47 52
      data.select {|row| row[criteria].blank? }
app/models/role.rb
58 58
    where("#{compare} builtin = 0")
59 59
  }
60 60

  
61
  belongs_to :default_time_entry_activity, :class_name => "TimeEntryActivity"
62

  
61 63
  before_destroy :check_deletable
62 64
  has_many :workflow_rules, :dependent => :delete_all
63 65
  has_and_belongs_to_many :custom_fields, :join_table => "#{table_name_prefix}custom_fields_roles#{table_name_suffix}", :foreign_key => "role_id"
......
96 98
      'managed_role_ids',
97 99
      'permissions',
98 100
      'permissions_all_trackers',
99
      'permissions_tracker_ids'
101
      'permissions_tracker_ids',
102
      'default_time_entry_activity_id'
100 103

  
101 104
  # Copies attributes from another role, arg can be an id or a Role
102 105
  def copy_from(arg, options={})
app/models/time_entry.rb
91 91
  def initialize(attributes=nil, *args)
92 92
    super
93 93
    if new_record? && self.activity.nil?
94
      if default_activity = TimeEntryActivity.default
95
        self.activity_id = default_activity.id
96
      end
94
      self.activity_id = TimeEntryActivity.default_activity_id(self.user, self.project)
97 95
      self.hours = nil if hours == 0
98 96
    end
99 97
  end
app/models/time_entry_activity.rb
35 35
  def transfer_relations(to)
36 36
    objects.update_all(:activity_id => to.id)
37 37
  end
38

  
39
  def self.default_activity_id(user=nil, project=nil)
40
    default_activities = []
41
    default_activity = nil
42
    allowed_activities = self.allowed_activities(project)
43

  
44
    if project && user
45
      user_membership = user.membership(project)
46
      if user_membership
47
        default_activities = user_membership.roles.where.not(:default_time_entry_activity_id => nil).sort.pluck(:default_time_entry_activity_id)
48
      end
49
    end
50

  
51
    global_activity = self.default
52
    if global_activity
53
      default_activities << global_activity.id unless default_activities.include?(global_activity.id)
54
    end
55

  
56
    default_activities.each do |id|
57
      default_activity = allowed_activities.detect{ |a| a.id == id || a.parent_id == id }
58
      break unless default_activity.nil?
59
    end
60

  
61
    default_activity.id unless default_activity.nil?
62
  end
63

  
64
  # Returns the available activities for the time entry
65
  def self.allowed_activities(project=nil)
66
    if project.nil?
67
      activities = TimeEntryActivity.shared.active
68
    else
69
      activities = project.activities
70
    end
71
  end
38 72
end
app/views/roles/_form.html.erb
38 38
      <%= hidden_field_tag 'role[managed_role_ids][]', '' %>
39 39
  <% end %>
40 40

  
41
  <% unless @role.anonymous? %>
42
    <p><%= f.select :default_time_entry_activity_id, options_from_collection_for_select(TimeEntryActivity.active.shared, :id, :name, @role.default_time_entry_activity_id), :include_blank => l(:label_none) %></p>
43
  <% end %>
44

  
41 45
  <% if @role.new_record? && @roles.any? %>
42 46
    <p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
43 47
    <%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@roles, :id, :name, params[:copy_workflow_from] || @copy_from.try(:id))) %></p>
app/views/timelog/new.js.erb
1
$('#time_entry_activity_id').html('<%= escape_javascript options_for_select(activity_collection_for_select_options(@time_entry), @time_entry.activity_id) %>');
1
$('#time_entry_activity_id').html('<%= escape_javascript options_for_select(activity_collection_for_select_options(@time_entry), default_activity(@time_entry)) %>');
2 2
$('#time_entry_issue').html('<%= escape_javascript link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %>');
db/migrate/20180806215628_add_default_time_entry_activity_to_roles.rb
1
class AddDefaultTimeEntryActivityToRoles < ActiveRecord::Migration[5.2]
2
  def change
3
    add_column :roles, :default_time_entry_activity_id, :int
4
  end
5
end
test/functional/timelog_controller_test.rb
86 86
    assert_response 403
87 87
  end
88 88

  
89
  def test_new_should_select_default_activity
89
  def test_new_should_select_default_role_activity
90
    developer = Role.find(2)
91
    developer.default_time_entry_activity_id = 9
92
    developer.save!
93

  
94
    @request.session[:user_id] = 3
95
    get :new, :params => {:project_id => 1}
96
    assert_response :success
97
    assert_select 'select[name=?]', 'time_entry[activity_id]' do
98
      assert_select 'option[selected=selected]', :text => 'Design'
99
    end
100
  end
101

  
102
  def test_new_should_select_default_global_activity_for_user_roles_without_default_activities
90 103
    @request.session[:user_id] = 3
91 104
    get :new, :params => {:project_id => 1}
92 105
    assert_response :success
test/unit/time_entry_activity_test.rb
124 124
    assert_include activity, project.activities
125 125
    assert_include TimeEntryActivity.find(9), project.activities
126 126
  end
127

  
128
  def test_default_activity_id_without_user_and_project_should_return_global_default_activity
129
    assert_equal 10, TimeEntryActivity.default_activity_id
130
  end
131

  
132
  def test_default_activity_id_with_user_and_project_should_return_role_default_activity
133
    # set a default activity for Manager role
134
    manager = Role.find(1)
135
    manager.default_time_entry_activity_id = 9
136
    manager.save
137

  
138
    assert_equal 9, TimeEntryActivity.default_activity_id(User.find(2), Project.find(1))
139
  end
140

  
141
  def test_default_activity_id_with_user_and_project_should_consider_role_position
142
    project = Project.find(1)
143
    user = User.find(2)
144

  
145
    # set a default activity for Manager role
146
    manager = Role.find(1)
147
    manager.default_time_entry_activity_id = 9
148
    manager.save!
149

  
150
    # set a default activity for Developer role
151
    # and set the role position first
152
    developer = Role.find(2)
153
    developer.default_time_entry_activity_id = 11
154
    developer.position = 1
155
    developer.save!
156

  
157
    member = Member.find_or_new(project, user)
158
    member.role_ids = [1, 2]
159
    member.save!
160

  
161
    assert_equal 11, TimeEntryActivity.default_activity_id(user, project)
162
  end
163

  
164

  
165
  def test_default_activity_id_should_include_only_allowed_activities
166
    # set a default activity for Manager role
167
    manager = Role.find(1)
168
    manager.default_time_entry_activity_id = 9
169
    manager.save!
170

  
171
    project = Project.find(1)
172

  
173
    # disable role default activity
174
    disable_activity = TimeEntryActivity.new({:name => "QA", :project => project, :parent => TimeEntryActivity.find(9), :active => false})
175
    disable_activity.save!
176

  
177
    assert_equal 10, TimeEntryActivity.default_activity_id(User.find(2), project)
178
  end
127 179
end
(1-1/3)