diff --git a/app/controllers/schoolings_controller.rb b/app/controllers/schoolings_controller.rb index 6f504668a..cfa1ca809 100644 --- a/app/controllers/schoolings_controller.rb +++ b/app/controllers/schoolings_controller.rb @@ -9,6 +9,8 @@ class SchoolingsController < ApplicationController def abrogate_decision GenerateAbrogationDecisionJob.perform_now(@schooling) + retry_eligibile_payment_requests! + redirect_to student_path(@schooling.student), notice: t("flash.da.abrogated", name: @schooling.student.full_name) end @@ -31,4 +33,11 @@ def set_classe redirect_to school_year_classes_path(selected_school_year), alert: t("errors.classes.not_found") and return end + + def retry_eligibile_payment_requests! + @schooling.pfmps.in_state(:validated).each do |pfmp| + p_r = pfmp.latest_payment_request + p_r.mark_ready! if p_r.eligible_for_auto_retry? + end + end end diff --git a/app/models/asp/payment_request.rb b/app/models/asp/payment_request.rb index e85552708..56a748886 100644 --- a/app/models/asp/payment_request.rb +++ b/app/models/asp/payment_request.rb @@ -106,5 +106,13 @@ def failed? def active? !terminated? end + + def eligible_for_auto_retry? + # rubocop:disable Layout/LineLength + error_message = I18n.t("activerecord.errors.models.asp/payment_request.attributes.ready_state_validation.needs_abrogated_attributive_decision") + # rubocop:enable Layout/LineLength + in_state?(:incomplete) && + last_transition.metadata["incomplete_reasons"]["ready_state_validation"].include?(error_message) + end end end diff --git a/spec/factories/asp/payment_requests.rb b/spec/factories/asp/payment_requests.rb index 253381d61..792966fde 100644 --- a/spec/factories/asp/payment_requests.rb +++ b/spec/factories/asp/payment_requests.rb @@ -2,6 +2,10 @@ FactoryBot.define do factory :asp_payment_request, class: "ASP::PaymentRequest" do + # rubocop:disable Layout/LineLength + error_message = I18n.t("activerecord.errors.models.asp/payment_request.attributes.ready_state_validation.needs_abrogated_attributive_decision") + # rubocop:enable Layout/LineLength + pfmp do association(:pfmp, :validated).tap { |p| p.payment_requests.destroy_all } end @@ -41,6 +45,15 @@ end end + trait :incomplete_for_missing_abrogation_da do + sendable + + after(:create) do |req| + req.errors.add(:ready_state_validation, :needs_abrogated_attributive_decision) + req.mark_incomplete!(incomplete_reasons: { ready_state_validation: [error_message] }) + end + end + trait :sent do ready diff --git a/spec/models/asp/payment_request_spec.rb b/spec/models/asp/payment_request_spec.rb index 5fb29dbd9..2e1b7f7df 100644 --- a/spec/models/asp/payment_request_spec.rb +++ b/spec/models/asp/payment_request_spec.rb @@ -132,4 +132,28 @@ end end end + + describe "eligible_for_auto_retry?" do + let(:p_r_incomplete_for_abrogation) { create(:asp_payment_request, :incomplete_for_missing_abrogation_da) } + let(:p_r_ready) { create(:asp_payment_request, :ready) } + let(:p_r_incomplete) { create(:asp_payment_request, :incomplete) } + + context "when the payment request is in 'incomplete' state with specific error message" do + it "returns true" do + expect(p_r_incomplete_for_abrogation.eligible_for_auto_retry?).to be true + end + end + + context "when the payment request is not in 'incomplete' state" do + it "returns false" do + expect(p_r_ready.eligible_for_auto_retry?).to be false + end + end + + context "when the payment request is in 'incomplete' state without the specific error message" do + it "returns false" do + expect(p_r_incomplete.eligible_for_auto_retry?).to be false + end + end + end end diff --git a/spec/requests/schoolings_controller_spec.rb b/spec/requests/schoolings_controller_spec.rb index e0dea00a8..fdf28b4d0 100644 --- a/spec/requests/schoolings_controller_spec.rb +++ b/spec/requests/schoolings_controller_spec.rb @@ -3,11 +3,27 @@ require "rails_helper" RSpec.describe SchoolingsController do - let(:schooling) { create(:schooling, :with_attributive_decision) } let(:student) { schooling.student } let(:user) { create(:user, :director, :with_selected_establishment, establishment: student.classe.establishment) } - before { sign_in(user) } + let(:schooling) { create(:schooling, :with_attributive_decision) } + let(:payment_request) { create(:asp_payment_request, :incomplete_for_missing_abrogation_da) } + + # rubocop:disable Layout/LineLength + error_message = I18n.t("activerecord.errors.models.asp/payment_request.attributes.ready_state_validation.needs_abrogated_attributive_decision") + # rubocop:enable Layout/LineLength + + before do + sign_in(user) + schooling.pfmps = [payment_request.pfmp] + schooling.save! + Timecop.safe_mode = false + Timecop.freeze(Date.new(2024, 6, 21)) + end + + after do + Timecop.return + end describe "DEL /abrogate_decision" do it "enqueues a job to generate the abrogation document" do @@ -18,4 +34,19 @@ params: { confirmed_director: "1" } end end + + describe "retry_eligibile_payment_requests" do + before do + schooling.update!(end_date: Date.current, start_date: Date.current - 1.day) + end + + context "when the payment request is retry eligible" do + it "does not return abrogated decision error" do + delete abrogate_decision_school_year_class_schooling_path(schooling.classe.school_year, + class_id: schooling.classe.id, id: schooling.id), + params: { confirmed_director: "1" } + expect(payment_request.last_transition.metadata).not_to include(error_message) + end + end + end end