From d05ded88d890396c5e551a9e90a72e57db672d3a Mon Sep 17 00:00:00 2001 From: Joshua Frost Date: Thu, 26 Mar 2026 16:12:08 +0000 Subject: [PATCH] Add "Review vaccs history" status * Adds new status that patients get for a programme when they have been triaged as "Safe to vaccinate" but a new vaccination record has appeared in their history. Jira-Issue: MAV-5582 --- app/lib/status_generator/programme.rb | 9 +++ app/lib/status_generator/triage.rb | 4 ++ app/models/patient/programme_status.rb | 6 ++ config/locales/status.en.yml | 2 + spec/lib/status_generator/programme_spec.rb | 26 ++++++++ spec/lib/status_generator/triage_spec.rb | 74 ++++++++++++++++++++- 6 files changed, 119 insertions(+), 2 deletions(-) diff --git a/app/lib/status_generator/programme.rb b/app/lib/status_generator/programme.rb index 6aa1fffb1c..a5200469c8 100644 --- a/app/lib/status_generator/programme.rb +++ b/app/lib/status_generator/programme.rb @@ -66,6 +66,8 @@ def status :needs_consent_no_response elsif should_be_cannot_vaccinate_delay_vaccination? :cannot_vaccinate_delay_vaccination + elsif should_be_review_vaccination_history? + :review_vaccination_history elsif should_be_due? :due elsif should_be_needs_triage? @@ -218,6 +220,13 @@ def should_be_cannot_vaccinate_delay_vaccination? is_eligible? && triage_generator.status == :delay_vaccination end + def should_be_review_vaccination_history? + is_eligible? && triage_generator.status == :safe_to_vaccinate && + vaccination_records.any? do |r| + r.created_at > triage_generator.created_at + end + end + def should_be_due? = is_due? def should_be_needs_triage? diff --git a/app/lib/status_generator/triage.rb b/app/lib/status_generator/triage.rb index 82c5136904..9e074920d9 100644 --- a/app/lib/status_generator/triage.rb +++ b/app/lib/status_generator/triage.rb @@ -51,6 +51,10 @@ def without_gelatine latest_triage&.without_gelatine if status_should_be_safe_to_vaccinate? end + def created_at + latest_triage&.created_at + end + delegate :disease_types, to: :consent_generator def delay_vaccination_until_date diff --git a/app/models/patient/programme_status.rb b/app/models/patient/programme_status.rb index c3ea99ac3e..750fcb11ef 100644 --- a/app/models/patient/programme_status.rb +++ b/app/models/patient/programme_status.rb @@ -85,6 +85,7 @@ class Patient::ProgrammeStatus < ApplicationRecord needs_consent has_refusal needs_triage + review_vaccination_history due cannot_vaccinate vaccinated @@ -108,6 +109,10 @@ class Patient::ProgrammeStatus < ApplicationRecord NEEDS_TRIAGE_STATUSES = { "needs_triage" => 30 }.freeze + REVIEW_VACCINATION_HISTORY_STATUSES = { + "review_vaccination_history" => 35 + }.freeze + DUE_STATUSES = { "due" => 40 }.freeze CANNOT_VACCINATE_STATUSES = { @@ -130,6 +135,7 @@ class Patient::ProgrammeStatus < ApplicationRecord **NEEDS_CONSENT_STATUSES, **HAS_REFUSAL_STATUSES, **NEEDS_TRIAGE_STATUSES, + **REVIEW_VACCINATION_HISTORY_STATUSES, **DUE_STATUSES, **CANNOT_VACCINATE_STATUSES, **VACCINATED_STATUSES diff --git a/config/locales/status.en.yml b/config/locales/status.en.yml index bee1d1d732..9a26dcd55b 100644 --- a/config/locales/status.en.yml +++ b/config/locales/status.en.yml @@ -68,6 +68,7 @@ en: needs_consent_no_contact_details: Needs consent needs_triage: Needs triage not_eligible: Not eligible + review_vaccination_history: Review vaccs history vaccinated: Vaccinated vaccinated_already: Vaccinated vaccinated_fully: Vaccinated @@ -96,6 +97,7 @@ en: needs_consent_no_contact_details: blue needs_triage: blue not_eligible: grey + review_vaccination_history: blue vaccinated: white vaccinated_already: white vaccinated_fully: white diff --git a/spec/lib/status_generator/programme_spec.rb b/spec/lib/status_generator/programme_spec.rb index 3154b4e983..512bf36d02 100644 --- a/spec/lib/status_generator/programme_spec.rb +++ b/spec/lib/status_generator/programme_spec.rb @@ -499,6 +499,32 @@ end end + context "when a vaccination record was added after a safe to vaccinate triage" do + let(:programme) { Programme.mmr } + + before do + create(:consent, :given, patient:, programme:) + create( + :triage, + :safe_to_vaccinate, + patient:, + programme:, + created_at: 1.day.ago + ) + create(:vaccination_record, :yesterday, patient:, programme:) + end + + its(:consent_status) { should be(:given) } + its(:consent_vaccine_methods) { should contain_exactly("injection") } + its(:date) { should eq(Date.yesterday) } + its(:disease_types) { should be_empty } + its(:dose_sequence) { should eq(2) } + its(:location_id) { should be_nil } + its(:status) { should be(:review_vaccination_history) } + its(:vaccine_methods) { should contain_exactly("injection") } + its(:without_gelatine) { should be(false) } + end + context "when not eligible" do let(:patient) { create(:patient, year_group: 12, parents:) } diff --git a/spec/lib/status_generator/triage_spec.rb b/spec/lib/status_generator/triage_spec.rb index 308f1d4e28..b06a24a117 100644 --- a/spec/lib/status_generator/triage_spec.rb +++ b/spec/lib/status_generator/triage_spec.rb @@ -4,7 +4,7 @@ subject(:generator) do described_class.new( programme_type: programme.type, - academic_year: AcademicYear.current, + academic_year: current_academic_year, patient:, consents: patient.consents, triages: patient.triages, @@ -15,6 +15,7 @@ ) end + let(:current_academic_year) { AcademicYear.current } let(:patient) { create(:patient) } let(:programme) { Programme.hpv } @@ -212,7 +213,6 @@ end describe "academic year filtering" do - let(:current_academic_year) { AcademicYear.current } let(:previous_academic_year) { current_academic_year - 1 } let(:patient) { create(:patient) } let(:programme) { Programme.sample } @@ -366,6 +366,76 @@ end end + describe "#created_at" do + subject { generator.created_at } + + context "with no triage" do + it { should be_nil } + end + + context "with a safe to vaccinate triage" do + let!(:triage) do + create(:triage, :safe_to_vaccinate, patient:, programme:) + end + + it { should eq(triage.created_at) } + end + + context "with a safe to vaccinate triage and vaccinated" do + let!(:triage) do + create(:triage, :safe_to_vaccinate, patient:, programme:) + end + + before { create(:vaccination_record, patient:, programme:) } + + it { should eq(triage.created_at) } + end + + context "with a do not vaccinate triage" do + let!(:triage) { create(:triage, :do_not_vaccinate, patient:, programme:) } + + it { should eq(triage.created_at) } + end + + context "with multiple triages" do + let!(:latest_triage) do + create( + :triage, + :safe_to_vaccinate, + patient:, + programme:, + created_at: latest_created_at + ) + end + + let(:older_created_at) do + Date.new(current_academic_year, 10, 15).in_time_zone + end + + let(:latest_created_at) { older_created_at + 2.days } + + before do + create( + :triage, + :safe_to_vaccinate, + patient:, + programme:, + created_at: older_created_at + ) + end + + it { should eq(latest_triage.created_at) } + end + + context "with an invalidated safe to vaccinate triage" do + before do + create(:triage, :safe_to_vaccinate, :invalidated, patient:, programme:) + end + + it { should be_nil } + end + end + describe "#without_gelatine" do subject { generator.without_gelatine }