diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index d3360a82eb4..22af0d8ad11 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -28,7 +28,10 @@ def destroy end @attachment.purge_later - @champ.piece_justificative_file.reload if champ? + if champ? + @champ.piece_justificative_file.reload + @champ.touch_changed + end flash.notice = 'La pièce jointe a bien été supprimée.' diff --git a/app/controllers/champs/carte_controller.rb b/app/controllers/champs/carte_controller.rb index 33a4aeb6ff6..47eeffa50d6 100644 --- a/app/controllers/champs/carte_controller.rb +++ b/app/controllers/champs/carte_controller.rb @@ -14,6 +14,7 @@ def create geo_area = @champ.geo_areas.build(source: params_source, properties: {}) if save_feature(geo_area, create_params_feature) + @champ.touch_changed FetchCadastreRealGeometryJob.perform_later(geo_area) if geo_area.cadastre? render json: { feature: geo_area.to_feature }, status: :created else @@ -28,6 +29,7 @@ def update geo_area = @champ.geo_areas.find(params[:id]) if save_feature(geo_area, update_params_feature) + @champ.touch_changed FetchCadastreRealGeometryJob.perform_later(geo_area) if geo_area.cadastre? head :no_content else @@ -37,7 +39,7 @@ def update def destroy @champ.geo_areas.find(params[:id]).destroy! - propagate_touch_champs_changed + @champ.touch_changed head :no_content end @@ -81,9 +83,6 @@ def save_feature(geo_area, feature) if feature[:properties] geo_area.properties.merge!(feature[:properties]) end - if geo_area.save - propagate_touch_champs_changed - true - end + geo_area.save end end diff --git a/app/controllers/champs/champ_controller.rb b/app/controllers/champs/champ_controller.rb index b334bd4fc9b..ded73040c1a 100644 --- a/app/controllers/champs/champ_controller.rb +++ b/app/controllers/champs/champ_controller.rb @@ -24,9 +24,4 @@ def params_row_id def set_champ @champ = find_champ end - - def propagate_touch_champs_changed - @champ.touch - @champ.dossier.touch_champs_changed([:last_champ_updated_at]) - end end diff --git a/app/controllers/champs/piece_justificative_controller.rb b/app/controllers/champs/piece_justificative_controller.rb index ed6eeda5117..677a8b76796 100644 --- a/app/controllers/champs/piece_justificative_controller.rb +++ b/app/controllers/champs/piece_justificative_controller.rb @@ -32,7 +32,7 @@ def attach_piece_justificative end if save_succeed && dossier.brouillon? - dossier.touch_champs_changed([:last_champ_updated_at, :last_champ_piece_jointe_updated_at]) + @champ.touch_changed end save_succeed diff --git a/app/controllers/champs/repetition_controller.rb b/app/controllers/champs/repetition_controller.rb index f2d3e32ccd2..7cc94310f23 100644 --- a/app/controllers/champs/repetition_controller.rb +++ b/app/controllers/champs/repetition_controller.rb @@ -5,14 +5,14 @@ def add @row_id = @champ.add_row(updated_by: current_user.email) @first_champ_id = @champ.focusable_input_id @row_number = @row_id.nil? ? 0 : @champ.row_ids.find_index(@row_id) + 1 - @champ.dossier.touch_champs_changed([:last_champ_updated_at]) + @champ.touch_changed end def remove @champ.remove_row(params[:row_id], updated_by: current_user.email) @to_remove = "safe-row-selector-#{params[:row_id]}" @to_focus = @champ.focusable_input_id || helpers.dom_id(@champ, :create_repetition) - @champ.dossier.touch_champs_changed([:last_champ_updated_at]) + @champ.touch_changed end private diff --git a/app/controllers/champs/rna_controller.rb b/app/controllers/champs/rna_controller.rb index 78431d67b21..3516057262e 100644 --- a/app/controllers/champs/rna_controller.rb +++ b/app/controllers/champs/rna_controller.rb @@ -8,6 +8,6 @@ def show unless @champ.fetch_association!(rna) @error = @champ.association_fetch_error_key end - @champ.dossier.touch_champs_changed([:last_champ_updated_at]) + @champ.touch_changed end end diff --git a/app/controllers/champs/siret_controller.rb b/app/controllers/champs/siret_controller.rb index 0f18ed691b4..2672d0cb8cd 100644 --- a/app/controllers/champs/siret_controller.rb +++ b/app/controllers/champs/siret_controller.rb @@ -10,6 +10,6 @@ def show else @siret = @champ.etablissement_fetch_error_key end - @champ.dossier.touch_champs_changed([:last_champ_updated_at]) + @champ.touch_changed end end diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 0cf585dcd6c..a35d52c7be6 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -577,7 +577,7 @@ def update_dossier_and_compute_errors if dossier.brouillon? if dossier.save if updated_champs.present? - dossier.touch_champs_changed([:last_champ_updated_at]) + updated_champs.each(&:touch_changed) if updated_champs.any?(&:used_by_routing_rules?) @update_contact_information = true RoutingEngine.compute(dossier) diff --git a/app/models/champ.rb b/app/models/champ.rb index 89366a175ed..5b7cc221327 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -310,6 +310,27 @@ def clone_value_from(champ) save! end + def touch_changed + return unless private? || dossier.brouillon? + + updated_at = Time.zone.now + attributes = { updated_at: } + update_columns(attributes) if persisted? + + if piece_justificative_or_titre_identite? + attributes[:last_champ_piece_jointe_updated_at] = updated_at + end + + if private? + attributes[:last_champ_private_updated_at] = updated_at + else + attributes[:last_champ_updated_at] = updated_at + attributes[:brouillon_close_to_expiration_notice_sent_at] = nil + end + + dossier.update_columns(attributes) if attributes.present? + end + class NotImplemented < ::StandardError def initialize(method) super(":#{method} not implemented") diff --git a/app/models/concerns/dossier_champs_concern.rb b/app/models/concerns/dossier_champs_concern.rb index 03237334dc8..ab319088ec4 100644 --- a/app/models/concerns/dossier_champs_concern.rb +++ b/app/models/concerns/dossier_champs_concern.rb @@ -192,15 +192,12 @@ def merge_user_buffer_stream! now = Time.zone.now history_stream = "#{Champ::HISTORY_STREAM}#{now}" + changed_champs = champs.filter { _1.id.in?(buffer_champ_ids) } + transaction do champs.where(id: main_champ_ids, stream: Champ::MAIN_STREAM).update_all(stream: history_stream) champs.where(id: buffer_champ_ids, stream: Champ::USER_BUFFER_STREAM).update_all(stream: Champ::MAIN_STREAM, updated_at: now) - - if Champ.exists?(id: buffer_champ_ids, type: ['Champs::PieceJustificativeChamp', 'Champs::TitreIdentiteChamp']) - touch_champs_changed([:last_champ_updated_at, :last_champ_piece_jointe_updated_at]) - else - touch_champs_changed([:last_champ_updated_at]) - end + touch_champs_changed(changed_champs) end # update loaded champ instances diff --git a/app/models/concerns/dossier_clone_concern.rb b/app/models/concerns/dossier_clone_concern.rb index 5610c289b6f..2f420de3a15 100644 --- a/app/models/concerns/dossier_clone_concern.rb +++ b/app/models/concerns/dossier_clone_concern.rb @@ -74,10 +74,8 @@ def merge_fork(editing_fork) diff = make_diff(editing_fork) apply_diff(diff) - attributes_to_touch = [:last_champ_updated_at] - attributes_to_touch << :last_champ_piece_jointe_updated_at if diff[:updated].any? { |c| c.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp]) } - - touch_champs_changed(attributes_to_touch) + changed_champs = diff.values.flatten + touch_champs_changed(changed_champs) end reload index_search_terms_later diff --git a/app/models/dossier.rb b/app/models/dossier.rb index ee4bf60a47a..d624f7cc852 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -1024,11 +1024,14 @@ def termine_and_accuse_lecture? procedure.accuse_lecture? && termine? end - def touch_champs_changed(attributes) - now = Time.zone.now - update_columns(attributes.each_with_object({ brouillon_close_to_expiration_notice_sent_at: nil, updated_at: now }) do |attribute, hash| - hash[attribute] = now - end) + def touch_champs_changed(changed_champs) + return if changed_champs.empty? + updated_at = Time.zone.now + attributes = { updated_at:, last_champ_updated_at: updated_at } + if changed_champs.any?(&:piece_justificative_or_titre_identite?) + attributes[:last_champ_piece_jointe_updated_at] = updated_at + end + update_columns(attributes) end private diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index bafe0412746..f1767c4b4a4 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -2427,21 +2427,29 @@ end describe '#touch_champs_changed' do - let(:dossier) { create(:dossier, brouillon_close_to_expiration_notice_sent_at: 10.days.ago) } + let(:procedure) { create(:procedure, types_de_champ_public: [{}, { type: :piece_justificative }, { type: :titre_identite }]) } + let(:dossier) { create(:dossier, procedure:, brouillon_close_to_expiration_notice_sent_at: 10.days.ago) } + let(:changed_champs) { dossier.champs.filter(&:text?) } - subject { -> { dossier.touch_champs_changed(attributes) } } - - let(:attributes) { [:last_champ_updated_at] } + subject { -> { dossier.touch_champs_changed(changed_champs) } } it { is_expected.to change(dossier, :last_champ_updated_at) } + it { is_expected.to change(dossier, :updated_at) } + + context 'when there is piece justificative' do + let(:changed_champs) { dossier.champs.filter(&:piece_justificative?) } - it { is_expected.to change(dossier, :brouillon_close_to_expiration_notice_sent_at).to(nil) } + it { is_expected.to change(dossier, :last_champ_updated_at) } + it { is_expected.to change(dossier, :last_champ_piece_jointe_updated_at) } + it { is_expected.to change(dossier, :updated_at) } + end - context 'when there is two attributes' do - let(:attributes) { [:last_champ_updated_at, :last_champ_piece_jointe_updated_at] } + context 'when there is titre identite' do + let(:changed_champs) { dossier.champs.filter(&:titre_identite?) } it { is_expected.to change(dossier, :last_champ_updated_at) } it { is_expected.to change(dossier, :last_champ_piece_jointe_updated_at) } + it { is_expected.to change(dossier, :updated_at) } end end