refactor(type_de_champ): improve and clean helper methods

This commit is contained in:
Paul Chavard 2024-11-04 15:59:58 +01:00
parent 5a2ab37049
commit 71009094a4
No known key found for this signature in database
8 changed files with 74 additions and 79 deletions

View file

@ -122,8 +122,8 @@ module ProcedurePublishConcern
end
def cleanup_types_de_champ_children!
draft_revision.types_de_champ.reject(&:repetition?).each do |type_de_champ|
draft_revision.remove_children_of(type_de_champ)
end
draft_revision.revision_types_de_champ
.filter(&:orphan?)
.each { draft_revision.remove_type_de_champ(_1.stable_id) }
end
end

View file

@ -39,7 +39,7 @@ class DossierPreloader
def revisions(pj_template: false)
@revisions ||= ProcedureRevision.where(id: @dossiers.pluck(:revision_id).uniq)
.includes(procedure: [], revision_types_de_champ: { parent: :type_de_champ }, types_de_champ_public: [], types_de_champ_private: [], types_de_champ: pj_template ? { piece_justificative_template_attachment: :blob } : [])
.includes(procedure: [], revision_types_de_champ: { parent_type_de_champ: [], types_de_champ: [] }, types_de_champ_public: [], types_de_champ_private: [], types_de_champ: pj_template ? { piece_justificative_template_attachment: :blob } : [])
.index_by(&:id)
end

View file

@ -45,22 +45,26 @@ class ProcedureRevision < ApplicationRecord
after_stable_id = params.delete(:after_stable_id)
after_coordinate, _ = coordinate_and_tdc(after_stable_id)
siblings = siblings_for(parent_coordinate:, private_tdc: params[:private])
type_de_champ = TypeDeChamp.new(params)
tdc = TypeDeChamp.new(params)
if tdc.save
if type_de_champ.save
siblings = siblings_for(type_de_champ:, parent_coordinate:)
position = next_position_for(after_coordinate:)
transaction do
# moving all the impacted tdc down
position = next_position_for(after_coordinate:, siblings:)
siblings.where("position >= ?", position).update_all("position = position + 1")
# insertion of the new tdc
h = { type_de_champ: tdc, parent_id: parent_id, position: position }
revision_types_de_champ.create!(h)
revision_types_de_champ.create!(type_de_champ:, parent_id:, position:)
end
tdc
revision_types_de_champ.reset
end
type_de_champ
rescue => e
TypeDeChamp.new.tap { |tdc| tdc.errors.add(:base, e.message) }
TypeDeChamp.new.tap { _1.errors.add(:base, e.message) }
end
def find_and_ensure_exclusive_use(stable_id)
@ -77,12 +81,17 @@ class ProcedureRevision < ApplicationRecord
coordinate, _ = coordinate_and_tdc(stable_id)
siblings = coordinate.siblings
transaction do
if position > coordinate.position
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
else
siblings.where(position: position..coordinate.position).update_all("position = position + 1")
end
coordinate.update_column(:position, position)
end
revision_types_de_champ.reset
coordinate.reload
coordinate
end
@ -90,6 +99,7 @@ class ProcedureRevision < ApplicationRecord
coordinate, _ = coordinate_and_tdc(stable_id)
siblings = coordinate.siblings
transaction do
if position > coordinate.position
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
coordinate.update_column(:position, position)
@ -97,9 +107,10 @@ class ProcedureRevision < ApplicationRecord
siblings.where(position: (position + 1)...coordinate.position).update_all("position = position + 1")
coordinate.update_column(:position, position + 1)
end
end
revision_types_de_champ.reset
coordinate.reload
coordinate
end
@ -110,13 +121,17 @@ class ProcedureRevision < ApplicationRecord
return nil if coordinate.nil?
children = children_of(tdc).to_a
transaction do
coordinate.destroy
children.each(&:destroy_if_orphan)
tdc.destroy_if_orphan
coordinate.siblings.where("position >= ?", coordinate.position).update_all("position = position - 1")
end
revision_types_de_champ.reset
coordinate
end
@ -181,33 +196,11 @@ class ProcedureRevision < ApplicationRecord
end
def children_of(tdc)
if revision_types_de_champ.loaded?
parent_coordinate_id = revision_types_de_champ
.filter { _1.type_de_champ_id == tdc.id }
.map(&:id)
revision_types_de_champ
.filter { _1.parent_id.in?(parent_coordinate_id) }
.sort_by(&:position)
.map(&:type_de_champ)
else
parent_coordinate_id = revision_types_de_champ.where(type_de_champ: tdc).select(:id)
types_de_champ
.where(procedure_revision_types_de_champ: { parent_id: parent_coordinate_id })
.order("procedure_revision_types_de_champ.position")
end
coordinate_for(tdc).types_de_champ
end
def parent_of(tdc)
revision_types_de_champ
.find { _1.type_de_champ_id == tdc.id }.parent&.type_de_champ
end
def remove_children_of(tdc)
children_of(tdc).each do |child|
remove_type_de_champ(child.stable_id)
end
coordinate_for(tdc).parent_type_de_champ
end
def dependent_conditions(tdc)
@ -268,24 +261,17 @@ class ProcedureRevision < ApplicationRecord
end
end
def children_types_de_champ_as_json(tdcs_as_json, parent_tdcs)
parent_tdcs.each do |parent_tdc|
tdc_as_json = tdcs_as_json.find { |json| json["id"] == parent_tdc.stable_id }
tdc_as_json&.merge!(types_de_champ: children_of(parent_tdc).includes(piece_justificative_template_attachment: :blob).map(&:as_json_for_editor))
end
end
def siblings_for(parent_coordinate: nil, private_tdc: false)
def siblings_for(type_de_champ:, parent_coordinate: nil)
if parent_coordinate
parent_coordinate.revision_types_de_champ
elsif private_tdc
elsif type_de_champ.private?
revision_types_de_champ_private
else
revision_types_de_champ_public
end
end
def next_position_for(siblings:, after_coordinate: nil)
def next_position_for(after_coordinate: nil)
# either we are at the beginning of the list or after another item
if after_coordinate.nil? # first element of the list, starts at 0
0
@ -477,10 +463,12 @@ class ProcedureRevision < ApplicationRecord
end
def replace_type_de_champ_by_clone(coordinate)
transaction do
cloned_type_de_champ = coordinate.type_de_champ.deep_clone do |original, kopy|
ClonePiecesJustificativesService.clone_attachments(original, kopy)
end
coordinate.update!(type_de_champ: cloned_type_de_champ)
cloned_type_de_champ
end
end
end

