comparison app/models/issue.rb @ 1517:dffacf8a6908 redmine-2.5

Update to Redmine SVN revision 13367 on 2.5-stable branch
author Chris Cannam
date Tue, 09 Sep 2014 09:29:00 +0100
parents e248c7af89ec
children fb9a13467253
comparison
equal deleted inserted replaced
1516:b450a9d58aed 1517:dffacf8a6908
36 :conditions => Proc.new { 36 :conditions => Proc.new {
37 ["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false] 37 ["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false]
38 }, 38 },
39 :readonly => true 39 :readonly => true
40 40
41 has_many :time_entries, :dependent => :delete_all 41 has_many :time_entries, :dependent => :destroy
42 has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC" 42 has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC"
43 43
44 has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all 44 has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
45 has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all 45 has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
46 46
198 base_reload(*args) 198 base_reload(*args)
199 end 199 end
200 200
201 # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields 201 # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
202 def available_custom_fields 202 def available_custom_fields
203 (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : [] 203 (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields) : []
204 end 204 end
205 205
206 def visible_custom_field_values(user=nil) 206 def visible_custom_field_values(user=nil)
207 user_real = user || User.current 207 user_real = user || User.current
208 custom_field_values.select do |value| 208 custom_field_values.select do |value|
481 visible_custom_field_values(user).reject do |value| 481 visible_custom_field_values(user).reject do |value|
482 read_only_attribute_names(user).include?(value.custom_field_id.to_s) 482 read_only_attribute_names(user).include?(value.custom_field_id.to_s)
483 end 483 end
484 end 484 end
485 485
486 # Returns the custom fields that can be edited by the given user
487 def editable_custom_fields(user=nil)
488 editable_custom_field_values(user).map(&:custom_field).uniq
489 end
490
486 # Returns the names of attributes that are read-only for user or the current user 491 # Returns the names of attributes that are read-only for user or the current user
487 # For users with multiple roles, the read-only fields are the intersection of 492 # For users with multiple roles, the read-only fields are the intersection of
488 # read-only fields of each role 493 # read-only fields of each role
489 # The result is an array of strings where sustom fields are represented with their ids 494 # The result is an array of strings where sustom fields are represented with their ids
490 # 495 #
837 # 842 #
838 # Example: 843 # Example:
839 # spent_hours => 0.0 844 # spent_hours => 0.0
840 # spent_hours => 50.2 845 # spent_hours => 50.2
841 def total_spent_hours 846 def total_spent_hours
842 @total_spent_hours ||= self_and_descendants.sum("#{TimeEntry.table_name}.hours", 847 @total_spent_hours ||=
843 :joins => "LEFT JOIN #{TimeEntry.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id").to_f || 0.0 848 self_and_descendants.
849 joins("LEFT JOIN #{TimeEntry.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id").
850 sum("#{TimeEntry.table_name}.hours").to_f || 0.0
844 end 851 end
845 852
846 def relations 853 def relations
847 @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort) 854 @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort)
848 end 855 end
1220 1227
1221 private 1228 private
1222 1229
1223 def after_project_change 1230 def after_project_change
1224 # Update project_id on related time entries 1231 # Update project_id on related time entries
1225 TimeEntry.update_all(["project_id = ?", project_id], {:issue_id => id}) 1232 TimeEntry.where({:issue_id => id}).update_all(["project_id = ?", project_id])
1226 1233
1227 # Delete issue relations 1234 # Delete issue relations
1228 unless Setting.cross_project_issue_relations? 1235 unless Setting.cross_project_issue_relations?
1229 relations_from.clear 1236 relations_from.clear
1230 relations_to.clear 1237 relations_to.clear
1284 def update_nested_set_attributes 1291 def update_nested_set_attributes
1285 if root_id.nil? 1292 if root_id.nil?
1286 # issue was just created 1293 # issue was just created
1287 self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id) 1294 self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
1288 set_default_left_and_right 1295 set_default_left_and_right
1289 Issue.update_all(["root_id = ?, lft = ?, rgt = ?", root_id, lft, rgt], ["id = ?", id]) 1296 Issue.where(["id = ?", id]).
1297 update_all(["root_id = ?, lft = ?, rgt = ?", root_id, lft, rgt])
1290 if @parent_issue 1298 if @parent_issue
1291 move_to_child_of(@parent_issue) 1299 move_to_child_of(@parent_issue)
1292 end 1300 end
1293 elsif parent_issue_id != parent_id 1301 elsif parent_issue_id != parent_id
1294 update_nested_set_attributes_on_parent_change 1302 update_nested_set_attributes_on_parent_change
1310 end 1318 end
1311 old_root_id = root_id 1319 old_root_id = root_id
1312 self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id ) 1320 self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id )
1313 target_maxright = nested_set_scope.maximum(right_column_name) || 0 1321 target_maxright = nested_set_scope.maximum(right_column_name) || 0
1314 offset = target_maxright + 1 - lft 1322 offset = target_maxright + 1 - lft
1315 Issue.update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset], 1323 Issue.where(["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]).
1316 ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]) 1324 update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
1317 self[left_column_name] = lft + offset 1325 self[left_column_name] = lft + offset
1318 self[right_column_name] = rgt + offset 1326 self[right_column_name] = rgt + offset
1319 if @parent_issue 1327 if @parent_issue
1320 move_to_child_of(@parent_issue) 1328 move_to_child_of(@parent_issue)
1321 end 1329 end
1335 end 1343 end
1336 1344
1337 def recalculate_attributes_for(issue_id) 1345 def recalculate_attributes_for(issue_id)
1338 if issue_id && p = Issue.find_by_id(issue_id) 1346 if issue_id && p = Issue.find_by_id(issue_id)
1339 # priority = highest priority of children 1347 # priority = highest priority of children
1340 if priority_position = p.children.maximum("#{IssuePriority.table_name}.position", :joins => :priority) 1348 if priority_position = p.children.joins(:priority).maximum("#{IssuePriority.table_name}.position")
1341 p.priority = IssuePriority.find_by_position(priority_position) 1349 p.priority = IssuePriority.find_by_position(priority_position)
1342 end 1350 end
1343 1351
1344 # start/due dates = lowest/highest dates of children 1352 # start/due dates = lowest/highest dates of children
1345 p.start_date = p.children.minimum(:start_date) 1353 p.start_date = p.children.minimum(:start_date)
1354 if leaves_count > 0 1362 if leaves_count > 0
1355 average = p.leaves.where("estimated_hours > 0").average(:estimated_hours).to_f 1363 average = p.leaves.where("estimated_hours > 0").average(:estimated_hours).to_f
1356 if average == 0 1364 if average == 0
1357 average = 1 1365 average = 1
1358 end 1366 end
1359 done = p.leaves.sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " + 1367 done = p.leaves.joins(:status).
1360 "* (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)", :joins => :status).to_f 1368 sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " +
1369 "* (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f
1361 progress = done / (average * leaves_count) 1370 progress = done / (average * leaves_count)
1362 p.done_ratio = progress.round 1371 p.done_ratio = progress.round
1363 end 1372 end
1364 end 1373 end
1365 1374