12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- module CanPriorization
- extend ActiveSupport::Concern
- included do
- before_create :fill_prio
- before_update :rearrangement
- end
- def rearrangement
- # rearrange only in case of changed prio
- return true if !changes['prio']
- rearranged_prio = 0
- rearrangement_previous_ordered_ids.each do |entry_id|
- # don't process currently updated entry
- next if id == entry_id
- rearranged_prio += 1
- # increase rearranged prio by one to avoid a collition
- # with the changed prio of current instance
- if rearranged_prio == prio
- rearranged_prio += 1
- end
- rearrange_entry(entry_id, rearranged_prio)
- end
- end
- def fill_prio
- return true if prio.present?
- self.prio = self.class.calculate_prio
- true
- end
- def rearrangement_previous_ordered_ids
- self.class.reorder(
- prio: :asc,
- updated_at: :desc
- ).pluck(:id)
- end
- def rearrange_entry(id, prio)
- # don't start rearranging logic for entrys that have already been rearranged
- self.class.without_callback(:update, :before, :rearrangement) do
- # fetch and update entry only if prio needs to change
- entry = self.class.where(
- id: id
- ).where.not(
- prio: prio
- ).take
- next if entry.blank?
- entry.update!(prio: prio)
- end
- end
- # methods defined here are going to extend the class, not the instance of it
- class_methods do
- def calculate_prio
- existing_maximum = maximum(:prio)
- return 0 if !existing_maximum
- existing_maximum + 1
- end
- end
- end
|