Skip to content

Commit 0cd12e0

Browse files
committed
Add ability to send clinic invitations in bulk
This adds a new page when viewing unknown or home-schooled patients, allowing users to send clinic invitations to any of those patients who have not yet received one. Jira-Issue: MAV-3886 Jira-Issue: MAV-3428
1 parent ce6c95d commit 0cd12e0

6 files changed

Lines changed: 231 additions & 0 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# frozen_string_literal: true
2+
3+
class Schools::InviteToClinicController < Schools::BaseController
4+
before_action :check_can_send_clinic_invitations
5+
before_action :set_back_link_path
6+
before_action :set_programme_statuses
7+
before_action :set_eligible_patients_not_vaccinated
8+
before_action :set_invitations_count_by_programme_type
9+
10+
def edit
11+
@form = SchoolInviteToClinicForm.new
12+
end
13+
14+
def update
15+
@form =
16+
SchoolInviteToClinicForm.new(
17+
programme_types:
18+
params.dig(:school_invite_to_clinic_form, :programme_types)
19+
)
20+
21+
if @form.valid?
22+
clinic_notifcations =
23+
@eligible_patients_not_vaccinated.filter_map do |patient|
24+
patient.notifier.send_clinic_invitation(
25+
Programme.find_all(@form.programme_types),
26+
team: current_team,
27+
academic_year: @academic_year,
28+
sent_by: current_user,
29+
include_already_invited_programmes: false
30+
)
31+
end
32+
33+
flash[
34+
:success
35+
] = "#{I18n.t("children", count: clinic_notifcations.count)} invited to the clinic"
36+
37+
redirect_to @back_link_path
38+
else
39+
render :edit, status: :unprocessable_entity
40+
end
41+
end
42+
43+
private
44+
45+
def check_can_send_clinic_invitations
46+
render status: :not_found unless @location.generic_clinic?
47+
end
48+
49+
def set_back_link_path
50+
@back_link_path = school_patients_path(Location::URN_UNKNOWN)
51+
end
52+
53+
def set_programme_statuses
54+
@programme_statuses =
55+
Patient::ProgrammeStatus.statuses.keys -
56+
Patient::ProgrammeStatus::NOT_ELIGIBLE_STATUSES.keys -
57+
Patient::ProgrammeStatus::HAS_REFUSAL_STATUSES.keys -
58+
Patient::ProgrammeStatus::VACCINATED_STATUSES.keys
59+
end
60+
61+
def set_eligible_patients_not_vaccinated
62+
@eligible_patients_not_vaccinated =
63+
Patient
64+
.joins(:patient_locations)
65+
.where(
66+
patient_locations: {
67+
location: @location,
68+
academic_year: @academic_year
69+
}
70+
)
71+
.where(school_id: @location.school_id)
72+
.includes_statuses
73+
.has_programme_status(
74+
@programme_statuses,
75+
programme: current_team.programmes,
76+
academic_year: @academic_year
77+
)
78+
end
79+
80+
def set_invitations_count_by_programme_type
81+
@invitations_count_by_programme_type =
82+
current_team.programmes.index_with do |programme|
83+
@eligible_patients_not_vaccinated
84+
.includes(:clinic_notifications)
85+
.has_programme_status(
86+
@programme_statuses,
87+
programme:,
88+
academic_year: @academic_year
89+
)
90+
.count do |patient|
91+
!patient.invited_to_clinic?(
92+
[programme],
93+
team: current_team,
94+
academic_year: @academic_year
95+
)
96+
end
97+
end
98+
end
99+
end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<% content_for :before_main do %>
2+
<%= govuk_back_link(href: @back_link_path) %>
3+
<% end %>
4+
5+
<%= h1 "Invite parents to book a clinic appointment" do %>
6+
<span class="nhsuk-caption-l"><%= @location.alternative_name %></span>
7+
Invite parents to book a clinic appointment
8+
<% end %>
9+
10+
<p><%= I18n.t("children_be", count: @eligible_patients_not_vaccinated.count) %> due a vaccination for at least 1 programme.</p>
11+
12+
<p>You can now send clinic booking invitations to their parents.</p>
13+
14+
<%= form_with model: @form, url: school_invite_to_clinic_path(Location::URN_UNKNOWN), method: :put do |f| %>
15+
<%= f.govuk_check_boxes_fieldset :programme_types, legend: nil do %>
16+
<% current_team.programmes.each do |programme| %>
17+
<%= f.govuk_check_box :programme_types,
18+
programme.type,
19+
label: { text: programme.name },
20+
hint: { text: "#{I18n.t("children_have", count: @invitations_count_by_programme_type[programme])} not been invited to a clinic yet" } %>
21+
<% end %>
22+
<% end %>
23+
24+
<%= f.govuk_submit "Send clinic invitations" %>
25+
<% end %>

