Mercurial > hg > soundsoftware-site
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 |