View file

@ -5,7 +5,9 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
belongs_to :type_de_champ
belongs_to :parent, class_name: 'ProcedureRevisionTypeDeChamp', optional: true
has_one :parent_type_de_champ, through: :parent, source: :type_de_champ
has_many :revision_types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'ProcedureRevisionTypeDeChamp', inverse_of: :parent, dependent: :destroy
has_many :types_de_champ, through: :revision_types_de_champ, source: :type_de_champ
has_one :procedure, through: :revision
scope :root, -> { where(parent: nil) }
scope :ordered, -> { order(:position, :id) }
@ -19,6 +21,10 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
parent_id.present?
end
def orphan?
child? && !parent_type_de_champ.repetition?
end
def first?
position == 0
end
@ -33,7 +39,7 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
def siblings
if child?
revision.revision_types_de_champ.where(parent_id:).ordered
parent.revision_types_de_champ
elsif private?
revision.revision_types_de_champ_private
else

View file

@ -336,7 +336,7 @@ class TypeDeChamp < ApplicationRecord
end
def child?(revision)
revision.revision_types_de_champ.find { _1.stable_id == stable_id }&.child?
revision.coordinate_for(self)&.child?
end
def filename_for_attachement(attachment_sym)
@ -403,10 +403,10 @@ class TypeDeChamp < ApplicationRecord
end
def level_for_revision(revision)
rtdc = revision.revision_types_de_champ.find { |rtdc| rtdc.stable_id == stable_id }
parent_type_de_champ = revision.parent_of(self)
if rtdc.child?
header_section_level_value.to_i + rtdc.parent.type_de_champ.current_section_level(revision)
if parent_type_de_champ.present?
header_section_level_value.to_i + parent_type_de_champ.current_section_level(revision)
elsif header_section_level_value
header_section_level_value.to_i
else

View file

@ -31,8 +31,9 @@ describe Champ do
end
context 'when repetition blank' do
let(:type_de_champ) { build(:type_de_champ_repetition) }
let(:champ) { Champs::RepetitionChamp.new(dossier: Dossier.new(revision: ProcedureRevision.new)) }
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, mandatory: false, children: [{ type: :text }] }]) }
let(:dossier) { create(:dossier, procedure:) }
let(:champ) { dossier.project_champs_public.find(&:repetition?) }
it { expect(champ.blank?).to be(true) }
end

View file

@ -830,6 +830,7 @@ describe ProcedureRevision do
.revision_types_de_champ
.where(type_de_champ: first_child)
.update(type_de_champ: new_child)
new_draft.revision_types_de_champ.reload
end
it 'returns the children regarding the revision' do

View file

@ -398,9 +398,8 @@ describe Procedure do
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).to include(invalid_repetition_error_message)
new_draft = procedure.draft_revision
repetition = procedure.draft_revision.types_de_champ_public.find(&:repetition?)
parent_coordinate = new_draft.revision_types_de_champ.find_by(type_de_champ: repetition)
new_draft.revision_types_de_champ.create(type_de_champ: create(:type_de_champ), position: 0, parent: parent_coordinate)
repetition = new_draft.types_de_champ_public.find(&:repetition?)
new_draft.add_type_de_champ(type_champ: :text, libelle: 'Nom', parent_stable_id: repetition.stable_id)
procedure.validate(:publication)
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).not_to include(invalid_repetition_error_message)