Skip to content

Commit 8da1381

Browse files
authored
Merge pull request #6601 from NHSDigital/MAV-6064-vaccination-already-had-template-error
Parents not notified when NHS API shows their child was vaccinated elsewhere
2 parents 99017e3 + 6f36301 commit 8da1381

9 files changed

Lines changed: 217 additions & 53 deletions

app/helpers/teams_helper.rb

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,38 @@
33
module TeamsHelper
44
include PhoneHelper
55

6-
def team_contact_name(session)
7-
(session.subteam || session.team).name
6+
def team_contact_name(session: nil, vaccination_record: nil)
7+
contact_entity(session:, vaccination_record:).name
88
end
99

10-
def team_contact_email(session)
11-
(session.subteam || session.team).email
10+
def team_contact_email(session: nil, vaccination_record: nil)
11+
contact_entity(session:, vaccination_record:).email
1212
end
1313

14-
def team_contact_phone(session)
15-
format_phone_with_instructions(session.subteam || session.team)
14+
def team_contact_phone(session: nil, vaccination_record: nil)
15+
format_phone_with_instructions(
16+
contact_entity(session:, vaccination_record:)
17+
)
18+
end
19+
20+
private
21+
22+
def contact_entity(session: nil, vaccination_record: nil)
23+
if session.nil? == vaccination_record.nil?
24+
raise ArgumentError,
25+
"provide either session: or vaccination_record:, not both or neither"
26+
end
27+
28+
team_location =
29+
session&.team_location || vaccination_record&.session&.team_location ||
30+
vaccination_record
31+
&.patient
32+
&.school
33+
&.team_locations
34+
&.includes(:team, :subteam)
35+
&.ordered
36+
&.find_by(academic_year: AcademicYear.current)
37+
38+
team_location&.subteam || team_location&.team
1639
end
1740
end

app/views/notify_templates/email/triage_vaccination_will_happen_mmr_second_dose.text.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ We recently gave <%= patient.short_name %> their <%= previous_dose %> dose of th
1010

1111
We’re coming to <%= session.location.name %> on <%= session_future_dates(session) %> and plan to give <%= patient.short_name %> their <%= next_dose %> dose then. Please let them know about this.
1212

13-
If <%= patient_short_name_possessive(patient) %> health changes, or you arrange for them to get their <%= next_dose %> dose somewhere else, contact us. You can email <%= team_contact_email(session) %> or phone <%= team_contact_phone(session) %>.
13+
If <%= patient_short_name_possessive(patient) %> health changes, or you arrange for them to get their <%= next_dose %> dose somewhere else, contact us. You can email <%= team_contact_email(session:) %> or phone <%= team_contact_phone(session:) %>.

