OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/lib/backlogs_list.rb

84 lines
2.5 KiB

module Backlogs
module List
unloadable
def self.included(base)
base.send(:include, InstanceMethods)
base.send(:extend, ClassMethods)
end
module ClassMethods
def acts_as_backlogs_list(tracker_method)
scope_string = 'project_id = #{self.project_id}' +
' AND fixed_version_id = #{self.fixed_version_id}' +
' AND tracker_id in (#{self.class.trackers_in_scope})'
trackers_method = "def self.trackers_method() \"#{tracker_method}\" end"
class_eval <<-EOV
acts_as_list :scope => scope_string
#{ trackers_method }
EOV
end
def trackers_in_scope
trackers = self.send(self.trackers_method().to_sym)
if trackers.is_a?(Array)
trackers.join(', ')
else
trackers
end
end
end
module InstanceMethods
def move_after(prev_id)
# remove so the potential 'prev' has a correct position
remove_from_list
begin
prev = self.class.find(prev_id)
rescue ActiveRecord::RecordNotFound
prev = nil
end
# if it's the first story, move it to the 1st position
if prev.blank?
insert_at
move_to_top
# if its predecessor has no position, create an order on position silently.
# This can happen when sorting inside a version for the first time after backlogs was activated
# and there have already been items inside the version at the time of backlogs activation
elsif !prev.in_list?
prev_pos = set_default_prev_positions_silently(prev)
insert_at(prev_pos += 1)
# there's a valid predecessor
else
insert_at(prev.position + 1)
end
end
private
def set_default_prev_positions_silently(prev)
stories = self.class.find(:all, :conditions => {:fixed_version_id => self.fixed_version_id, :tracker_id => self.class.trackers_in_scope})
self.class.record_timestamps = false #temporarily turn off column updates
highest_pos = stories.sort_by{|s| s.position ? s.position : 0}.collect(&:position).last
highest_pos = 0 if highest_pos.nil?
stories.sort_by { |s| s.id }.each do |story|
next if story.in_list? || story.id > prev.id || self.id == story.id
story.insert_at(highest_pos += 1)
end
self.class.record_timestamps = true #turning updates back on
highest_pos
end
end
end
end