demarches-normaliennes/app/models/concerns/dossier_rebase_concern.rb

75 lines
2.2 KiB
Ruby

# frozen_string_literal: true
module DossierRebaseConcern
extend ActiveSupport::Concern
def rebase!(force: false)
ProcedureRevisionPreloader.new([procedure.published_revision, revision].compact).all
return if procedure.published_revision.blank?
if force || can_rebase?
transaction do
rebase
end
end
end
def rebase_later
DossierRebaseJob.perform_later(self)
end
def can_rebase?
procedure.published_revision.present? && revision != procedure.published_revision &&
(brouillon? || accepted_en_construction_changes? || accepted_en_instruction_changes?)
end
def pending_changes
procedure.published_revision.present? ? revision.compare_types_de_champ(procedure.published_revision) : []
end
def can_rebase_mandatory_change?(stable_id)
!champs.filter { _1.stable_id == stable_id }.any?(&:blank?)
end
def can_rebase_drop_down_options_change?(stable_id, options)
!champs.filter { _1.stable_id == stable_id }.any? { _1.in?(options) }
end
private
def accepted_en_construction_changes?
en_construction? && pending_changes.all? { _1.can_rebase?(self) }
end
def accepted_en_instruction_changes?
en_instruction? && pending_changes.all? { _1.can_rebase?(self) }
end
def rebase
# revision we are rebasing to
target_revision = procedure.published_revision
changed_stable_ids_by_op = pending_changes
.group_by(&:op)
.transform_values { _1.map(&:stable_id) }
updated_stable_ids = changed_stable_ids_by_op.fetch(:update, [])
added_stable_ids = changed_stable_ids_by_op.fetch(:add, [])
# update dossier revision
update_column(:revision_id, target_revision.id)
# mark updated champs as rebased
champs.where(stable_id: updated_stable_ids).update_all(rebased_at: Time.zone.now)
# add rows for new repetitions
repetition_types_de_champ = target_revision
.types_de_champ
.repetition
.where(stable_id: added_stable_ids)
repetition_types_de_champ.mandatory
.or(repetition_types_de_champ.private_only)
.find_each do |type_de_champ|
self.champs << type_de_champ.build_champ(row_id: ULID.generate, rebased_at: Time.zone.now)
end
end
end