diff --git a/app/services/sva_svr_decision_date_calculator_service.rb b/app/services/sva_svr_decision_date_calculator_service.rb index 6ddd6cbb3..bc3783e72 100644 --- a/app/services/sva_svr_decision_date_calculator_service.rb +++ b/app/services/sva_svr_decision_date_calculator_service.rb @@ -12,9 +12,18 @@ class SVASVRDecisionDateCalculatorService end def decision_date - base_date = determine_base_date + duration = calculate_duration - duration = case unit + start_date = determine_start_date + correction_delay = calculate_correction_delay(start_date) + + start_date + correction_delay + duration + end + + private + + def calculate_duration + case unit when :days period.days when :weeks @@ -22,35 +31,36 @@ class SVASVRDecisionDateCalculatorService when :months period.months end - - base_date + duration end - private + def determine_start_date + return dossier.depose_at.to_date if dossier.corrections.empty? + return latest_correction_date if resume_method == :reset + return latest_incomplete_correction_date if dossier.corrections.any?(&:incomplete?) - def determine_base_date - return dossier.depose_at.to_date + total_correction_delay if resume_method == :continue - - if dossier.corrections.any? - most_recent_correction_date - else - dossier.depose_at.to_date - end + dossier.depose_at.to_date end - def total_correction_delay + def latest_incomplete_correction_date + correction_date dossier.corrections.filter(&:incomplete?).max_by(&:resolved_at) + end + + def latest_correction_date + correction_date dossier.corrections.max_by(&:resolved_at) + end + + def calculate_correction_delay(start_date) dossier.corrections.sum do |correction| - # If the correction is not resolved, we use the current date - # so interfaces could calculate how many remaining days - resolved_date = correction.resolved_at&.to_date || Date.current + resolved_date = correction_date(correction) + next 0 unless resolved_date > start_date (resolved_date - correction.created_at.to_date).days end end - def most_recent_correction_date - return Date.current if dossier.pending_correction? - - dossier.corrections.max_by(&:resolved_at).resolved_at.to_date + def correction_date(correction) + # NOTE: when correction is not resolved, assume it could be done today + # so interfaces could show how many days are remaining after correction + correction.resolved_at&.to_date || Date.current end end diff --git a/spec/factories/dossier_corrections.rb b/spec/factories/dossier_corrections.rb index a3f88a9f5..acad74696 100644 --- a/spec/factories/dossier_corrections.rb +++ b/spec/factories/dossier_corrections.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :dossier_correction do dossier commentaire + kind { :correction } resolved_at { nil } trait :resolved do diff --git a/spec/services/sva_svr_decision_date_calculator_service_spec.rb b/spec/services/sva_svr_decision_date_calculator_service_spec.rb index cd3de51c5..4eac4a946 100644 --- a/spec/services/sva_svr_decision_date_calculator_service_spec.rb +++ b/spec/services/sva_svr_decision_date_calculator_service_spec.rb @@ -59,7 +59,7 @@ describe SVASVRDecisionDateCalculatorService do end end - context 'there is a pending correction' do + context 'there is a pending correction kind = correct' do before do travel_to DateTime.new(2023, 5, 30, 18) do dossier.flag_as_pending_correction!(build(:commentaire, dossier:)) @@ -72,6 +72,44 @@ describe SVASVRDecisionDateCalculatorService do expect(subject).to eq(Date.new(2023, 7, 26)) end end + + context 'there is a pending correction kind = incomplete' do + before do + travel_to DateTime.new(2023, 5, 30, 18) do + dossier.flag_as_pending_correction!(build(:commentaire, dossier:), :incomplete) + end + + travel_to DateTime.new(2023, 6, 5, 8) # 6 days elapsed + end + + it 'calculates the date, like if resolution will be today' do + expect(subject).to eq(Date.new(2023, 8, 5)) + end + end + + context 'when correction was for an incomplete dossier' do + let!(:correction) do + created_at = DateTime.new(2023, 5, 20, 15) + resolved_at = DateTime.new(2023, 5, 25, 12) + create(:dossier_correction, :incomplete, dossier:, created_at:, resolved_at:) + end + + it 'calculates the date by resetting delay' do + expect(subject).to eq(Date.new(2023, 7, 25)) + end + + context 'when there are multiple corrections' do + let!(:correction2) do + created_at = DateTime.new(2023, 5, 30, 18) + resolved_at = DateTime.new(2023, 6, 3, 8) + create(:dossier_correction, dossier:, created_at:, resolved_at:) + end + + it 'calculates the date based on SVA rules with all correction delays' do + expect(subject).to eq(Date.new(2023, 7, 29)) + end + end + end end end @@ -88,7 +126,7 @@ describe SVASVRDecisionDateCalculatorService do before do created_at = DateTime.new(2023, 5, 16, 15) resolved_at = DateTime.new(2023, 5, 17, 12) - create(:dossier_correction, dossier:, created_at:, resolved_at:) + create(:dossier_correction, :incomplete, dossier:, created_at:, resolved_at:) created_at = DateTime.new(2023, 5, 20, 15) resolved_at = DateTime.new(2023, 5, 25, 12)