|
|
|
@ -5,93 +5,6 @@ module RedmineBacklogs::Patches::IssuePatch |
|
|
|
|
base.class_eval do |
|
|
|
|
unloadable |
|
|
|
|
|
|
|
|
|
# The leading and trailing quotes trick the eval code in |
|
|
|
|
# acts_as_silent_list. This way, we are able to execute actual code in |
|
|
|
|
# our quote string. Also sanitize_sql seems to be unavailable in a |
|
|
|
|
# sensible way. Therefore we're using send to circumvent visibility |
|
|
|
|
# issues. |
|
|
|
|
acts_as_silent_list |
|
|
|
|
def scope_condition |
|
|
|
|
self.class.send(:sanitize_sql, ['project_id = ? AND fixed_version_id = ? AND tracker_id IN (?)', |
|
|
|
|
self.project_id, self.fixed_version_id, self.trackers]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# add new items to top of list automatically |
|
|
|
|
after_create :insert_at, :if => :is_story? |
|
|
|
|
|
|
|
|
|
# reorder list, if issue is removed from sprint |
|
|
|
|
before_update :fix_other_issues_positions |
|
|
|
|
before_update :fix_own_issue_position |
|
|
|
|
|
|
|
|
|
# deactivate the default add_to_list_bottom callback |
|
|
|
|
def add_to_list_bottom |
|
|
|
|
super unless caller(2).first =~ /callbacks/ |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def fix_other_issues_positions |
|
|
|
|
if changes.slice('project_id', 'tracker_id', 'fixed_version_id').present? |
|
|
|
|
if changes.slice('project_id', 'fixed_version_id').blank? and |
|
|
|
|
Story.trackers.include?(tracker_id.to_i) and |
|
|
|
|
Story.trackers.include?(tracker_id_was.to_i) |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if fixed_version_id_changed? |
|
|
|
|
restore_version_id = true |
|
|
|
|
new_version_id = fixed_version_id |
|
|
|
|
self.fixed_version_id = fixed_version_id_was |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if tracker_id_changed? |
|
|
|
|
restore_tracker_id = true |
|
|
|
|
new_tracker_id = tracker_id |
|
|
|
|
self.tracker_id = tracker_id_was |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if project_id_changed? |
|
|
|
|
restore_project_id = true |
|
|
|
|
# I've got no idea, why there's a difference between setting the |
|
|
|
|
# project via project= or via project_id=, but there is. |
|
|
|
|
new_project = project |
|
|
|
|
self.project = Project.find(project_id_was) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
remove_from_list if is_story? |
|
|
|
|
|
|
|
|
|
if restore_project_id |
|
|
|
|
self.project = new_project |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if restore_tracker_id |
|
|
|
|
self.tracker_id = new_tracker_id |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if restore_version_id |
|
|
|
|
self.fixed_version_id = new_version_id |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def fix_own_issue_position |
|
|
|
|
if changes.slice('project_id', 'tracker_id', 'fixed_version_id').present? |
|
|
|
|
if changes.slice('project_id', 'fixed_version_id').blank? and |
|
|
|
|
Story.trackers.include?(tracker_id.to_i) and |
|
|
|
|
Story.trackers.include?(tracker_id_was.to_i) |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if is_story? and fixed_version.present? |
|
|
|
|
insert_at(1) |
|
|
|
|
else |
|
|
|
|
assume_not_in_list |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# list end |
|
|
|
|
|
|
|
|
|
include InstanceMethods |
|
|
|
|
extend ClassMethods |
|
|
|
|
|
|
|
|
@ -112,6 +25,8 @@ module RedmineBacklogs::Patches::IssuePatch |
|
|
|
|
|
|
|
|
|
validate_children(record, attr, value) #not using validates_associated because the errors are not displayed nicely then |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
include RedmineBacklogs::List |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
@ -133,6 +48,7 @@ module RedmineBacklogs::Patches::IssuePatch |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
private |
|
|
|
|
|
|
|
|
|
def validate_parent_issue_relation(issue, parent_attr, value) |
|
|
|
|
parent = Issue.find_by_id(value) |
|
|
|
|
if parent_issue_relationship_spanning_projects?(parent, issue) |
|
|
|
|