remaniement(dossier.clone): simplifications, pas de callback/after, pas d'heritage, mm interface pour cloner les champs public/prive, clonage des PJs avec le nouveau service de clone, ajoute une cle etrangere sur la colonne parent_dossier_id
This commit is contained in:
parent
90f7d265c6
commit
18b7f4e4fa
15 changed files with 55 additions and 131 deletions
|
@ -1,5 +0,0 @@
|
|||
class ClonePieceJustificativeJob < ApplicationJob
|
||||
def perform(from_champ, kopy_champ)
|
||||
from_champ.clone_piece_justificative(kopy_champ)
|
||||
end
|
||||
end
|
|
@ -30,7 +30,6 @@ class Champ < ApplicationRecord
|
|||
has_many :geo_areas, -> { order(:created_at) }, dependent: :destroy, inverse_of: :champ
|
||||
belongs_to :etablissement, optional: true, dependent: :destroy
|
||||
has_many :champs, -> { ordered }, foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy
|
||||
after_create_commit :after_clone, if: :cloned?
|
||||
|
||||
delegate :libelle,
|
||||
:type_champ,
|
||||
|
@ -217,26 +216,20 @@ class Champ < ApplicationRecord
|
|||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = deep_clone(only: [:data, :private, :row, :type, :value, :value_json, :external_id, :type_de_champ_id])
|
||||
kopy = deep_clone(only: (private? ? [] : [:value, :value_json]) + [:data, :private, :row, :type, :external_id, :type_de_champ_id],
|
||||
include: private? ? [] : [:etablissement, :geo_areas])
|
||||
|
||||
kopy.dossier = dossier
|
||||
kopy.parent = parent if parent
|
||||
kopy
|
||||
end
|
||||
|
||||
def mark_for_delayed_clone_piece_justificative(from)
|
||||
if from.piece_justificative_file.attached?
|
||||
@cloned_from = from
|
||||
@cloned_kopy = self
|
||||
case self
|
||||
when Champs::RepetitionChamp
|
||||
kopy.champs = (private? ? champs.where(row: 0) : champs).map do |champ_de_repetition|
|
||||
champ_de_repetition.clone(dossier: dossier, parent: kopy)
|
||||
end
|
||||
when Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp
|
||||
PiecesJustificativesService.clone_attachments(self, kopy) if !private? && piece_justificative_file.attached?
|
||||
end
|
||||
end
|
||||
|
||||
def after_clone
|
||||
ClonePieceJustificativeJob.perform_later(@cloned_from, @cloned_kopy)
|
||||
end
|
||||
|
||||
def cloned?
|
||||
@cloned_from && @cloned_kopy
|
||||
kopy
|
||||
end
|
||||
|
||||
def clone_piece_justificative(kopy)
|
||||
|
|
|
@ -115,13 +115,6 @@ class Champs::CarteChamp < Champ
|
|||
geo_areas.blank?
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = super(dossier: dossier, parent: parent)
|
||||
|
||||
kopy.geo_areas = geo_areas.map(&:dup)
|
||||
kopy
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def selection_utilisateur_legacy_geometry
|
||||
|
|
|
@ -51,11 +51,4 @@ class Champs::PieceJustificativeChamp < Champ
|
|||
piece_justificative_file.service_url
|
||||
end
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = super(dossier: dossier, parent: parent)
|
||||
|
||||
kopy.mark_for_delayed_clone_piece_justificative(self)
|
||||
kopy
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,13 +77,4 @@ class Champs::RepetitionChamp < Champ
|
|||
] + Dossier.champs_for_export(champs, types_de_champ)
|
||||
end
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = super(dossier: dossier, parent: parent)
|
||||
|
||||
kopy.champs = champs.map do |champ_de_repetition|
|
||||
champ_de_repetition.clone(dossier: dossier, parent: kopy)
|
||||
end
|
||||
kopy
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,11 +27,4 @@ class Champs::SiretChamp < Champ
|
|||
def mandatory_blank?
|
||||
mandatory? && Siret.new(siret: value).invalid?
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = super(dossier: dossier, parent: parent)
|
||||
|
||||
kopy.etablissement = etablissement.dup
|
||||
kopy
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,11 +43,4 @@ class Champs::TitreIdentiteChamp < Champ
|
|||
def for_api
|
||||
nil
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = super(dossier: dossier, parent: parent)
|
||||
|
||||
mark_for_delayed_clone_piece_justificative(kopy)
|
||||
kopy
|
||||
end
|
||||
end
|
||||
|
|
|
@ -131,6 +131,8 @@ class Dossier < ApplicationRecord
|
|||
belongs_to :groupe_instructeur, optional: true
|
||||
belongs_to :revision, class_name: 'ProcedureRevision', optional: false
|
||||
belongs_to :user, optional: true
|
||||
belongs_to :parent_dossier, class_name: 'Dossier', optional: true
|
||||
|
||||
has_one :france_connect_information, through: :user
|
||||
|
||||
has_one :attestation_template, through: :revision
|
||||
|
@ -140,6 +142,7 @@ class Dossier < ApplicationRecord
|
|||
|
||||
belongs_to :transfer, class_name: 'DossierTransfer', foreign_key: 'dossier_transfer_id', optional: true, inverse_of: :dossiers
|
||||
has_many :transfer_logs, class_name: 'DossierTransferLog', dependent: :destroy
|
||||
has_many :parent_dossiers, class_name: 'Dossier', foreign_key: 'parent_dossier_id', dependent: :nullify, inverse_of: :parent_dossier
|
||||
|
||||
accepts_nested_attributes_for :champs_public
|
||||
accepts_nested_attributes_for :champs_private
|
||||
|
@ -475,7 +478,7 @@ class Dossier < ApplicationRecord
|
|||
end
|
||||
|
||||
def build_default_champs_for_new_dossier
|
||||
revision.build_champs.each do |champ|
|
||||
revision.build_champs_public.each do |champ|
|
||||
champs_public << champ
|
||||
end
|
||||
revision.build_champs_private.each do |champ|
|
||||
|
@ -1179,14 +1182,20 @@ class Dossier < ApplicationRecord
|
|||
@sections[champ.parent || (champ.public? ? :public : :private)]
|
||||
end
|
||||
|
||||
# while cloning we do not have champ.id. it comes after transaction
|
||||
# so we collect a list of jobs to process. then enqueue this list
|
||||
def clone
|
||||
cloned_dossier = deep_clone(only: [:autorisation_donnees, :user_id, :revision_id, :groupe_instructeur_id],
|
||||
include: [:individual, :etablissement]) do |original, kopy|
|
||||
if original.is_a?(Dossier)
|
||||
kopy.parent_dossier_id = original.id
|
||||
kopy.state = Dossier.states.fetch(:brouillon)
|
||||
kopy.champs = original.champs.map { |champ| champ.clone(dossier: kopy) }
|
||||
kopy.champs_private = kopy.revision.types_de_champ_private.map { |tdc| tdc.build_champ(revision: kopy.revision, dossier: kopy) }
|
||||
kopy.champs_public = original.champs_public.map do |champ|
|
||||
champ.clone(dossier: kopy)
|
||||
end
|
||||
kopy.champs_private = original.champs_private.map do |champ|
|
||||
champ.clone(dossier: kopy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ class PiecesJustificativesService
|
|||
|
||||
def self.clone_attachments(original, kopy)
|
||||
case original
|
||||
when Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp
|
||||
clone_attachment(original.piece_justificative_file, kopy.piece_justificative_file)
|
||||
when TypeDeChamp
|
||||
clone_attachment(original.piece_justificative_template, kopy.piece_justificative_template)
|
||||
when Procedure
|
||||
|
|
|
@ -249,8 +249,8 @@ en:
|
|||
actions: "Actions"
|
||||
dossier_action:
|
||||
edit_dossier: "Edit the file"
|
||||
start_other_dossier: "Start an other empty file"
|
||||
clone: "Clone this file"
|
||||
start_other_dossier: "Start another empty file"
|
||||
clone: "Duplicate the file"
|
||||
delete_dossier: "Delete the file"
|
||||
transfer_dossier: "Transfer the file"
|
||||
edit_draft: "Edit the draft"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddForeignKeyToParentDossierId < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_foreign_key "dossiers", "dossiers", column: "parent_dossier_id", validate: false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class ValidateForeignKeyToParentDossierId < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
validate_foreign_key "dossiers", "dossiers"
|
||||
end
|
||||
end
|
|
@ -10,8 +10,8 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_11_10_100759) do
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_11_07_163131) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
enable_extension "plpgsql"
|
||||
|
@ -921,6 +921,7 @@ ActiveRecord::Schema.define(version: 2022_11_07_163131) do
|
|||
add_foreign_key "dossier_operation_logs", "bill_signatures"
|
||||
add_foreign_key "dossier_transfer_logs", "dossiers"
|
||||
add_foreign_key "dossiers", "dossier_transfers"
|
||||
add_foreign_key "dossiers", "dossiers", column: "parent_dossier_id"
|
||||
add_foreign_key "dossiers", "groupe_instructeurs"
|
||||
add_foreign_key "dossiers", "procedure_revisions", column: "revision_id"
|
||||
add_foreign_key "dossiers", "users"
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
describe ClonePieceJustificativeJob, type: :job do
|
||||
describe 'perform' do
|
||||
let(:dossier_from) { create(:dossier) }
|
||||
let(:dossier_to) { create(:dossier, procedure: dossier_from.procedure) }
|
||||
let(:champ_piece_justificative_from) { create(:champ, :with_piece_justificative_file, dossier_id: dossier_from.id) }
|
||||
let(:champ_piece_justificative_to) { create(:champ_without_piece_justificative, dossier_id: dossier_to.id, piece_justificative_file: nil) }
|
||||
|
||||
it 'creates a piece_justificative_file' do
|
||||
expect {
|
||||
ClonePieceJustificativeJob.perform_now(champ_piece_justificative_from, champ_piece_justificative_to)
|
||||
}.to change { champ_piece_justificative_to.piece_justificative_file.blob }.from(nil).to an_instance_of(ActiveStorage::Blob)
|
||||
end
|
||||
it 'creates a piece_justificative_file' do
|
||||
ClonePieceJustificativeJob.perform_now(champ_piece_justificative_from, champ_piece_justificative_to)
|
||||
expect(champ_piece_justificative_to.piece_justificative_file.blob.download)
|
||||
.to eq(champ_piece_justificative_from.piece_justificative_file.blob.download)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1732,14 +1732,15 @@ describe Dossier do
|
|||
let(:dossier) { create(:dossier, :accepte) }
|
||||
|
||||
it { expect(new_dossier.brouillon?).to eq(true) }
|
||||
it { expect(new_dossier.parent_dossier_id).to eq(dossier.id) }
|
||||
end
|
||||
it { expect(new_dossier.parent_dossier).to eq(dossier) }
|
||||
|
||||
context 'links type_de_champ' do
|
||||
it { expect(new_dossier.types_de_champ.count).to eq(1) }
|
||||
it { expect(new_dossier.types_de_champ).to eq(dossier.types_de_champ) }
|
||||
it { expect(new_dossier.types_de_champ_private.count).to eq(1) }
|
||||
it { expect(new_dossier.types_de_champ_private).to eq(dossier.types_de_champ_private) }
|
||||
context 'destroy parent' do
|
||||
before { new_dossier }
|
||||
|
||||
it 'clean fk' do
|
||||
expect { dossier.destroy }.to change { new_dossier.reload.parent_dossier_id }.from(dossier.id).to(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'procedure with_individual' do
|
||||
|
@ -1754,55 +1755,25 @@ describe Dossier do
|
|||
it { expect(new_dossier.etablissement.id).not_to eq(dossier.etablissement.id) }
|
||||
end
|
||||
|
||||
describe 'skips commentaires' do
|
||||
let(:dossier) { create(:dossier, :with_commentaires) }
|
||||
|
||||
it { expect(new_dossier.commentaires.count).not_to eq(dossier.commentaires.count) }
|
||||
it { expect(new_dossier.commentaires.size).to eq(0) }
|
||||
end
|
||||
|
||||
describe 'skips invites' do
|
||||
let(:dossier) { create(:dossier, :with_invites) }
|
||||
|
||||
it { expect(new_dossier.invites.count).not_to eq(dossier.invites.count) }
|
||||
it { expect(new_dossier.invites.count).to eq(0) }
|
||||
end
|
||||
|
||||
describe 'skips avis' do
|
||||
let(:dossier) { create(:dossier, :with_avis) }
|
||||
|
||||
it { expect(new_dossier.avis.count).not_to eq(dossier.avis.count) }
|
||||
it { expect(new_dossier.avis.count).to eq(0) }
|
||||
it { expect(new_dossier.experts.count).not_to eq(dossier.experts.count) }
|
||||
it { expect(new_dossier.experts.count).to eq(0) }
|
||||
end
|
||||
|
||||
describe 'skips dossier_operation_logs' do
|
||||
let(:dossier) { create(:dossier, :accepte, :with_dossier_operation_logs) }
|
||||
|
||||
it { expect(new_dossier.dossier_operation_logs.count).not_to eq(dossier.dossier_operation_logs.count) }
|
||||
it { expect(new_dossier.dossier_operation_logs.count).to eq(0) }
|
||||
end
|
||||
|
||||
describe 'champs' do
|
||||
it { expect(new_dossier.id).not_to eq(dossier.id) }
|
||||
|
||||
context 'public are duplicated' do
|
||||
it { expect(new_dossier.champs.count).to eq(dossier.champs.count) }
|
||||
it { expect(new_dossier.champs.ids).not_to eq(dossier.champs.ids) }
|
||||
it { expect(new_dossier.champs_public.count).to eq(dossier.champs_public.count) }
|
||||
it { expect(new_dossier.champs_public.ids).not_to eq(dossier.champs_public.ids) }
|
||||
|
||||
it 'keeps champs.values' do
|
||||
original_first_champ = dossier.champs.first
|
||||
original_first_champ = dossier.champs_public.first
|
||||
original_first_champ.update!(value: 'kthxbye')
|
||||
|
||||
expect(new_dossier.champs.first.value).to eq(original_first_champ.value)
|
||||
expect(new_dossier.champs_public.first.value).to eq(original_first_champ.value)
|
||||
end
|
||||
|
||||
context 'for Champs::Repetition with rows, original_champ.repetition and rows are duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, procedure: dossier.procedure) }
|
||||
let(:champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
|
||||
before { dossier.champs << champ_repetition }
|
||||
before { dossier.champs_public << champ_repetition }
|
||||
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(4) }
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.ids).not_to eq(champ_repetition.champs.ids) }
|
||||
|
@ -1813,7 +1784,7 @@ describe Dossier do
|
|||
let(:type_de_champ_carte) { create(:type_de_champ_carte, procedure: dossier.procedure) }
|
||||
let(:geo_area) { create(:geo_area, :selection_utilisateur, :polygon) }
|
||||
let(:champ_carte) { create(:champ_carte, type_de_champ: type_de_champ_carte, geo_areas: [geo_area]) }
|
||||
before { dossier.champs << champ_carte }
|
||||
before { dossier.champs_public << champ_carte }
|
||||
|
||||
it { expect(Champs::CarteChamp.where(dossier: new_dossier).first.geo_areas.count).to eq(1) }
|
||||
it { expect(Champs::CarteChamp.where(dossier: new_dossier).first.geo_areas.ids).not_to eq(champ_carte.geo_areas.ids) }
|
||||
|
@ -1824,7 +1795,7 @@ describe Dossier do
|
|||
let(:type_de_champs_siret) { create(:type_de_champ_siret, procedure: dossier.procedure) }
|
||||
let(:etablissement) { create(:etablissement) }
|
||||
let(:champ_siret) { create(:champ_siret, type_de_champ: type_de_champs_siret, etablissement: create(:etablissement)) }
|
||||
before { dossier.champs << champ_siret }
|
||||
before { dossier.champs_public << champ_siret }
|
||||
|
||||
it { expect(Champs::SiretChamp.where(dossier: dossier).first.etablissement).not_to be_nil }
|
||||
it { expect(Champs::SiretChamp.where(dossier: new_dossier).first.etablissement.id).not_to eq(champ_siret.etablissement.id) }
|
||||
|
@ -1833,9 +1804,8 @@ describe Dossier do
|
|||
context 'for Champs::PieceJustificative, original_champ.piece_justificative_file is duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ_piece_justificative) { create(:champ_piece_justificative, dossier_id: dossier.id) }
|
||||
before { dossier.champs << champ_piece_justificative }
|
||||
it { expect(Champs::PieceJustificativeChamp.where(dossier: new_dossier).first.piece_justificative_file.blob).to be_nil }
|
||||
it { expect { new_dossier }.to have_enqueued_job(ClonePieceJustificativeJob) }
|
||||
before { dossier.champs_public << champ_piece_justificative }
|
||||
it { expect(Champs::PieceJustificativeChamp.where(dossier: new_dossier).first.piece_justificative_file.blob).to eq(champ_piece_justificative.piece_justificative_file.blob) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue