feat(dossier): optional repetition champ should not add first row
This commit is contained in:
parent
4ec9a4be37
commit
6924b8e46d
14 changed files with 32 additions and 62 deletions
|
@ -33,7 +33,7 @@ class Champs::RepetitionChamp < Champ
|
||||||
transaction do
|
transaction do
|
||||||
row_id = ULID.generate
|
row_id = ULID.generate
|
||||||
revision.children_of(type_de_champ).each do |type_de_champ|
|
revision.children_of(type_de_champ).each do |type_de_champ|
|
||||||
added_champs << type_de_champ.champ.build(row_id:)
|
added_champs << type_de_champ.build_champ(row_id:)
|
||||||
end
|
end
|
||||||
self.champs << added_champs
|
self.champs << added_champs
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,6 +58,7 @@ module DossierRebaseConcern
|
||||||
.joins(:type_de_champ)
|
.joins(:type_de_champ)
|
||||||
.group_by(&:stable_id)
|
.group_by(&:stable_id)
|
||||||
.transform_values { Champ.where(id: _1) }
|
.transform_values { Champ.where(id: _1) }
|
||||||
|
.tap { _1.default = Champ.none }
|
||||||
|
|
||||||
# add champ
|
# add champ
|
||||||
changes_by_op[:add]
|
changes_by_op[:add]
|
||||||
|
@ -67,12 +68,11 @@ module DossierRebaseConcern
|
||||||
.each { add_new_champs_for_revision(_1) }
|
.each { add_new_champs_for_revision(_1) }
|
||||||
|
|
||||||
# remove champ
|
# remove champ
|
||||||
changes_by_op[:remove]
|
changes_by_op[:remove].each { champs_by_stable_id[_1.stable_id].destroy_all }
|
||||||
.each { champs_by_stable_id[_1.stable_id].destroy_all }
|
|
||||||
|
|
||||||
|
# update champ
|
||||||
if brouillon?
|
if brouillon?
|
||||||
changes_by_op[:update]
|
changes_by_op[:update].each { apply(_1, champs_by_stable_id[_1.stable_id]) }
|
||||||
.each { apply(_1, champs_by_stable_id[_1.stable_id]) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# due to repetition tdc clone on update or erase
|
# due to repetition tdc clone on update or erase
|
||||||
|
@ -125,12 +125,12 @@ module DossierRebaseConcern
|
||||||
parent_stable_id = target_coordinate.parent.stable_id
|
parent_stable_id = target_coordinate.parent.stable_id
|
||||||
|
|
||||||
champs.filter { _1.stable_id == parent_stable_id }.each do |champ_repetition|
|
champs.filter { _1.stable_id == parent_stable_id }.each do |champ_repetition|
|
||||||
if champ_repetition.champs.empty?
|
if champ_repetition.champs.present?
|
||||||
create_champ(target_coordinate, champ_repetition, row_id: ULID.generate)
|
|
||||||
else
|
|
||||||
champ_repetition.champs.map(&:row_id).uniq.each do |row_id|
|
champ_repetition.champs.map(&:row_id).uniq.each do |row_id|
|
||||||
create_champ(target_coordinate, champ_repetition, row_id:)
|
create_champ(target_coordinate, champ_repetition, row_id:)
|
||||||
end
|
end
|
||||||
|
elsif champ_repetition.mandatory?
|
||||||
|
create_champ(target_coordinate, champ_repetition, row_id: ULID.generate)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -141,8 +141,7 @@ module DossierRebaseConcern
|
||||||
def create_champ(target_coordinate, parent, row_id: nil)
|
def create_champ(target_coordinate, parent, row_id: nil)
|
||||||
champ = target_coordinate
|
champ = target_coordinate
|
||||||
.type_de_champ
|
.type_de_champ
|
||||||
.champ
|
.build_champ(rebased_at: Time.zone.now, row_id:)
|
||||||
.build(rebased_at: Time.zone.now, row_id:)
|
|
||||||
parent.champs << champ
|
parent.champs << champ
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -507,6 +507,12 @@ class Dossier < ApplicationRecord
|
||||||
revision.build_champs_private.each do |champ|
|
revision.build_champs_private.each do |champ|
|
||||||
champs_private << champ
|
champs_private << champ
|
||||||
end
|
end
|
||||||
|
champs_public.filter { _1.repetition? && _1.mandatory? }.each do |champ|
|
||||||
|
champ.add_row(revision)
|
||||||
|
end
|
||||||
|
champs_private.filter(&:repetition?).each do |champ|
|
||||||
|
champ.add_row(revision)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_default_individual
|
def build_default_individual
|
||||||
|
|
|
@ -34,12 +34,12 @@ class ProcedureRevision < ApplicationRecord
|
||||||
|
|
||||||
def build_champs_public
|
def build_champs_public
|
||||||
# reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc
|
# reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc
|
||||||
types_de_champ_public.reload.map { |tdc| tdc.build_champ(revision: self) }
|
types_de_champ_public.reload.map(&:build_champ)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_champs_private
|
def build_champs_private
|
||||||
# reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc
|
# reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc
|
||||||
types_de_champ_private.reload.map { |tdc| tdc.build_champ(revision: self) }
|
types_de_champ_private.reload.map(&:build_champ)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_type_de_champ(params)
|
def add_type_de_champ(params)
|
||||||
|
|
|
@ -176,12 +176,10 @@ class TypeDeChamp < ApplicationRecord
|
||||||
|
|
||||||
has_many :champ, inverse_of: :type_de_champ, dependent: :destroy do
|
has_many :champ, inverse_of: :type_de_champ, dependent: :destroy do
|
||||||
def build(params = {})
|
def build(params = {})
|
||||||
params.delete(:revision)
|
|
||||||
super(params.merge(proxy_association.owner.params_for_champ))
|
super(params.merge(proxy_association.owner.params_for_champ))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(params = {})
|
def create(params = {})
|
||||||
params.delete(:revision)
|
|
||||||
super(params.merge(proxy_association.owner.params_for_champ))
|
super(params.merge(proxy_association.owner.params_for_champ))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -229,8 +227,8 @@ class TypeDeChamp < ApplicationRecord
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_champ(params)
|
def build_champ(params = {})
|
||||||
dynamic_type.build_champ(params)
|
champ.build(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_mandatory
|
def check_mandatory
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
class TypesDeChamp::RepetitionTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
class TypesDeChamp::RepetitionTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
def build_champ(params)
|
|
||||||
revision = params[:revision]
|
|
||||||
champ = super
|
|
||||||
champ.add_row(revision)
|
|
||||||
champ
|
|
||||||
end
|
|
||||||
|
|
||||||
def estimated_fill_duration(revision)
|
def estimated_fill_duration(revision)
|
||||||
estimated_rows_in_repetition = 2.5
|
estimated_rows_in_repetition = 2.5
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,6 @@ class TypesDeChamp::TypeDeChampBase
|
||||||
(words / READ_WORDS_PER_SECOND).round.seconds
|
(words / READ_WORDS_PER_SECOND).round.seconds
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_champ(params)
|
|
||||||
@type_de_champ.champ.build(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter_to_human(filter_value)
|
def filter_to_human(filter_value)
|
||||||
filter_value
|
filter_value
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
describe Champs::RepetitionController, type: :controller do
|
describe Champs::RepetitionController, type: :controller do
|
||||||
describe '#remove' do
|
describe '#remove' do
|
||||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, children: [{ libelle: 'Nom' }, { type: :integer_number, libelle: 'Age' }] }]) }
|
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'Nom' }, { type: :integer_number, libelle: 'Age' }] }]) }
|
||||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||||
|
|
||||||
before { sign_in dossier.user }
|
before { sign_in dossier.user }
|
||||||
|
|
|
@ -68,16 +68,7 @@ describe Champ do
|
||||||
|
|
||||||
describe '#sections' do
|
describe '#sections' do
|
||||||
let(:procedure) do
|
let(:procedure) do
|
||||||
create(:procedure, :with_type_de_champ, :with_type_de_champ_private, :with_repetition, types_de_champ_count: 1, types_de_champ_private_count: 1).tap do |procedure|
|
create(:procedure, types_de_champ_public: [{}, { type: :header_section }, { type: :repetition, mandatory: true, children: [{ type: :header_section }] }], types_de_champ_private: [{}, { type: :header_section }])
|
||||||
create(:type_de_champ_header_section, procedure: procedure)
|
|
||||||
create(:type_de_champ_header_section, procedure: procedure, private: true)
|
|
||||||
|
|
||||||
procedure.active_revision.add_type_de_champ(
|
|
||||||
libelle: 'header',
|
|
||||||
type_champ: 'header_section',
|
|
||||||
parent_stable_id: procedure.active_revision.types_de_champ_public.find(&:repetition?).stable_id
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||||
let(:public_champ) { dossier.champs_public.first }
|
let(:public_champ) { dossier.champs_public.first }
|
||||||
|
@ -500,7 +491,7 @@ describe Champ do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'repetition' do
|
describe 'repetition' do
|
||||||
let(:procedure) { create(:procedure, :published, :with_type_de_champ, :with_type_de_champ_private, :with_repetition) }
|
let(:procedure) { create(:procedure, :published, types_de_champ_private: [{}], types_de_champ_public: [{}, { type: :repetition, mandatory: true, children: [{}, { type: :integer_number }] }]) }
|
||||||
let(:tdc_repetition) { procedure.active_revision.types_de_champ_public.find(&:repetition?) }
|
let(:tdc_repetition) { procedure.active_revision.types_de_champ_public.find(&:repetition?) }
|
||||||
let(:tdc_text) { procedure.active_revision.children_of(tdc_repetition).first }
|
let(:tdc_text) { procedure.active_revision.children_of(tdc_repetition).first }
|
||||||
|
|
||||||
|
@ -510,10 +501,6 @@ describe Champ do
|
||||||
let(:champ_integer) { champ.champs.find { |c| c.type_champ == 'integer_number' } }
|
let(:champ_integer) { champ.champs.find { |c| c.type_champ == 'integer_number' } }
|
||||||
let(:champ_text_attrs) { attributes_for(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate) }
|
let(:champ_text_attrs) { attributes_for(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate) }
|
||||||
|
|
||||||
before do
|
|
||||||
procedure.active_revision.add_type_de_champ(libelle: 'sub integer', type_champ: 'integer_number', parent_stable_id: tdc_repetition.stable_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when creating the model directly' do
|
context 'when creating the model directly' do
|
||||||
let(:champ_text_row_1) { create(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate, parent: champ, dossier: nil) }
|
let(:champ_text_row_1) { create(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate, parent: champ, dossier: nil) }
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ describe Champs::HeaderSectionChamp do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for repetition champs' do
|
context 'for repetition champs' do
|
||||||
let(:types_de_champ_public) { [{ type: :repetition, children: types_de_champ }] }
|
let(:types_de_champ_public) { [{ type: :repetition, mandatory: true, children: types_de_champ }] }
|
||||||
|
|
||||||
let(:first_header) { dossier.champs_public.first.champs.first }
|
let(:first_header) { dossier.champs_public.first.champs.first }
|
||||||
let(:second_header) { dossier.champs_public.first.champs.fourth }
|
let(:second_header) { dossier.champs_public.first.champs.fourth }
|
||||||
|
|
|
@ -254,7 +254,7 @@ describe DossierRebaseConcern do
|
||||||
create(:procedure, types_de_champ_public: [
|
create(:procedure, types_de_champ_public: [
|
||||||
{ type: :text, mandatory: true, stable_id: 100 },
|
{ type: :text, mandatory: true, stable_id: 100 },
|
||||||
{
|
{
|
||||||
type: :repetition, stable_id: 101, children: [
|
type: :repetition, stable_id: 101, mandatory: true, children: [
|
||||||
{ type: :text, stable_id: 102 }
|
{ type: :text, stable_id: 102 }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -300,7 +300,8 @@ describe DossierRebaseConcern do
|
||||||
procedure.draft_revision.remove_type_de_champ(yes_no_type_de_champ.stable_id)
|
procedure.draft_revision.remove_type_de_champ(yes_no_type_de_champ.stable_id)
|
||||||
new_repetition_type_de_champ = procedure.draft_revision.add_type_de_champ({
|
new_repetition_type_de_champ = procedure.draft_revision.add_type_de_champ({
|
||||||
type_champ: TypeDeChamp.type_champs.fetch(:repetition),
|
type_champ: TypeDeChamp.type_champs.fetch(:repetition),
|
||||||
libelle: "une autre repetition"
|
libelle: "une autre repetition",
|
||||||
|
mandatory: true
|
||||||
})
|
})
|
||||||
procedure.draft_revision.add_type_de_champ({
|
procedure.draft_revision.add_type_de_champ({
|
||||||
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
||||||
|
@ -610,7 +611,7 @@ describe DossierRebaseConcern do
|
||||||
context 'with a procedure with a repetition' do
|
context 'with a procedure with a repetition' do
|
||||||
let!(:procedure) do
|
let!(:procedure) do
|
||||||
create(:procedure).tap do |p|
|
create(:procedure).tap do |p|
|
||||||
repetition = p.draft_revision.add_type_de_champ(type_champ: :repetition, libelle: 'p1')
|
repetition = p.draft_revision.add_type_de_champ(type_champ: :repetition, libelle: 'p1', mandatory: true)
|
||||||
p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c1', parent_stable_id: repetition.stable_id)
|
p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c1', parent_stable_id: repetition.stable_id)
|
||||||
p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c2', parent_stable_id: repetition.stable_id)
|
p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c2', parent_stable_id: repetition.stable_id)
|
||||||
p.publish!
|
p.publish!
|
||||||
|
|
|
@ -162,18 +162,8 @@ describe TagsSubstitutionConcern, type: :model do
|
||||||
|
|
||||||
context 'when the procedure has a type de champ repetition' do
|
context 'when the procedure has a type de champ repetition' do
|
||||||
let(:template) { '--Répétition--' }
|
let(:template) { '--Répétition--' }
|
||||||
let(:repetition) do
|
let(:types_de_champ_public) { [{ type: :repetition, libelle: 'Répétition', mandatory: true, children: [{ libelle: 'Nom' }, { libelle: 'Prénom' }] }] }
|
||||||
repetition_tdc = procedure.active_revision.add_type_de_champ(type_champ: 'repetition', libelle: 'Répétition')
|
let(:dossier) { create(:dossier, procedure:) }
|
||||||
procedure.active_revision.add_type_de_champ(type_champ: 'text', libelle: 'Nom', parent_stable_id: repetition_tdc.stable_id)
|
|
||||||
procedure.active_revision.add_type_de_champ(type_champ: 'text', libelle: 'Prénom', parent_stable_id: repetition_tdc.stable_id)
|
|
||||||
|
|
||||||
repetition_tdc
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:dossier) do
|
|
||||||
repetition
|
|
||||||
create(:dossier, procedure: procedure)
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
repetition = dossier.champs_public
|
repetition = dossier.champs_public
|
||||||
|
|
|
@ -2,7 +2,7 @@ describe DossierPreloader do
|
||||||
let(:types_de_champ) do
|
let(:types_de_champ) do
|
||||||
[
|
[
|
||||||
{ type: :text },
|
{ type: :text },
|
||||||
{ type: :repetition, children: [{ type: :text }] }
|
{ type: :repetition, mandatory: true, children: [{ type: :text }] }
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
let(:procedure) { create(:procedure, types_de_champ_public: types_de_champ) }
|
let(:procedure) { create(:procedure, types_de_champ_public: types_de_champ) }
|
||||||
|
|
|
@ -104,7 +104,7 @@ describe 'The user' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:procedure_with_repetition) do
|
let(:procedure_with_repetition) do
|
||||||
create(:procedure, :published, :for_individual, :with_repetition)
|
create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'sub type de champ' }] }])
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'fill a dossier with repetition', js: true do
|
scenario 'fill a dossier with repetition', js: true do
|
||||||
|
@ -333,7 +333,7 @@ describe 'The user' do
|
||||||
types_de_champ_public: [
|
types_de_champ_public: [
|
||||||
{ type: :checkbox, libelle: 'champ_a', stable_id: a_stable_id },
|
{ type: :checkbox, libelle: 'champ_a', stable_id: a_stable_id },
|
||||||
{
|
{
|
||||||
type: :repetition, libelle: 'repetition', children: [
|
type: :repetition, libelle: 'repetition', mandatory: true, children: [
|
||||||
{ type: :checkbox, libelle: 'champ_b', stable_id: b_stable_id },
|
{ type: :checkbox, libelle: 'champ_b', stable_id: b_stable_id },
|
||||||
{ type: :text, libelle: 'champ_c', condition: }
|
{ type: :text, libelle: 'champ_c', condition: }
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue