69 lines
2.5 KiB
Ruby
69 lines
2.5 KiB
Ruby
class Recovery::AlignChampWithDossierRevision
|
|
def initialize(dossiers, progress: nil)
|
|
@dossiers = dossiers
|
|
@progress = progress
|
|
@logs = []
|
|
end
|
|
|
|
attr_reader :logs
|
|
|
|
def run(destroy_extra_champs: false)
|
|
@logs = []
|
|
bad_dossier_ids = find_broken_dossier_ids
|
|
|
|
Dossier
|
|
.where(id: bad_dossier_ids)
|
|
.includes(:procedure, champs: { type_de_champ: :revisions })
|
|
.find_each do |dossier|
|
|
bad_champs = dossier.champs.filter { !dossier.revision_id.in?(_1.type_de_champ.revisions.ids) }
|
|
bad_champs.each do |champ|
|
|
type_de_champ = dossier.revision.types_de_champ.find { _1.stable_id == champ.stable_id }
|
|
state = {
|
|
champ_id: champ.id,
|
|
champ_type_de_champ_id: champ.type_de_champ_id,
|
|
dossier_id: dossier.id,
|
|
dossier_revision_id: dossier.revision_id,
|
|
procedure_id: dossier.procedure.id
|
|
}
|
|
if type_de_champ.present?
|
|
logs << state.merge(status: :updated, type_de_champ_id: type_de_champ.id)
|
|
champ.update_column(:type_de_champ_id, type_de_champ.id)
|
|
else
|
|
logs << state.merge(status: :not_found)
|
|
champ.destroy! if destroy_extra_champs
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def find_broken_dossier_ids
|
|
bad_dossier_ids = []
|
|
|
|
@dossiers.in_batches(of: 15_000) do |dossiers|
|
|
dossier_ids_revision_ids = dossiers.pluck(:id, :revision_id)
|
|
dossier_ids = dossier_ids_revision_ids.map(&:first)
|
|
dossier_ids_type_de_champ_ids = Champ.where(dossier_id: dossier_ids).pluck(:dossier_id, :type_de_champ_id)
|
|
type_de_champ_ids = dossier_ids_type_de_champ_ids.map(&:second).uniq
|
|
revision_ids_by_type_de_champ_id = ProcedureRevisionTypeDeChamp
|
|
.where(type_de_champ_id: type_de_champ_ids)
|
|
.pluck(:type_de_champ_id, :revision_id)
|
|
.group_by(&:first).transform_values { _1.map(&:second).uniq }
|
|
|
|
type_de_champ_ids_by_dossier_id = dossier_ids_type_de_champ_ids
|
|
.group_by(&:first)
|
|
.transform_values { _1.map(&:second).uniq }
|
|
|
|
bad_dossier_ids += dossier_ids_revision_ids.filter do |(dossier_id, revision_id)|
|
|
type_de_champ_ids_by_dossier_id.fetch(dossier_id, []).any? do |type_de_champ_id|
|
|
!revision_id.in?(revision_ids_by_type_de_champ_id.fetch(type_de_champ_id, []))
|
|
end
|
|
end.map(&:first)
|
|
|
|
@progress.inc(dossiers.count) if @progress
|
|
end
|
|
|
|
@progress.finish if @progress
|
|
|
|
bad_dossier_ids
|
|
end
|
|
end
|