Index: app/models/sprint.rb =================================================================== --- app/models/sprint.rb (.../v0.13.2~5) (revision 48) +++ app/models/sprint.rb (.../v0.13.2~6) (revision 52) @@ -57,6 +57,15 @@ issues.where(conditions).order(order).select{|issue| issue.visible?} end + def normalized_pbis + normalize_positions(pbis) + end + + def release_position(pbi) + normalize_positions(pbis, pbi) + nil + end + def story_points pbis.collect{|pbi| pbi.story_points.to_f}.compact.sum end @@ -219,6 +228,20 @@ private + def normalize_positions(issues, issue_to_ignore = nil) + new_position = 1 + issues.each do |issue| + unless issue == issue_to_ignore + unless issue.position == new_position + issue.position = new_position + issue.save! + end + new_position += 1 + end + end + issues + end + def update_project_product_backlog if is_product_backlog? project.product_backlog = nil Index: app/controllers/product_backlog_controller.rb =================================================================== --- app/controllers/product_backlog_controller.rb (.../v0.13.2~5) (revision 48) +++ app/controllers/product_backlog_controller.rb (.../v0.13.2~6) (revision 52) @@ -124,7 +124,7 @@ end def find_pbis - @pbis = @product_backlog.pbis + @pbis = @product_backlog.normalized_pbis rescue render_404 end Index: lib/scrum/issue_patch.rb =================================================================== --- lib/scrum/issue_patch.rb (.../v0.13.2~5) (revision 48) +++ lib/scrum/issue_patch.rb (.../v0.13.2~6) (revision 52) @@ -19,7 +19,7 @@ safe_attributes :sprint_id, :if => lambda {|issue, user| user.allowed_to?(:edit_issues, issue.project)} - before_save :update_position, :if => lambda {|issue| issue.sprint_id_changed? and issue.is_pbi?} + before_save :update_positions_on_sprint_change, :if => lambda {|issue| issue.sprint_id_changed? and issue.is_pbi?} before_save :update_sprint_of_children, :if => lambda {|issue| issue.sprint_id_changed? and issue.is_pbi?} @@ -224,10 +224,8 @@ case position when "top" move_issue_to_the_begin_of_the_sprint - save! when "bottom" move_issue_to_the_end_of_the_sprint - save! when "before", "after" if other_pbi_id.nil? or (other_pbi = Issue.find(other_pbi_id)).nil? raise "Other PBI ID ##{other_pbi_id} is invalid" @@ -239,17 +237,16 @@ move_issue_respecting_to_pbi(other_pbi, position == "after") end end + self.save! end end def is_first_pbi? - min = min_position - return ((!(position.nil?)) and (!(min.nil?)) and (position <= min)) + self == sprint.pbis.first end def is_last_pbi? - max = max_position - return ((!(position.nil?)) and (!(max.nil?)) and (position >= max)) + self == sprint.pbis.last end protected @@ -262,7 +259,7 @@ private - def update_position + def update_positions_on_sprint_change if sprint_id_was.blank? # New PBI into PB or Sprint if @set_on_top @@ -281,47 +278,55 @@ # From Sprint to Sprint move_issue_to_the_end_of_the_sprint end + old_sprint.release_position(self) end end - def min_position - min = nil - sprint.pbis.each do |pbi| - min = pbi.position if min.nil? or (pbi.position < min) + def move_issue_to_the_begin_of_the_sprint + if first_pbi = sprint.pbis.first + move_issue_respecting_to_pbi(first_pbi, false) + else + self.position = 1 end - return min end - def max_position - max = nil - sprint.pbis.each do |pbi| - max = pbi.position if max.nil? or (pbi.position > max) + def move_issue_to_the_end_of_the_sprint + if last_pbi = sprint.pbis.last + move_issue_respecting_to_pbi(last_pbi, true) + else + self.position = 1 end - return max end - def move_issue_to_the_begin_of_the_sprint - min = min_position - self.position = min.nil? ? 1 : (min - 1) - end - - def move_issue_to_the_end_of_the_sprint - max = max_position - self.position = max.nil? ? 1 : (max + 1) - end - def move_issue_respecting_to_pbi(other_pbi, after) - self.position = other_pbi.position - self.position += 1 if after - self.save! - sprint.pbis(:position_above => after ? self.position : self.position - 1).each do |next_pbi| - if next_pbi.id != self.id - next_pbi.position += 1 - next_pbi.save! + new_position = 1 + sprint.pbis.each do |pbi| + unless pbi == self + if pbi == other_pbi + if after + update_position(pbi, new_position) + new_position += 1 + self.position = new_position + else + self.position = new_position + new_position += 1 + update_position(pbi, new_position) + end + else + update_position(pbi, new_position) + end + new_position += 1 end end end + def update_position(pbi, new_position) + unless pbi.position == new_position + pbi.position = new_position + pbi.save! + end + end + def update_sprint_of_children self.children.each do |child| unless child.closed?