refactor(type_de_champ): improve and clean helper methods
This commit is contained in:
parent
5a2ab37049
commit
71009094a4
8 changed files with 74 additions and 79 deletions
|
@ -122,8 +122,8 @@ module ProcedurePublishConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def cleanup_types_de_champ_children!
|
def cleanup_types_de_champ_children!
|
||||||
draft_revision.types_de_champ.reject(&:repetition?).each do |type_de_champ|
|
draft_revision.revision_types_de_champ
|
||||||
draft_revision.remove_children_of(type_de_champ)
|
.filter(&:orphan?)
|
||||||
end
|
.each { draft_revision.remove_type_de_champ(_1.stable_id) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,7 +39,7 @@ class DossierPreloader
|
||||||
|
|
||||||
def revisions(pj_template: false)
|
def revisions(pj_template: false)
|
||||||
@revisions ||= ProcedureRevision.where(id: @dossiers.pluck(:revision_id).uniq)
|
@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)
|
.index_by(&:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -45,22 +45,26 @@ class ProcedureRevision < ApplicationRecord
|
||||||
after_stable_id = params.delete(:after_stable_id)
|
after_stable_id = params.delete(:after_stable_id)
|
||||||
after_coordinate, _ = coordinate_and_tdc(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 type_de_champ.save
|
||||||
if tdc.save
|
siblings = siblings_for(type_de_champ:, parent_coordinate:)
|
||||||
|
position = next_position_for(after_coordinate:)
|
||||||
|
|
||||||
|
transaction do
|
||||||
# moving all the impacted tdc down
|
# moving all the impacted tdc down
|
||||||
position = next_position_for(after_coordinate:, siblings:)
|
|
||||||
siblings.where("position >= ?", position).update_all("position = position + 1")
|
siblings.where("position >= ?", position).update_all("position = position + 1")
|
||||||
|
|
||||||
# insertion of the new tdc
|
# insertion of the new tdc
|
||||||
h = { type_de_champ: tdc, parent_id: parent_id, position: position }
|
revision_types_de_champ.create!(type_de_champ:, parent_id:, position:)
|
||||||
revision_types_de_champ.create!(h)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
tdc
|
revision_types_de_champ.reset
|
||||||
|
end
|
||||||
|
|
||||||
|
type_de_champ
|
||||||
rescue => e
|
rescue => e
|
||||||
TypeDeChamp.new.tap { |tdc| tdc.errors.add(:base, e.message) }
|
TypeDeChamp.new.tap { _1.errors.add(:base, e.message) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_and_ensure_exclusive_use(stable_id)
|
def find_and_ensure_exclusive_use(stable_id)
|
||||||
|
@ -77,12 +81,17 @@ class ProcedureRevision < ApplicationRecord
|
||||||
coordinate, _ = coordinate_and_tdc(stable_id)
|
coordinate, _ = coordinate_and_tdc(stable_id)
|
||||||
siblings = coordinate.siblings
|
siblings = coordinate.siblings
|
||||||
|
|
||||||
|
transaction do
|
||||||
if position > coordinate.position
|
if position > coordinate.position
|
||||||
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
|
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
|
||||||
else
|
else
|
||||||
siblings.where(position: position..coordinate.position).update_all("position = position + 1")
|
siblings.where(position: position..coordinate.position).update_all("position = position + 1")
|
||||||
end
|
end
|
||||||
coordinate.update_column(:position, position)
|
coordinate.update_column(:position, position)
|
||||||
|
end
|
||||||
|
|
||||||
|
revision_types_de_champ.reset
|
||||||
|
coordinate.reload
|
||||||
coordinate
|
coordinate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,6 +99,7 @@ class ProcedureRevision < ApplicationRecord
|
||||||
coordinate, _ = coordinate_and_tdc(stable_id)
|
coordinate, _ = coordinate_and_tdc(stable_id)
|
||||||
siblings = coordinate.siblings
|
siblings = coordinate.siblings
|
||||||
|
|
||||||
|
transaction do
|
||||||
if position > coordinate.position
|
if position > coordinate.position
|
||||||
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
|
siblings.where(position: coordinate.position..position).update_all("position = position - 1")
|
||||||
coordinate.update_column(:position, position)
|
coordinate.update_column(:position, position)
|
||||||
|
@ -97,9 +107,10 @@ class ProcedureRevision < ApplicationRecord
|
||||||
siblings.where(position: (position + 1)...coordinate.position).update_all("position = position + 1")
|
siblings.where(position: (position + 1)...coordinate.position).update_all("position = position + 1")
|
||||||
coordinate.update_column(:position, position + 1)
|
coordinate.update_column(:position, position + 1)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
revision_types_de_champ.reset
|
||||||
coordinate.reload
|
coordinate.reload
|
||||||
|
|
||||||
coordinate
|
coordinate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,13 +121,17 @@ class ProcedureRevision < ApplicationRecord
|
||||||
return nil if coordinate.nil?
|
return nil if coordinate.nil?
|
||||||
|
|
||||||
children = children_of(tdc).to_a
|
children = children_of(tdc).to_a
|
||||||
|
|
||||||
|
transaction do
|
||||||
coordinate.destroy
|
coordinate.destroy
|
||||||
|
|
||||||
children.each(&:destroy_if_orphan)
|
children.each(&:destroy_if_orphan)
|
||||||
tdc.destroy_if_orphan
|
tdc.destroy_if_orphan
|
||||||
|
|
||||||
coordinate.siblings.where("position >= ?", coordinate.position).update_all("position = position - 1")
|
coordinate.siblings.where("position >= ?", coordinate.position).update_all("position = position - 1")
|
||||||
|
end
|
||||||
|
|
||||||
|
revision_types_de_champ.reset
|
||||||
coordinate
|
coordinate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -181,33 +196,11 @@ class ProcedureRevision < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def children_of(tdc)
|
def children_of(tdc)
|
||||||
if revision_types_de_champ.loaded?
|
coordinate_for(tdc).types_de_champ
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent_of(tdc)
|
def parent_of(tdc)
|
||||||
revision_types_de_champ
|
coordinate_for(tdc).parent_type_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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def dependent_conditions(tdc)
|
def dependent_conditions(tdc)
|
||||||
|
@ -268,24 +261,17 @@ class ProcedureRevision < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def children_types_de_champ_as_json(tdcs_as_json, parent_tdcs)
|
def siblings_for(type_de_champ:, parent_coordinate: nil)
|
||||||
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)
|
|
||||||
if parent_coordinate
|
if parent_coordinate
|
||||||
parent_coordinate.revision_types_de_champ
|
parent_coordinate.revision_types_de_champ
|
||||||
elsif private_tdc
|
elsif type_de_champ.private?
|
||||||
revision_types_de_champ_private
|
revision_types_de_champ_private
|
||||||
else
|
else
|
||||||
revision_types_de_champ_public
|
revision_types_de_champ_public
|
||||||
end
|
end
|
||||||
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
|
# 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
|
if after_coordinate.nil? # first element of the list, starts at 0
|
||||||
0
|
0
|
||||||
|
@ -477,10 +463,12 @@ class ProcedureRevision < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_type_de_champ_by_clone(coordinate)
|
def replace_type_de_champ_by_clone(coordinate)
|
||||||
|
transaction do
|
||||||
cloned_type_de_champ = coordinate.type_de_champ.deep_clone do |original, kopy|
|
cloned_type_de_champ = coordinate.type_de_champ.deep_clone do |original, kopy|
|
||||||
ClonePiecesJustificativesService.clone_attachments(original, kopy)
|
ClonePiecesJustificativesService.clone_attachments(original, kopy)
|
||||||
end
|
end
|
||||||
coordinate.update!(type_de_champ: cloned_type_de_champ)
|
coordinate.update!(type_de_champ: cloned_type_de_champ)
|
||||||
cloned_type_de_champ
|
cloned_type_de_champ
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,9 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
||||||
belongs_to :type_de_champ
|
belongs_to :type_de_champ
|
||||||
|
|
||||||
belongs_to :parent, class_name: 'ProcedureRevisionTypeDeChamp', optional: true
|
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 :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
|
has_one :procedure, through: :revision
|
||||||
scope :root, -> { where(parent: nil) }
|
scope :root, -> { where(parent: nil) }
|
||||||
scope :ordered, -> { order(:position, :id) }
|
scope :ordered, -> { order(:position, :id) }
|
||||||
|
@ -19,6 +21,10 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
||||||
parent_id.present?
|
parent_id.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def orphan?
|
||||||
|
child? && !parent_type_de_champ.repetition?
|
||||||
|
end
|
||||||
|
|
||||||
def first?
|
def first?
|
||||||
position == 0
|
position == 0
|
||||||
end
|
end
|
||||||
|
@ -33,7 +39,7 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
||||||
|
|
||||||
def siblings
|
def siblings
|
||||||
if child?
|
if child?
|
||||||
revision.revision_types_de_champ.where(parent_id:).ordered
|
parent.revision_types_de_champ
|
||||||
elsif private?
|
elsif private?
|
||||||
revision.revision_types_de_champ_private
|
revision.revision_types_de_champ_private
|
||||||
else
|
else
|
||||||
|
|
|
@ -336,7 +336,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def child?(revision)
|
def child?(revision)
|
||||||
revision.revision_types_de_champ.find { _1.stable_id == stable_id }&.child?
|
revision.coordinate_for(self)&.child?
|
||||||
end
|
end
|
||||||
|
|
||||||
def filename_for_attachement(attachment_sym)
|
def filename_for_attachement(attachment_sym)
|
||||||
|
@ -403,10 +403,10 @@ class TypeDeChamp < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def level_for_revision(revision)
|
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?
|
if parent_type_de_champ.present?
|
||||||
header_section_level_value.to_i + rtdc.parent.type_de_champ.current_section_level(revision)
|
header_section_level_value.to_i + parent_type_de_champ.current_section_level(revision)
|
||||||
elsif header_section_level_value
|
elsif header_section_level_value
|
||||||
header_section_level_value.to_i
|
header_section_level_value.to_i
|
||||||
else
|
else
|
||||||
|
|
|
@ -31,8 +31,9 @@ describe Champ do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when repetition blank' do
|
context 'when repetition blank' do
|
||||||
let(:type_de_champ) { build(:type_de_champ_repetition) }
|
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, mandatory: false, children: [{ type: :text }] }]) }
|
||||||
let(:champ) { Champs::RepetitionChamp.new(dossier: Dossier.new(revision: ProcedureRevision.new)) }
|
let(:dossier) { create(:dossier, procedure:) }
|
||||||
|
let(:champ) { dossier.project_champs_public.find(&:repetition?) }
|
||||||
|
|
||||||
it { expect(champ.blank?).to be(true) }
|
it { expect(champ.blank?).to be(true) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -830,6 +830,7 @@ describe ProcedureRevision do
|
||||||
.revision_types_de_champ
|
.revision_types_de_champ
|
||||||
.where(type_de_champ: first_child)
|
.where(type_de_champ: first_child)
|
||||||
.update(type_de_champ: new_child)
|
.update(type_de_champ: new_child)
|
||||||
|
new_draft.revision_types_de_champ.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the children regarding the revision' do
|
it 'returns the children regarding the revision' do
|
||||||
|
|
|
@ -398,9 +398,8 @@ describe Procedure do
|
||||||
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).to include(invalid_repetition_error_message)
|
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).to include(invalid_repetition_error_message)
|
||||||
|
|
||||||
new_draft = procedure.draft_revision
|
new_draft = procedure.draft_revision
|
||||||
repetition = procedure.draft_revision.types_de_champ_public.find(&:repetition?)
|
repetition = new_draft.types_de_champ_public.find(&:repetition?)
|
||||||
parent_coordinate = new_draft.revision_types_de_champ.find_by(type_de_champ: repetition)
|
new_draft.add_type_de_champ(type_champ: :text, libelle: 'Nom', parent_stable_id: repetition.stable_id)
|
||||||
new_draft.revision_types_de_champ.create(type_de_champ: create(:type_de_champ), position: 0, parent: parent_coordinate)
|
|
||||||
|
|
||||||
procedure.validate(:publication)
|
procedure.validate(:publication)
|
||||||
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).not_to include(invalid_repetition_error_message)
|
expect(procedure.errors.messages_for(:draft_types_de_champ_public)).not_to include(invalid_repetition_error_message)
|
||||||
|
|
Loading…
Reference in a new issue