From 718a30639ffae4ea04ab23dc2c2449e1da96096e Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Fri, 23 Nov 2018 11:04:28 +0100 Subject: [PATCH 01/13] [Fix #2929] Improve readability of invitation for avis --- app/mailers/avis_mailer.rb | 2 ++ app/views/avis_mailer/avis_invitation.html.haml | 13 +++++++++---- spec/mailers/avis_mailer_spec.rb | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/mailers/avis_mailer.rb b/app/mailers/avis_mailer.rb index b4ca982c1..78c7ac5a8 100644 --- a/app/mailers/avis_mailer.rb +++ b/app/mailers/avis_mailer.rb @@ -1,5 +1,7 @@ # Preview all emails at http://localhost:3000/rails/mailers/avis_mailer class AvisMailer < ApplicationMailer + layout 'mailers/layout' + def avis_invitation(avis) @avis = avis email = @avis.gestionnaire&.email || @avis.email diff --git a/app/views/avis_mailer/avis_invitation.html.haml b/app/views/avis_mailer/avis_invitation.html.haml index c5ba3e20b..e339c9a88 100644 --- a/app/views/avis_mailer/avis_invitation.html.haml +++ b/app/views/avis_mailer/avis_invitation.html.haml @@ -1,16 +1,21 @@ +- content_for(:title, 'Vous avez été invité à donner votre avis') + - avis_link = @avis.gestionnaire.present? ? gestionnaire_avis_url(@avis) : sign_up_gestionnaire_avis_url(@avis.id, @avis.email) %p Bonjour, %p - = "Vous avez été invité par #{@avis.claimant.email} à donner votre avis sur le dossier nº #{@avis.dossier.id} de la démarche \"#{@avis.dossier.procedure.libelle}\"." + Vous avez été invité par + %strong= @avis.claimant.email + = "à donner votre avis sur le dossier nº #{@avis.dossier.id} de la démarche :" + %strong= @avis.dossier.procedure.libelle %p - Message de votre interlocuteur : + = "#{@avis.claimant.email} vous a écrit :" %br - %span{ style: 'font-style: italic;' } - = @avis.introduction +%p{ style: "padding: 8px; color: #333333; background-color: #EEEEEE; font-size: 16px;" } + = @avis.introduction - if @avis.gestionnaire.present? %p diff --git a/spec/mailers/avis_mailer_spec.rb b/spec/mailers/avis_mailer_spec.rb index 9b3b07e6e..70f826b13 100644 --- a/spec/mailers/avis_mailer_spec.rb +++ b/spec/mailers/avis_mailer_spec.rb @@ -7,7 +7,7 @@ RSpec.describe AvisMailer, type: :mailer do subject { described_class.avis_invitation(avis) } it { expect(subject.subject).to eq("Donnez votre avis sur le dossier nº #{avis.dossier.id} (#{avis.dossier.procedure.libelle})") } - it { expect(subject.body).to include("Vous avez été invité par #{avis.claimant.email} à donner votre avis sur le dossier nº #{avis.dossier.id} de la démarche "#{avis.dossier.procedure.libelle}".") } + it { expect(subject.body).to have_text("Vous avez été invité par #{avis.claimant.email} à donner votre avis sur le dossier nº #{avis.dossier.id} de la démarche : #{avis.dossier.procedure.libelle}") } it { expect(subject.body).to include(avis.introduction) } it { expect(subject.body).to include(gestionnaire_avis_url(avis)) } From af47ccda9440e5aaa16a9fa36d0a788dc30efe3e Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 26 Nov 2018 12:09:35 +0100 Subject: [PATCH 02/13] deploy: require mina only for deployment tasks This fixes mina activating Rake traces, which pollutes the output of rake tasks. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 42647402b..59eaecbb2 100644 --- a/Gemfile +++ b/Gemfile @@ -175,7 +175,7 @@ group :development, :test do gem 'rspec-rails' # Deploy - gem 'mina', git: 'https://github.com/mina-deploy/mina.git' + gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false gem 'rspec_junit_formatter' end From f2e7feec1d54af9f91672e3ed98fead55901f363 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 27 Nov 2018 11:31:03 +0100 Subject: [PATCH 03/13] =?UTF-8?q?Do=20not=20send=20error=20json=20to=20bac?= =?UTF-8?q?kend=20-=20it=20doesn=E2=80=99t=20need=20it=20and=20it=20create?= =?UTF-8?q?s=20bad=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/champs/carte_controller.rb | 2 +- app/javascript/shared/carte.js | 2 +- spec/controllers/champs/carte_controller_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/champs/carte_controller.rb b/app/controllers/champs/carte_controller.rb index 857970ac2..9746896a5 100644 --- a/app/controllers/champs/carte_controller.rb +++ b/app/controllers/champs/carte_controller.rb @@ -28,7 +28,7 @@ class Champs::CarteController < ApplicationController geo_areas = [] geo_json = geo_json.blank? ? [] : JSON.parse(geo_json) - if geo_json.first == ["error", "TooManyPolygons"] + if geo_json.empty? @error = true @champ.value = nil @champ.geo_areas = [] diff --git a/app/javascript/shared/carte.js b/app/javascript/shared/carte.js index 5a86af744..1c7d7655e 100644 --- a/app/javascript/shared/carte.js +++ b/app/javascript/shared/carte.js @@ -115,7 +115,7 @@ export function addFreeDrawEvents(map, selector) { } else if (polygonArea(latLngs) < 300000) { input.value = JSON.stringify(latLngs); } else { - input.value = '{ "error": "TooManyPolygons" }'; + input.value = ''; } fire(input, 'change'); diff --git a/spec/controllers/champs/carte_controller_spec.rb b/spec/controllers/champs/carte_controller_spec.rb index 267f6d3b2..9bd6c7627 100644 --- a/spec/controllers/champs/carte_controller_spec.rb +++ b/spec/controllers/champs/carte_controller_spec.rb @@ -50,7 +50,7 @@ describe Champs::CarteController, type: :controller do context 'when error' do let(:geojson) { [[{ "lat": 48.87442541960633, "lng": 2.3859214782714844 }, { "lat": 48.87273183590832, "lng": 2.3850631713867183 }, { "lat": 48.87081237174292, "lng": 2.3809432983398438 }, { "lat": 48.8712640169951, "lng": 2.377510070800781 }, { "lat": 48.87510283703279, "lng": 2.3778533935546875 }, { "lat": 48.87544154230615, "lng": 2.382831573486328 }, { "lat": 48.87442541960633, "lng": 2.3859214782714844 }]] } - let(:selection) { { error: "TooManyPolygons" } } + let(:selection) { '' } it { expect(champ.reload.value).to eq(nil) From febf625dd9bac1914b833f2830c8f85a81aca04a Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 27 Nov 2018 12:15:36 +0100 Subject: [PATCH 04/13] Make difference between error and empty geo json --- app/controllers/champs/carte_controller.rb | 13 ++++++++++--- app/javascript/shared/carte.js | 7 +++++-- spec/controllers/champs/carte_controller_spec.rb | 16 +++++++++++----- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/app/controllers/champs/carte_controller.rb b/app/controllers/champs/carte_controller.rb index 9746896a5..3609272fd 100644 --- a/app/controllers/champs/carte_controller.rb +++ b/app/controllers/champs/carte_controller.rb @@ -1,6 +1,9 @@ class Champs::CarteController < ApplicationController before_action :authenticate_logged_user! + EMPTY_GEO_JSON = '[]' + ERROR_GEO_JSON = '' + def show @selector = ".carte-#{params[:position]}" @@ -26,13 +29,17 @@ class Champs::CarteController < ApplicationController end geo_areas = [] - geo_json = geo_json.blank? ? [] : JSON.parse(geo_json) - if geo_json.empty? + if geo_json == EMPTY_GEO_JSON + @champ.value = nil + @champ.geo_areas = [] + elsif geo_json == ERROR_GEO_JSON @error = true @champ.value = nil @champ.geo_areas = [] - elsif geo_json.present? + else + geo_json = JSON.parse(geo_json) + if @champ.cadastres? cadastres = ModuleApiCartoService.generate_cadastre(geo_json) geo_areas += cadastres.map do |cadastre| diff --git a/app/javascript/shared/carte.js b/app/javascript/shared/carte.js index 1c7d7655e..a9360e829 100644 --- a/app/javascript/shared/carte.js +++ b/app/javascript/shared/carte.js @@ -107,15 +107,18 @@ export function getCurrentMap(input) { } } +const EMPTY_GEO_JSON = '[]'; +const ERROR_GEO_JSON = ''; + export function addFreeDrawEvents(map, selector) { const input = findInput(selector); map.freeDraw.on('markers', ({ latLngs }) => { if (latLngs.length === 0) { - input.value = ''; + input.value = EMPTY_GEO_JSON; } else if (polygonArea(latLngs) < 300000) { input.value = JSON.stringify(latLngs); } else { - input.value = ''; + input.value = ERROR_GEO_JSON; } fire(input, 'change'); diff --git a/spec/controllers/champs/carte_controller_spec.rb b/spec/controllers/champs/carte_controller_spec.rb index 9bd6c7627..6fbbd88e6 100644 --- a/spec/controllers/champs/carte_controller_spec.rb +++ b/spec/controllers/champs/carte_controller_spec.rb @@ -8,7 +8,7 @@ describe Champs::CarteController, type: :controller do { dossier: { champs_attributes: { - '1' => { value: selection.to_json } + '1' => { value: value } } }, position: '1', @@ -35,13 +35,18 @@ describe Champs::CarteController, type: :controller do end context 'when coordinates are empty' do - let(:selection) { [] } + let(:value) { '[]' } - it { expect(response.body).to include("DS.drawMapData(\".carte-1\", {\"position\":{\"lon\":\"2.428462\",\"lat\":\"46.538192\",\"zoom\":\"13\"},\"selection\":[],\"quartiersPrioritaires\":[],\"cadastres\":[],\"parcellesAgricoles\":[]});") } + it { + expect(assigns(:error)).to eq(nil) + expect(champ.reload.value).to eq(nil) + expect(champ.reload.geo_areas).to eq([]) + expect(response.body).to include("DS.drawMapData(\".carte-1\", {\"position\":{\"lon\":\"2.428462\",\"lat\":\"46.538192\",\"zoom\":\"13\"},\"selection\":[],\"quartiersPrioritaires\":[],\"cadastres\":[],\"parcellesAgricoles\":[]});") + } end context 'when coordinates are informed' do - let(:selection) { [[{ "lat": 48.87442541960633, "lng": 2.3859214782714844 }, { "lat": 48.87273183590832, "lng": 2.3850631713867183 }, { "lat": 48.87081237174292, "lng": 2.3809432983398438 }, { "lat": 48.8712640169951, "lng": 2.377510070800781 }, { "lat": 48.87510283703279, "lng": 2.3778533935546875 }, { "lat": 48.87544154230615, "lng": 2.382831573486328 }, { "lat": 48.87442541960633, "lng": 2.3859214782714844 }]] } + let(:value) { [[{ "lat": 48.87442541960633, "lng": 2.3859214782714844 }, { "lat": 48.87273183590832, "lng": 2.3850631713867183 }, { "lat": 48.87081237174292, "lng": 2.3809432983398438 }, { "lat": 48.8712640169951, "lng": 2.377510070800781 }, { "lat": 48.87510283703279, "lng": 2.3778533935546875 }, { "lat": 48.87544154230615, "lng": 2.382831573486328 }, { "lat": 48.87442541960633, "lng": 2.3859214782714844 }]].to_json } it { expect(response.body).not_to be_nil } it { expect(response.body).to include('MultiPolygon') } @@ -50,9 +55,10 @@ describe Champs::CarteController, type: :controller do context 'when error' do let(:geojson) { [[{ "lat": 48.87442541960633, "lng": 2.3859214782714844 }, { "lat": 48.87273183590832, "lng": 2.3850631713867183 }, { "lat": 48.87081237174292, "lng": 2.3809432983398438 }, { "lat": 48.8712640169951, "lng": 2.377510070800781 }, { "lat": 48.87510283703279, "lng": 2.3778533935546875 }, { "lat": 48.87544154230615, "lng": 2.382831573486328 }, { "lat": 48.87442541960633, "lng": 2.3859214782714844 }]] } - let(:selection) { '' } + let(:value) { '' } it { + expect(assigns(:error)).to eq(true) expect(champ.reload.value).to eq(nil) expect(champ.reload.geo_areas).to eq([]) } From 9843666bdcd15e2054b176e68501125cf20749d6 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 26 Nov 2018 19:12:56 +0100 Subject: [PATCH 05/13] Implement state change methods on dossier --- app/models/dossier.rb | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 22f3cfe4c..403a034b2 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -306,6 +306,47 @@ class Dossier < ApplicationRecord DossierMailer.notify_deletion_to_user(deleted_dossier, user.email).deliver_later end + def passer_en_instruction!(gestionnaire) + en_instruction! + gestionnaire.follow(self) + end + + def repasser_en_construction! + self.en_instruction_at = nil + en_construction! + end + + def accepter!(motivation) + self.motivation = motivation + self.en_instruction_at ||= Time.zone.now + + accepte! + + if attestation.nil? + update(attestation: build_attestation) + end + + NotificationMailer.send_closed_notification(self).deliver_later + end + + def refuser!(motivation) + self.motivation = motivation + self.en_instruction_at ||= Time.zone.now + + refuse! + + NotificationMailer.send_refused_notification(self).deliver_later + end + + def classer_sans_suite!(motivation) + self.motivation = motivation + self.en_instruction_at ||= Time.zone.now + + sans_suite! + + NotificationMailer.send_without_continuation_notification(self).deliver_later + end + private def update_state_dates From 15b1499e5d4d6e243ca95bd6422afd218c1ee4a3 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 26 Nov 2018 21:24:18 +0100 Subject: [PATCH 06/13] Use state change methods on dossier in dossier controller --- .../new_gestionnaire/dossiers_controller.rb | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/app/controllers/new_gestionnaire/dossiers_controller.rb b/app/controllers/new_gestionnaire/dossiers_controller.rb index 47aafc301..0bd738fb3 100644 --- a/app/controllers/new_gestionnaire/dossiers_controller.rb +++ b/app/controllers/new_gestionnaire/dossiers_controller.rb @@ -74,44 +74,32 @@ module NewGestionnaire end def passer_en_instruction - dossier.en_instruction! - current_gestionnaire.follow(dossier) + dossier.passer_en_instruction!(current_gestionnaire) flash.notice = 'Dossier passé en instruction.' render partial: 'state_button_refresh', locals: { dossier: dossier } end def repasser_en_construction - dossier.en_construction! + dossier.repasser_en_construction! flash.notice = 'Dossier repassé en construction.' render partial: 'state_button_refresh', locals: { dossier: dossier } end def terminer - if params[:dossier] && params[:dossier][:motivation].present? - dossier.motivation = params[:dossier][:motivation] - end + motivation = params[:dossier] && params[:dossier][:motivation] case params[:process_action] when "refuser" - dossier.refuse! - dossier.save + dossier.refuser!(motivation) flash.notice = "Dossier considéré comme refusé." - NotificationMailer.send_refused_notification(dossier).deliver_later when "classer_sans_suite" - dossier.sans_suite! - dossier.save + dossier.classer_sans_suite!(motivation) flash.notice = "Dossier considéré comme sans suite." - NotificationMailer.send_without_continuation_notification(dossier).deliver_later when "accepter" - dossier.accepte! - if dossier.attestation.nil? - dossier.attestation = dossier.build_attestation - dossier.save - end + dossier.accepter!(motivation) flash.notice = "Dossier traité avec succès." - NotificationMailer.send_closed_notification(dossier).deliver_later end render partial: 'state_button_refresh', locals: { dossier: dossier } From a079eaea5c32eff5d62444100086fc0284f357ff Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 27 Nov 2018 11:13:55 +0100 Subject: [PATCH 07/13] Add procedure gestionnaire_for_cron_job method --- app/models/procedure.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 2ad171a4c..2021d69b2 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -358,6 +358,12 @@ class Procedure < ApplicationRecord where.not(aasm_state: :archivee).where("path LIKE ?", "%#{path}%") end + def gestionnaire_for_cron_job + administrateur_email = administrateur.email + gestionnaire = Gestionnaire.find_by(email: administrateur_email) + gestionnaire || gestionnaires.first + end + private def claim_path_ownership!(path) From b5b6832be866170e23e70a38248f1ab6a4b65ed4 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 26 Nov 2018 21:25:50 +0100 Subject: [PATCH 08/13] Use state change methods on dossier in dossier auto recieve job --- ...auto_receive_dossiers_for_procedure_job.rb | 20 ++---- spec/factories/procedure.rb | 6 ++ ...receive_dossiers_for_procedure_job_spec.rb | 69 +++++++++++-------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/app/jobs/auto_receive_dossiers_for_procedure_job.rb b/app/jobs/auto_receive_dossiers_for_procedure_job.rb index ce44c4d46..6e5ee24da 100644 --- a/app/jobs/auto_receive_dossiers_for_procedure_job.rb +++ b/app/jobs/auto_receive_dossiers_for_procedure_job.rb @@ -1,24 +1,18 @@ class AutoReceiveDossiersForProcedureJob < ApplicationJob queue_as :cron - def perform(procedure_id, state) + def perform(procedure_id, state, gestionnaire_id = nil) procedure = Procedure.find(procedure_id) + gestionnaire = procedure.gestionnaire_for_cron_job + case state when Dossier.states.fetch(:en_instruction) - procedure.dossiers.state_en_construction.update_all( - state: Dossier.states.fetch(:en_instruction), - en_instruction_at: Time.zone.now - ) + procedure.dossiers.state_en_construction.find_each do |dossier| + dossier.passer_en_instruction!(gestionnaire) + end when Dossier.states.fetch(:accepte) procedure.dossiers.state_en_construction.find_each do |dossier| - dossier.update( - state: Dossier.states.fetch(:accepte), - en_instruction_at: Time.zone.now, - processed_at: Time.zone.now - ) - dossier.attestation = dossier.build_attestation - dossier.save - NotificationMailer.send_closed_notification(dossier).deliver_later + dossier.accepter!('') end else raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\"" diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index c22488dcc..7206a4504 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -46,6 +46,12 @@ FactoryBot.define do end end + trait :with_gestionnaire do + after(:build) do |procedure, _evaluator| + procedure.gestionnaires << create(:gestionnaire) + end + end + trait :with_api_carto do after(:build) do |procedure, _evaluator| procedure.module_api_carto.use_api_carto = true diff --git a/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb b/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb index fa22ab6b5..ae4e06676 100644 --- a/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb +++ b/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb @@ -5,57 +5,66 @@ RSpec.describe AutoReceiveDossiersForProcedureJob, type: :job do let(:date) { Time.utc(2017, 9, 1, 10, 5, 0) } let(:instruction_date) { date + 120 } + let(:procedure) { create(:procedure, :with_gestionnaire) } + let(:nouveau_dossier1) { create(:dossier, :en_construction, procedure: procedure) } + let(:nouveau_dossier2) { create(:dossier, :en_construction, procedure: procedure) } + let(:dossier_recu) { create(:dossier, :en_instruction, procedure: procedure) } + let(:dossier_brouillon) { create(:dossier, procedure: procedure) } + before do Timecop.freeze(date) - create(:attestation_template, procedure: nouveau_dossier1.procedure) - AutoReceiveDossiersForProcedureJob.new.perform(procedure_id, state) + nouveau_dossier1 + nouveau_dossier2 + dossier_recu + dossier_brouillon + + create(:attestation_template, procedure: procedure) + AutoReceiveDossiersForProcedureJob.new.perform(procedure.id, state) end after { Timecop.return } context "with some dossiers" do - let(:nouveau_dossier1) { create(:dossier, :en_construction) } - let(:nouveau_dossier2) { create(:dossier, :en_construction, procedure: nouveau_dossier1.procedure) } - let(:dossier_recu) { create(:dossier, :en_instruction, procedure: nouveau_dossier2.procedure) } - let(:dossier_brouillon) { create(:dossier, procedure: dossier_recu.procedure) } - let(:procedure_id) { dossier_brouillon.procedure_id } - context "en_construction" do let(:state) { Dossier.states.fetch(:en_instruction) } - it { expect(nouveau_dossier1.reload.en_instruction?).to be true } - it { expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) } + it { + expect(nouveau_dossier1.reload.en_instruction?).to be true + expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) - it { expect(nouveau_dossier2.reload.en_instruction?).to be true } - it { expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) } + expect(nouveau_dossier2.reload.en_instruction?).to be true + expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) - it { expect(dossier_recu.reload.en_instruction?).to be true } - it { expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) } + expect(dossier_recu.reload.en_instruction?).to be true + expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) - it { expect(dossier_brouillon.reload.brouillon?).to be true } - it { expect(dossier_brouillon.reload.en_instruction_at).to eq(nil) } + expect(dossier_brouillon.reload.brouillon?).to be true + expect(dossier_brouillon.reload.en_instruction_at).to eq(nil) + } end context "accepte" do let(:state) { Dossier.states.fetch(:accepte) } - it { expect(nouveau_dossier1.reload.accepte?).to be true } - it { expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) } - it { expect(nouveau_dossier1.reload.processed_at).to eq(date) } - it { expect(nouveau_dossier1.reload.attestation).to be_present } + it { + expect(nouveau_dossier1.reload.accepte?).to be true + expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) + expect(nouveau_dossier1.reload.processed_at).to eq(date) + expect(nouveau_dossier1.reload.attestation).to be_present - it { expect(nouveau_dossier2.reload.accepte?).to be true } - it { expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) } - it { expect(nouveau_dossier2.reload.processed_at).to eq(date) } - it { expect(nouveau_dossier2.reload.attestation).to be_present } + expect(nouveau_dossier2.reload.accepte?).to be true + expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) + expect(nouveau_dossier2.reload.processed_at).to eq(date) + expect(nouveau_dossier2.reload.attestation).to be_present - it { expect(dossier_recu.reload.en_instruction?).to be true } - it { expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) } - it { expect(dossier_recu.reload.processed_at).to eq(nil) } + expect(dossier_recu.reload.en_instruction?).to be true + expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) + expect(dossier_recu.reload.processed_at).to eq(nil) - it { expect(dossier_brouillon.reload.brouillon?).to be true } - it { expect(dossier_brouillon.reload.en_instruction_at).to eq(nil) } - it { expect(dossier_brouillon.reload.processed_at).to eq(nil) } + expect(dossier_brouillon.reload.brouillon?).to be true + expect(dossier_brouillon.reload.en_instruction_at).to eq(nil) + expect(dossier_brouillon.reload.processed_at).to eq(nil) + } end end end From 98d388b64d55e078505164799e0d7f507304e669 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 27 Nov 2018 11:13:37 +0100 Subject: [PATCH 09/13] Use state change methods on dossier in dossier auto archive job --- app/jobs/auto_archive_procedure_job.rb | 6 +++- spec/jobs/auto_archive_procedure_job_spec.rb | 34 +++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/app/jobs/auto_archive_procedure_job.rb b/app/jobs/auto_archive_procedure_job.rb index 0821ba5ed..7791dbc13 100644 --- a/app/jobs/auto_archive_procedure_job.rb +++ b/app/jobs/auto_archive_procedure_job.rb @@ -3,7 +3,11 @@ class AutoArchiveProcedureJob < ApplicationJob def perform(*args) Procedure.publiees.where("auto_archive_on <= ?", Date.today).each do |procedure| - procedure.dossiers.state_en_construction.each(&:en_instruction!) + gestionnaire = procedure.gestionnaire_for_cron_job + + procedure.dossiers.state_en_construction.find_each do |dossier| + dossier.passer_en_instruction!(gestionnaire) + end procedure.archive! end diff --git a/spec/jobs/auto_archive_procedure_job_spec.rb b/spec/jobs/auto_archive_procedure_job_spec.rb index d671ad212..3d3b58b05 100644 --- a/spec/jobs/auto_archive_procedure_job_spec.rb +++ b/spec/jobs/auto_archive_procedure_job_spec.rb @@ -1,10 +1,10 @@ require 'rails_helper' RSpec.describe AutoArchiveProcedureJob, type: :job do - let!(:procedure) { create(:procedure, :published, auto_archive_on: nil) } - let!(:procedure_hier) { create(:procedure, :published, auto_archive_on: 1.day.ago) } - let!(:procedure_aujourdhui) { create(:procedure, :published, auto_archive_on: Date.today) } - let!(:procedure_demain) { create(:procedure, :published, auto_archive_on: 1.day.from_now) } + let!(:procedure) { create(:procedure, :published, :with_gestionnaire, auto_archive_on: nil) } + let!(:procedure_hier) { create(:procedure, :published, :with_gestionnaire, auto_archive_on: 1.day.ago) } + let!(:procedure_aujourdhui) { create(:procedure, :published, :with_gestionnaire, auto_archive_on: Date.today) } + let!(:procedure_demain) { create(:procedure, :published, :with_gestionnaire, auto_archive_on: 1.day.from_now) } subject { AutoArchiveProcedureJob.new.perform } @@ -37,18 +37,22 @@ RSpec.describe AutoArchiveProcedureJob, type: :job do procedure_aujourdhui.reload end - it { expect(dossier1.state).to eq Dossier.states.fetch(:brouillon) } - it { expect(dossier2.state).to eq Dossier.states.fetch(:en_instruction) } - it { expect(dossier3.state).to eq Dossier.states.fetch(:en_instruction) } - it { expect(dossier4.state).to eq Dossier.states.fetch(:en_instruction) } - it { expect(dossier5.state).to eq Dossier.states.fetch(:en_instruction) } - it { expect(dossier6.state).to eq Dossier.states.fetch(:accepte) } - it { expect(dossier7.state).to eq Dossier.states.fetch(:refuse) } - it { expect(dossier8.state).to eq Dossier.states.fetch(:sans_suite) } - it { expect(dossier9.state).to eq Dossier.states.fetch(:en_instruction) } + it { + expect(dossier1.state).to eq Dossier.states.fetch(:brouillon) + expect(dossier2.state).to eq Dossier.states.fetch(:en_instruction) + expect(dossier3.state).to eq Dossier.states.fetch(:en_instruction) + expect(dossier4.state).to eq Dossier.states.fetch(:en_instruction) + expect(dossier5.state).to eq Dossier.states.fetch(:en_instruction) + expect(dossier6.state).to eq Dossier.states.fetch(:accepte) + expect(dossier7.state).to eq Dossier.states.fetch(:refuse) + expect(dossier8.state).to eq Dossier.states.fetch(:sans_suite) + expect(dossier9.state).to eq Dossier.states.fetch(:en_instruction) + } - it { expect(procedure_hier.archivee?).to eq true } - it { expect(procedure_aujourdhui.archivee?).to eq true } + it { + expect(procedure_hier.archivee?).to eq true + expect(procedure_aujourdhui.archivee?).to eq true + } end context "when procedures have auto_archive_on set on future" do From 85e3eb04f482bcdd8dd85886fa2af1efe06dcd78 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Fri, 23 Nov 2018 21:02:18 +0100 Subject: [PATCH 10/13] Add DossierOperationLog model --- app/models/dossier.rb | 2 ++ app/models/dossier_operation_log.rb | 12 ++++++++++++ ...20181123195208_create_dossier_operation_logs.rb | 11 +++++++++++ db/schema.rb | 14 +++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 app/models/dossier_operation_log.rb create mode 100644 db/migrate/20181123195208_create_dossier_operation_logs.rb diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 403a034b2..d1b7b2f3c 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -28,6 +28,8 @@ class Dossier < ApplicationRecord has_many :followers_gestionnaires, through: :follows, source: :gestionnaire has_many :avis, dependent: :destroy + has_many :dossier_operation_logs + belongs_to :procedure belongs_to :user diff --git a/app/models/dossier_operation_log.rb b/app/models/dossier_operation_log.rb new file mode 100644 index 000000000..fd4e770a4 --- /dev/null +++ b/app/models/dossier_operation_log.rb @@ -0,0 +1,12 @@ +class DossierOperationLog < ApplicationRecord + enum operation: { + passer_en_instruction: 'passer_en_instruction', + repasser_en_construction: 'repasser_en_construction', + accepter: 'accepter', + refuser: 'refuser', + classer_sans_suite: 'classer_sans_suite' + } + + belongs_to :dossier + belongs_to :gestionnaire +end diff --git a/db/migrate/20181123195208_create_dossier_operation_logs.rb b/db/migrate/20181123195208_create_dossier_operation_logs.rb new file mode 100644 index 000000000..7a6003219 --- /dev/null +++ b/db/migrate/20181123195208_create_dossier_operation_logs.rb @@ -0,0 +1,11 @@ +class CreateDossierOperationLogs < ActiveRecord::Migration[5.2] + def change + create_table :dossier_operation_logs do |t| + t.string :operation, null: false + t.references :dossier, foreign_key: true, index: true + t.references :gestionnaire, foreign_key: true, index: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 41ef703c6..b8b98f83e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_11_21_234008) do +ActiveRecord::Schema.define(version: 2018_11_23_195208) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -218,6 +218,16 @@ ActiveRecord::Schema.define(version: 2018_11_21_234008) do t.index ["procedure_id"], name: "index_deleted_dossiers_on_procedure_id" end + create_table "dossier_operation_logs", force: :cascade do |t| + t.string "operation", null: false + t.bigint "dossier_id" + t.bigint "gestionnaire_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["dossier_id"], name: "index_dossier_operation_logs_on_dossier_id" + t.index ["gestionnaire_id"], name: "index_dossier_operation_logs_on_gestionnaire_id" + end + create_table "dossiers", id: :serial, force: :cascade do |t| t.boolean "autorisation_donnees" t.integer "procedure_id" @@ -608,6 +618,8 @@ ActiveRecord::Schema.define(version: 2018_11_21_234008) do add_foreign_key "avis", "gestionnaires", column: "claimant_id" add_foreign_key "closed_mails", "procedures" add_foreign_key "commentaires", "dossiers" + add_foreign_key "dossier_operation_logs", "dossiers" + add_foreign_key "dossier_operation_logs", "gestionnaires" add_foreign_key "dossiers", "users" add_foreign_key "feedbacks", "users" add_foreign_key "geo_areas", "champs" From 0f0ca2ec652310e17577eb827df5418d641f5ba6 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 26 Nov 2018 21:29:06 +0100 Subject: [PATCH 11/13] Lod dossier operations --- .../new_gestionnaire/dossiers_controller.rb | 8 +++---- ...auto_receive_dossiers_for_procedure_job.rb | 2 +- app/models/dossier.rb | 22 +++++++++++++++---- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/app/controllers/new_gestionnaire/dossiers_controller.rb b/app/controllers/new_gestionnaire/dossiers_controller.rb index 0bd738fb3..473d66d08 100644 --- a/app/controllers/new_gestionnaire/dossiers_controller.rb +++ b/app/controllers/new_gestionnaire/dossiers_controller.rb @@ -81,7 +81,7 @@ module NewGestionnaire end def repasser_en_construction - dossier.repasser_en_construction! + dossier.repasser_en_construction!(current_gestionnaire) flash.notice = 'Dossier repassé en construction.' render partial: 'state_button_refresh', locals: { dossier: dossier } @@ -92,13 +92,13 @@ module NewGestionnaire case params[:process_action] when "refuser" - dossier.refuser!(motivation) + dossier.refuser!(current_gestionnaire, motivation) flash.notice = "Dossier considéré comme refusé." when "classer_sans_suite" - dossier.classer_sans_suite!(motivation) + dossier.classer_sans_suite!(current_gestionnaire, motivation) flash.notice = "Dossier considéré comme sans suite." when "accepter" - dossier.accepter!(motivation) + dossier.accepter!(current_gestionnaire, motivation) flash.notice = "Dossier traité avec succès." end diff --git a/app/jobs/auto_receive_dossiers_for_procedure_job.rb b/app/jobs/auto_receive_dossiers_for_procedure_job.rb index 6e5ee24da..6ff7fa117 100644 --- a/app/jobs/auto_receive_dossiers_for_procedure_job.rb +++ b/app/jobs/auto_receive_dossiers_for_procedure_job.rb @@ -12,7 +12,7 @@ class AutoReceiveDossiersForProcedureJob < ApplicationJob end when Dossier.states.fetch(:accepte) procedure.dossiers.state_en_construction.find_each do |dossier| - dossier.accepter!('') + dossier.accepter!(gestionnaire, '') end else raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\"" diff --git a/app/models/dossier.rb b/app/models/dossier.rb index d1b7b2f3c..d5d6273c8 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -311,14 +311,18 @@ class Dossier < ApplicationRecord def passer_en_instruction!(gestionnaire) en_instruction! gestionnaire.follow(self) + + log_dossier_operation(gestionnaire, :passer_en_instruction) end - def repasser_en_construction! + def repasser_en_construction!(gestionnaire) self.en_instruction_at = nil en_construction! + + log_dossier_operation(gestionnaire, :repasser_en_construction) end - def accepter!(motivation) + def accepter!(gestionnaire, motivation) self.motivation = motivation self.en_instruction_at ||= Time.zone.now @@ -329,28 +333,38 @@ class Dossier < ApplicationRecord end NotificationMailer.send_closed_notification(self).deliver_later + log_dossier_operation(gestionnaire, :accepter) end - def refuser!(motivation) + def refuser!(gestionnaire, motivation) self.motivation = motivation self.en_instruction_at ||= Time.zone.now refuse! NotificationMailer.send_refused_notification(self).deliver_later + log_dossier_operation(gestionnaire, :refuser) end - def classer_sans_suite!(motivation) + def classer_sans_suite!(gestionnaire, motivation) self.motivation = motivation self.en_instruction_at ||= Time.zone.now sans_suite! NotificationMailer.send_without_continuation_notification(self).deliver_later + log_dossier_operation(gestionnaire, :classer_sans_suite) end private + def log_dossier_operation(gestionnaire, operation) + dossier_operation_logs.create( + gestionnaire: gestionnaire, + operation: DossierOperationLog.operations.fetch(operation) + ) + end + def update_state_dates if en_construction? && !self.en_construction_at self.en_construction_at = Time.zone.now From 91115ea8479a66cafd493635e597ca0d1a592c9e Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Tue, 27 Nov 2018 14:02:29 +0100 Subject: [PATCH 12/13] [Fix sentry-26] if file does not exist, filename should be nil --- app/uploaders/procedure_logo_uploader.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/uploaders/procedure_logo_uploader.rb b/app/uploaders/procedure_logo_uploader.rb index 29e499c9d..c38970ac0 100644 --- a/app/uploaders/procedure_logo_uploader.rb +++ b/app/uploaders/procedure_logo_uploader.rb @@ -25,14 +25,16 @@ class ProcedureLogoUploader < BaseUploader end def filename - if original_filename.present? || model.logo_secure_token - if Flipflop.remote_storage? - filename = "#{model.class.to_s.underscore}-#{secure_token}.#{file.extension.downcase}" - else - filename = "logo-#{secure_token}.#{file.extension.downcase}" + if file.present? + if original_filename.present? || model.logo_secure_token + if Flipflop.remote_storage? + filename = "#{model.class.to_s.underscore}-#{secure_token}.#{file.extension.downcase}" + else + filename = "logo-#{secure_token}.#{file.extension.downcase}" + end end + filename end - filename end private From ef1c17beaaecb2c1835abfd320dac56eb161c270 Mon Sep 17 00:00:00 2001 From: pedong Date: Fri, 23 Nov 2018 14:56:29 +0100 Subject: [PATCH 13/13] [Fix #3056] get url api in the environment variable --- config/initializers/urls.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/initializers/urls.rb b/config/initializers/urls.rb index c0e6cc0f7..f77379b64 100644 --- a/config/initializers/urls.rb +++ b/config/initializers/urls.rb @@ -1,11 +1,11 @@ # API URLs -API_ADRESSE_URL = "https://api-adresse.data.gouv.fr" -API_CARTO_URL = "https://apicarto.sgmap.fr" -API_ENTREPRISE_URL = "https://entreprise.api.gouv.fr/v2" +API_ADRESSE_URL = ENV.fetch("API_ADRESSE_URL", "https://api-adresse.data.gouv.fr") +API_CARTO_URL = ENV.fetch("API_CARTO_URL", "https://apicarto.sgmap.fr") +API_ENTREPRISE_URL = ENV.fetch("API_ENTREPRISE_URL", "https://entreprise.api.gouv.fr/v2") API_GEO_URL = ENV.fetch("API_GEO_URL", "https://geo.api.gouv.fr") -API_GEO_SANDBOX_URL = "https://sandbox.geo.api.gouv.fr" -HELPSCOUT_API_URL = "https://api.helpscout.net/v2" -PIPEDRIVE_API_URL = "https://api.pipedrive.com/v1" +API_GEO_SANDBOX_URL = ENV.fetch("API_GEO_SANDBOX_URL", "https://sandbox.geo.api.gouv.fr") +HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2") +PIPEDRIVE_API_URL = ENV.fetch("PIPEDRIVE_API_URL", "https://api.pipedrive.com/v1") # Internal URLs FOG_BASE_URL = "https://static.demarches-simplifiees.fr"