app/views/schools/patients/index.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
<% if @location.school? %>
1111
<%= govuk_button_link_to "Import class lists", new_school_import_path(@location), secondary: true %>
12+
<% elsif @location.generic_clinic? %>
13+
<%= govuk_button_link_to "Send clinic invitations", edit_school_invite_to_clinic_path(Location::URN_UNKNOWN), secondary: true %>
1214
<% end %>
1315

1416
<div class="nhsuk-grid-row">

config/locales/countables.en.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ en:
33
zero: No children
44
one: 1 child
55
other: "%{count} children"
6+
children_be:
7+
zero: No children are
8+
one: 1 child is
9+
other: "%{count} children are"
10+
children_have:
11+
zero: No children have
12+
one: 1 child has
13+
other: "%{count} children have"
614
children_for_programme:
715
zero: No children for %{programme}
816
one: 1 child for %{programme}

config/routes.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@
268268
end
269269

270270
resources :schools, only: :index, param: :urn_and_site do
271+
resource :invite_to_clinic,
272+
only: %i[edit update],
273+
path: "invite-to-clinic",
274+
controller: "schools/invite_to_clinic"
275+
271276
resources :import, only: :new, controller: "schools/import"
272277
resources :patients, only: :index, controller: "schools/patients"
273278
resources :sessions, only: :index, controller: "schools/sessions"

spec/features/schools_spec.rb

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@
2929
then_i_see_the_secondary_sessions
3030
end
3131

32+
scenario "Sending clinic invitations to children in no known school" do
33+
given_a_team_with_no_known_school_children
34+
and_i_am_signed_in
35+
36+
when_i_visit_the_schools_page
37+
and_i_click_on_no_known_school
38+
then_i_see_the_send_invitations_button
39+
40+
when_i_click_send_clinic_invitations
41+
and_i_select_programmes_and_send
42+
then_i_see_the_invitation_confirmation
43+
and_the_parents_receive_invitations
44+
end
45+
3246
def given_a_team_exists_with_a_few_schools
3347
programmes = [Programme.flu, Programme.hpv]
3448

@@ -134,4 +148,82 @@ def when_i_click_on_edit_session
134148
def and_i_click_on_back
135149
click_on "Back"
136150
end
151+
152+
def given_a_team_with_no_known_school_children
153+
programmes = [Programme.hpv]
154+
@team = create(:team, :with_generic_clinic, programmes:)
155+
@generic_clinic = @team.generic_clinic
156+
157+
@patients =
158+
10.times.map do
159+
create(
160+
:patient,
161+
:consent_no_response,
162+
school: nil,
163+
parents: [build(:parent)],
164+
programmes:,
165+
location: @generic_clinic,
166+
academic_year: AcademicYear.pending
167+
)
168+
end
169+
170+
# We create these to ensure these children aren't invited.
171+
create(
172+
:patient,
173+
:consent_refused,
174+
school: nil,
175+
parents: [build(:parent)],
176+
programmes:,
177+
location: @generic_clinic,
178+
academic_year: AcademicYear.pending
179+
)
180+
create(
181+
:patient,
182+
:consent_conflicting,
183+
school: nil,
184+
parents: [build(:parent)],
185+
programmes:,
186+
location: @generic_clinic,
187+
academic_year: AcademicYear.pending
188+
)
189+
190+
@nurse = create(:nurse, team: @team)
191+
end
192+
193+
def when_i_visit_the_schools_page
194+
visit schools_path
195+
end
196+
197+
def and_i_click_on_no_known_school
198+
click_on "No known school"
199+
end
200+
201+
def then_i_see_the_send_invitations_button
202+
expect(page).to have_content("Send clinic invitations")
203+
end
204+
205+
def when_i_click_send_clinic_invitations
206+
click_on "Send clinic invitations"
207+
end
208+
209+
def and_i_select_programmes_and_send
210+
check "HPV"
211+
click_on "Send clinic invitations"
212+
end
213+
214+
def then_i_see_the_invitation_confirmation
215+
expect(page).to have_content("10 children invited to the clinic")
216+
end
217+
218+
def and_the_parents_receive_invitations
219+
perform_enqueued_jobs
220+
221+
expect(email_deliveries.count).to eq(@patients.count)
222+
223+
@patients.each do |patient|
224+
patient.parents.each do |parent|
225+
expect_email_to parent.email, :clinic_initial_invitation, :any
226+
end
227+
end
228+
end
137229
end

0 commit comments

Comments
 (0)