app/views/notify_templates/email/vaccination_administered.text.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ To be fully protected against <%= programme_disease_names(vaccination_record.pro
3232

3333
You can [give feedback](https://feedback.digital.nhs.uk/jfe/form/SV_3fICo6frMvUZX1k) about the ’Give or refuse consent’ service by completing our short survey. Your feedback will help us improve the service.
3434

35-
<%= team_contact_name(vaccination_record.session) %>
36-
<%= team_contact_email(vaccination_record.session) %>
37-
<%= team_contact_phone(vaccination_record.session) %>
35+
<%= team_contact_name(vaccination_record:) %>
36+
<%= team_contact_email(vaccination_record:) %>
37+
<%= team_contact_phone(vaccination_record:) %>

app/views/notify_templates/email/vaccination_already_had.text.erb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ subject: "Cancelled <%= programme_name_for_parents(vaccination_record.programme)
55
---
66
We’re contacting you because our records show that <%= short_patient_name %> was vaccinated at another location <%= vaccination_record_today_or_date(vaccination_record) %> so we’re cancelling their vaccination appointment at school.
77

8-
If you think this is wrong, please tell us immediately on <%= team_contact_phone(vaccination_record.session) %> or <%= team_contact_email(vaccination_record.session) %>.
8+
If you think this is wrong, please tell us immediately on <%= team_contact_phone(vaccination_record:) %> or <%= team_contact_email(vaccination_record:) %>.
99

1010
If <%= short_patient_name %> was vaccinated <%= vaccination_record_today_or_date(vaccination_record) %>, you do not need
1111
to do anything.
1212

13-
<%= team_contact_name(vaccination_record.session) %>
13+
<%= team_contact_name(vaccination_record:) %>

app/views/notify_templates/email/vaccination_not_administered.text.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ subject: "Your child did not have their <%= programme_name_for_parents(vaccinati
77

88
<% if show_additional_instructions? %>If you’d still like your child to be vaccinated, you can book an appointment at a catch-up clinic by contacting our team.<% end %>
99

10-
<%= team_contact_name(vaccination_record.session) %>
11-
<%= team_contact_email(vaccination_record.session) %>
12-
<%= team_contact_phone(vaccination_record.session) %>
10+
<%= team_contact_name(vaccination_record:) %>
11+
<%= team_contact_email(vaccination_record:) %>
12+
<%= team_contact_phone(vaccination_record:) %>

app/views/notify_templates/sms/vaccination_already_had.text.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ template_id: "fab1e355-bde1-47d5-835c-103bfd232b93"
33
template_name: vaccination_already_had
44
---
55
We are cancelling <%= short_patient_name %>'s <%= programme_name_for_parents(vaccination_record.programme) %> vaccination at school
6-
as our records show <%= short_patient_name %> was vaccinated at another location <%= vaccination_record_today_or_date(vaccination_record) %>. If this is wrong, contact us. <%= team_contact_phone(vaccination_record.session) %>
6+
as our records show <%= short_patient_name %> was vaccinated at another location <%= vaccination_record_today_or_date(vaccination_record) %>. If this is wrong, contact us. <%= team_contact_phone(vaccination_record:) %>

app/views/notify_templates/sms/vaccination_not_administered.text.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ template_name: vaccination_not_administered
44
---
55
<%= short_patient_name %> did not have their <%= programme_name_for_parents(vaccination_record.programme) %> vaccination at school today. This was because <%= reason_did_not_vaccinate %>.
66

7-
If you'd still like them to be vaccinated on a different date, contact the local health team by calling <%= team_contact_phone(vaccination_record.session) %>, or email <%= team_contact_email(vaccination_record.session) %>.
7+
If you'd still like them to be vaccinated on a different date, contact the local health team by calling <%= team_contact_phone(vaccination_record:) %>, or email <%= team_contact_email(vaccination_record:) %>.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# frozen_string_literal: true
2+
3+
describe "NHS vaccination already had notification" do
4+
before do
5+
Flipper.enable(:imms_api_integration)
6+
Flipper.enable(:imms_api_search_job, Programme.flu)
7+
end
8+
9+
after do
10+
Flipper.disable(:imms_api_integration)
11+
Flipper.disable(:imms_api_search_job)
12+
end
13+
14+
scenario "parent is notified when NHS API reveals their child was vaccinated elsewhere" do
15+
given_a_patient_with_consent_exists
16+
and_the_nhs_api_returns_a_flu_vaccination_for_the_patient
17+
when_the_nhs_vaccination_search_runs
18+
then_the_parent_receives_a_vaccination_already_had_email
19+
end
20+
21+
private
22+
23+
def given_a_patient_with_consent_exists
24+
team =
25+
create(
26+
:team,
27+
programmes: [Programme.flu],
28+
name: "South Hampshire SAIS",
29+
email: "southhampshire@example.com",
30+
phone: "02380 654321"
31+
)
32+
school = create(:gias_school, team:)
33+
session =
34+
create(:session, programmes: [Programme.flu], team:, location: school)
35+
@parent = create(:parent, email: "parent@example.com")
36+
@patient =
37+
create(
38+
:patient,
39+
nhs_number: "9449308357",
40+
parents: [@parent],
41+
session:,
42+
school:
43+
)
44+
create(
45+
:consent,
46+
:given,
47+
patient: @patient,
48+
programme: Programme.flu,
49+
parent: @parent
50+
)
51+
end
52+
53+
def and_the_nhs_api_returns_a_flu_vaccination_for_the_patient
54+
stub_request(
55+
:get,
56+
"https://sandbox.api.service.nhs.uk/immunisation-fhir-api/FHIR/R4/Immunization"
57+
).with(
58+
query: {
59+
"patient.identifier" => "https://fhir.nhs.uk/Id/nhs-number|9449308357",
60+
"-immunization.target" => "3IN1,FLU,HPV,MENACWY,MMR,MMRV"
61+
}
62+
).to_return(
63+
status: 200,
64+
body:
65+
file_fixture(
66+
"fhir/search_responses/1_result_in_academic_year_2025.json"
67+
).read,
68+
headers: {
69+
"content-type" => "application/fhir+json"
70+
}
71+
)
72+
end
73+
74+
def when_the_nhs_vaccination_search_runs
75+
SearchVaccinationRecordsInNHSJob.new.perform(@patient.id)
76+
end
77+
78+
def then_the_parent_receives_a_vaccination_already_had_email
79+
expect(email_deliveries).to include(
80+
matching_notify_email(
81+
to: "parent@example.com",
82+
template: :vaccination_already_had
83+
).with_content_including(
84+
"South Hampshire SAIS",
85+
"southhampshire@example.com",
86+
"023 8065 4321"
87+
)
88+
)
89+
end
90+
end

spec/helpers/teams_helper_spec.rb

Lines changed: 87 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,111 @@
1212

1313
let(:session) { create(:session, team:) }
1414

15-
describe "#team_contact_name" do
16-
subject { helper.team_contact_name(session) }
15+
context "with a session" do
16+
describe "#team_contact_name" do
17+
subject { helper.team_contact_name(session:) }
1718

18-
context "without a subteam" do
19-
it { should eq("SAIS Team") }
19+
context "without a subteam" do
20+
it { should eq("SAIS Team") }
21+
end
22+
23+
context "with a subteam" do
24+
before do
25+
subteam = create(:subteam, team:, name: "SAIS Subteam")
26+
session.team_location.update!(subteam:)
27+
end
28+
29+
it { should eq("SAIS Subteam") }
30+
end
2031
end
2132

22-
context "with a subteam" do
23-
before do
24-
subteam = create(:subteam, team:, name: "SAIS Subteam")
25-
session.team_location.update!(subteam:)
33+
describe "#team_contact_email" do
34+
subject { helper.team_contact_email(session:) }
35+
36+
context "without a subteam" do
37+
it { should eq("sais@example.com") }
2638
end
2739

28-
it { should eq("SAIS Subteam") }
40+
context "with a subteam" do
41+
before do
42+
subteam = create(:subteam, team:, email: "subteam@example.com")
43+
session.team_location.update!(subteam:)
44+
end
45+
46+
it { should eq("subteam@example.com") }
47+
end
2948
end
30-
end
3149

32-
describe "#team_contact_email" do
33-
subject { helper.team_contact_email(session) }
50+
describe "#team_contact_phone" do
51+
subject { helper.team_contact_phone(session:) }
3452

35-
context "without a subteam" do
36-
it { should eq("sais@example.com") }
37-
end
53+
context "without a subteam" do
54+
it { should eq("01234 567890") }
55+
end
3856

39-
context "with a subteam" do
40-
before do
41-
subteam = create(:subteam, team:, email: "subteam@example.com")
42-
session.team_location.update!(subteam:)
57+
context "with a subteam" do
58+
before do
59+
subteam =
60+
create(
61+
:subteam,
62+
team:,
63+
phone: "01234 567890",
64+
phone_instructions: "option 2"
65+
)
66+
session.team_location.update!(subteam:)
67+
end
68+
69+
it { should eq("01234 567890 (option 2)") }
4370
end
71+
end
72+
end
4473

45-
it { should eq("subteam@example.com") }
74+
context "with neither session nor vaccination_record" do
75+
it "raises an ArgumentError" do
76+
expect { helper.team_contact_name }.to raise_error(ArgumentError)
4677
end
4778
end
4879

49-
describe "#team_contact_phone" do
50-
subject { helper.team_contact_phone(session) }
80+
context "with both session and vaccination_record" do
81+
let(:vaccination_record) do
82+
create(:vaccination_record, programme: Programme.hpv, session:)
83+
end
5184

52-
context "without a subteam" do
53-
it { should eq("01234 567890") }
85+
it "raises an ArgumentError" do
86+
expect {
87+
helper.team_contact_name(session:, vaccination_record:)
88+
}.to raise_error(ArgumentError)
5489
end
90+
end
5591

56-
context "with a subteam" do
57-
before do
58-
subteam =
59-
create(
60-
:subteam,
61-
team:,
62-
phone: "01234 567890",
63-
phone_instructions: "option 2"
64-
)
65-
session.team_location.update!(subteam:)
66-
end
92+
context "with a vaccination_record without a session" do
93+
let(:school) { create(:gias_school, team:) }
94+
let(:patient) { create(:patient, school:) }
95+
let(:vaccination_record) do
96+
create(
97+
:vaccination_record,
98+
:sourced_from_nhs_immunisations_api,
99+
patient:,
100+
session: nil
101+
)
102+
end
103+
104+
describe "#team_contact_name" do
105+
subject { helper.team_contact_name(vaccination_record:) }
67106

68-
it { should eq("01234 567890 (option 2)") }
107+
it { should eq("SAIS Team") }
108+
end
109+
110+
describe "#team_contact_email" do
111+
subject { helper.team_contact_email(vaccination_record:) }
112+
113+
it { should eq("sais@example.com") }
114+
end
115+
116+
describe "#team_contact_phone" do
117+
subject { helper.team_contact_phone(vaccination_record:) }
118+
119+
it { should eq("01234 567890") }
69120
end
70121
end
71122
end

0 commit comments

Comments
 (0)