From 0d25f523099facff9473ae61fb44f0718ca7bf9c Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 20 Jan 2021 13:21:23 +0100 Subject: [PATCH] Add changed? and compare on ProcedureRevision --- app/models/procedure.rb | 8 +++ app/models/procedure_revision.rb | 117 +++++++++++++++++++++++++++++++ app/models/type_de_champ.rb | 6 ++ 3 files changed, 131 insertions(+) diff --git a/app/models/procedure.rb b/app/models/procedure.rb index c2313239a..4a3b7fa82 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -333,6 +333,14 @@ class Procedure < ApplicationRecord publiee? || close? || depubliee? end + def draft_changed? + publiee? && published_revision.changed?(draft_revision) + end + + def revision_changes + published_revision.compare(draft_revision) + end + def accepts_new_dossiers? publiee? || brouillon? end diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 42c646ee2..ee616fa87 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -101,8 +101,125 @@ class ProcedureRevision < ApplicationRecord !draft? end + def changed?(revision) + types_de_champ != revision.types_de_champ || types_de_champ_private != revision.types_de_champ_private + end + + def compare(revision) + changes = [] + changes += compare_types_de_champ(types_de_champ, revision.types_de_champ) + changes += compare_types_de_champ(types_de_champ_private, revision.types_de_champ_private) + changes + end + private + def compare_types_de_champ(from_tdc, to_tdc) + if from_tdc == to_tdc + [] + else + from_h = from_tdc.index_by(&:stable_id) + to_h = to_tdc.index_by(&:stable_id) + + from_sids = from_h.keys + to_sids = to_h.keys + + removed = (from_sids - to_sids).map do |sid| + { op: :remove, label: from_h[sid].libelle, position: from_sids.index(sid) } + end + + added = (to_sids - from_sids).map do |sid| + { op: :add, label: to_h[sid].libelle, position: to_sids.index(sid) } + end + + kept = from_sids.intersection(to_sids) + + moved = kept + .map { |sid| [sid, from_sids.index(sid), to_sids.index(sid)] } + .filter { |_, from_index, to_index| from_index != to_index } + .map do |sid, from_index, to_index| + { op: :move, label: from_h[sid].libelle, from: from_index, to: to_index, position: to_index } + end + + changed = kept + .map { |sid| [sid, from_h[sid], to_h[sid]] } + .flat_map do |sid, from, to| + compare_type_de_champ(from, to) + .each { |h| h[:position] = to_sids.index(sid) } + end + + (removed + added + moved + changed) + .sort_by { |h| h[:position] } + .each { |h| h.delete(:position) } + end + end + + def compare_type_de_champ(from_type_de_champ, to_type_de_champ) + changes = [] + if from_type_de_champ.type_champ != to_type_de_champ.type_champ + changes << { + op: :update, + attribute: :type_champ, + label: from_type_de_champ.libelle, + from: from_type_de_champ.type_champ, + to: to_type_de_champ.type_champ + } + end + if from_type_de_champ.libelle != to_type_de_champ.libelle + changes << { + op: :update, + attribute: :libelle, + label: from_type_de_champ.libelle, + from: from_type_de_champ.libelle, + to: to_type_de_champ.libelle + } + end + if from_type_de_champ.description != to_type_de_champ.description + changes << { + op: :update, + attribute: :description, + label: from_type_de_champ.libelle, + from: from_type_de_champ.description, + to: to_type_de_champ.description + } + end + if from_type_de_champ.mandatory? != to_type_de_champ.mandatory? + changes << { + op: :update, + attribute: :mandatory, + label: from_type_de_champ.libelle, + from: from_type_de_champ.mandatory?, + to: to_type_de_champ.mandatory? + } + end + if to_type_de_champ.drop_down_list? + if from_type_de_champ.drop_down_list_options != to_type_de_champ.drop_down_list_options + changes << { + op: :update, + attribute: :drop_down_options, + label: from_type_de_champ.libelle, + from: from_type_de_champ.drop_down_list_options, + to: to_type_de_champ.drop_down_list_options + } + end + elsif to_type_de_champ.piece_justificative? + if from_type_de_champ.piece_justificative_template_checksum != to_type_de_champ.piece_justificative_template_checksum + changes << { + op: :update, + attribute: :piece_justificative_template, + label: from_type_de_champ.libelle, + from: from_type_de_champ.piece_justificative_template_filename, + to: to_type_de_champ.piece_justificative_template_filename + } + end + elsif to_type_de_champ.repetition? + if from_type_de_champ.types_de_champ != to_type_de_champ.types_de_champ + changes += compare_types_de_champ(from_type_de_champ.types_de_champ, to_type_de_champ.types_de_champ) + end + end + changes + end + def revise_type_de_champ(type_de_champ) types_de_champ_association = type_de_champ.private? ? :revision_types_de_champ_private : :revision_types_de_champ association = send(types_de_champ_association).find_by!(type_de_champ: type_de_champ) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 88fa0585c..35f168586 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -226,6 +226,12 @@ class TypeDeChamp < ApplicationRecord end end + def piece_justificative_template_checksum + if piece_justificative_template.attached? + piece_justificative_template.checksum + end + end + def drop_down_list_value if drop_down_list_options.present? drop_down_list_options.reject(&:empty?).join("\r\n")