diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 3539bf53e..d56321a14 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -744,11 +744,27 @@ class TypeDeChamp < ApplicationRecord # no champ return true if champ.nil? # type de champ on the revision changed - return true if type_champ_to_champ_class_name(type_champ) != champ.type + if type_champ != champ.type_champ + return !castable_on_change?(type_champ, champ.type_champ) + end # special case for linked drop down champ – it's blank implementation is not what you think return champ.value.blank? if type_champ == TypeDeChamp.type_champs.fetch(:linked_drop_down_list) champ.blank? end + + def castable_on_change?(from_type, to_type) + case [from_type, to_type] + when ['integer_number', 'decimal_number'], # recast numbers automatically + ['decimal_number', 'integer_number'], # may lose some data, but who cares ? + ['text', 'textarea'], # allow short text to long text + ['drop_down_list', 'multiple_drop_down_list'], # single list can become multi + ['date', 'datetime'], # date <=> datetime + ['datetime', 'date'] # may lose some data, but who cares ? + true + else + false + end + end end private diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 4ec2d0798..bc8ef1213 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -241,7 +241,10 @@ describe Champ do let(:value) { :noop } let(:champ_yes_no) { Champs::YesNoChamp.new(value: 'true') } let(:champ_text) { Champs::TextChamp.new(value: 'hello') } - + before do + allow(champ_yes_no).to receive(:type_de_champ).and_return(build(:type_de_champ_yes_no)) + allow(champ_text).to receive(:type_de_champ).and_return(build(:type_de_champ_text)) + end it { expect(TypeDeChamp.champ_value_for_export('text', champ_yes_no)).to eq(nil) } it { expect(TypeDeChamp.champ_value_for_export('yes_no', champ_text)).to eq('Non') } end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index a61fd0f66..7564568cf 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -1996,18 +1996,17 @@ describe Dossier, type: :model do describe "champs_for_export" do context 'with integer_number' do - let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :integer_number, libelle: 'c1' }]) } + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :integer_number, libelle: 'c1' }]) } let(:dossier) { create(:dossier, :with_populated_champs, procedure:) } let(:integer_number_type_de_champ) { procedure.active_revision.types_de_champ_public.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:integer_number) } } it 'give me back my decimal number' do - procedure.publish! dossier - integer_number_type_de_champ.update(type_champ: :decimal_number) - procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision) - dossier.reload - - expect(dossier.champs_for_export(procedure.types_de_champ_for_procedure_presentation.not_repetition.to_a)).to eq([['c1', 42]]) + expect { + integer_number_type_de_champ.update(type_champ: :decimal_number) + procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision) + }.to change { dossier.reload.champs_for_export(procedure.types_de_champ_for_procedure_presentation.not_repetition.to_a) } + .from([["c1", 42]]).to([["c1", 42.0]]) end end context 'with a unconditionnal procedure' do