Skip to content

Commit 5fc592b

Browse files
committed
Add nurse-facing follow-up flow for consents with requested discussion
When a parent refuses vaccination for certain reasons (medical, personal choice, contains gelatine, other), they can request a follow-up discussion with a nurse. Here we add the nurse-side flow to resolve that request. The nurse visits the consent record and is presented with a follow-up page showing the parent's contact details and the question "Does their original decision still stand?". If yes (refusal confirmed): taken to a confirmation page where they can add notes and confirm the refusal. The existing consent is updated in place with follow_up_outcome: "confirmed" and follow_up_resolved_at stamped and notes amended. If no (refusal withdrawn): taken through the full consent wizard to record a given consent on behalf of the parent (following verbal consent journey). The existing consent record (that requested follow up) is invalidated and a new "given" one created. `:who` step omitted in follow-up flow because the parent is already known from the original consent - there is no need to ask the nurse to select or create a contact again.
1 parent 2423924 commit 5fc592b

12 files changed

Lines changed: 251 additions & 2 deletions

File tree

app/components/app_consent_summary_component.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ def initialize(
66
change_links: {},
77
show_email_address: false,
88
show_notes: false,
9+
show_parent_name: false,
910
show_notify_parent: false,
1011
show_phone_number: false,
1112
show_programme: false,
@@ -15,6 +16,7 @@ def initialize(
1516
@change_links = change_links
1617
@show_email_address = show_email_address
1718
@show_notes = show_notes
19+
@show_parent_name = show_parent_name
1820
@show_notify_parent = show_notify_parent
1921
@show_phone_number = show_phone_number
2022
@show_programme = show_programme
@@ -27,6 +29,7 @@ def call = govuk_summary_list(rows:, actions: @change_links.present?)
2729

2830
attr_reader :consent,
2931
:change_links,
32+
:show_parent_name,
3033
:show_phone_number,
3134
:show_email_address,
3235
:show_programme,
@@ -37,12 +40,14 @@ def call = govuk_summary_list(rows:, actions: @change_links.present?)
3740
delegate :programme, to: :consent
3841
delegate :consent_response_tag,
3942
:govuk_summary_list,
43+
:consent_parent_name,
4044
:consent_parent_email,
4145
:consent_parent_phone,
4246
to: :helpers
4347

4448
def rows
4549
[
50+
parent_name_row,
4651
phone_number_row,
4752
email_address_row,
4853
programme_row,
@@ -57,6 +62,12 @@ def rows
5762
].compact
5863
end
5964

65+
def parent_name_row
66+
if show_parent_name && (name = consent_parent_name(consent)).present?
67+
{ key: { text: "Parent" }, value: { text: name } }
68+
end
69+
end
70+
6071
def phone_number_row
6172
if show_phone_number && (phone = consent_parent_phone(consent)).present?
6273
{ key: { text: "Phone number" }, value: { text: phone } }

app/controllers/draft_consents_controller.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ def update
4242

4343
@draft_consent.seed_health_questions if current_step == :agree
4444

45-
jump_to("confirm") if @draft_consent.editing? && current_step != :confirm
45+
if @draft_consent.editing? && !@draft_consent.follow_up_flow? &&
46+
current_step != :confirm
47+
jump_to("confirm")
48+
end
4649

4750
reload_steps
4851

@@ -82,6 +85,15 @@ def handle_confirm
8285
PatientStatusUpdater.call(patient: @patient)
8386
end
8487

88+
if (old_consent_id = @draft_consent.follow_up_consent_id)
89+
Consent.find(old_consent_id).resolve_follow_up!(
90+
outcome: :withdrawn,
91+
notes:
92+
"#{@draft_consent.human_enum_name(:response)} in follow-up discussion.",
93+
invalidate: true
94+
)
95+
end
96+
8597
if @draft_consent.send_confirmation?
8698
@consent.notifier.send_confirmation(
8799
session: @session,

app/controllers/patient_sessions/consents_controller.rb

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
class PatientSessions::ConsentsController < PatientSessions::BaseController
44
before_action :set_consent, except: %i[create send_request]
5+
before_action :ensure_can_follow_up,
6+
only: %i[
7+
edit_follow_up
8+
update_follow_up
9+
edit_confirm_refusal
10+
update_confirm_refusal
11+
]
512
before_action :ensure_can_withdraw, only: %i[edit_withdraw update_withdraw]
613
before_action :ensure_can_invalidate,
714
only: %i[edit_invalidate update_invalidate]
@@ -51,6 +58,58 @@ def send_request
5158
def show
5259
end
5360

61+
def edit_follow_up
62+
render :follow_up
63+
end
64+
65+
def update_follow_up
66+
if follow_up_params[:decision_stands].nil?
67+
@consent.errors.add(:decision_stands, :blank)
68+
render :follow_up, status: :unprocessable_content
69+
elsif follow_up_params[:decision_stands] == "true"
70+
redirect_to confirm_refusal_session_patient_programme_consent_path
71+
else
72+
@draft_consent = DraftConsent.new(request_session: session, current_user:)
73+
@draft_consent.clear_attributes
74+
@draft_consent.assign_attributes(create_params)
75+
@draft_consent.follow_up_consent_id = @consent.id
76+
@draft_consent.follow_up_flow = true
77+
@draft_consent.new_or_existing_contact = @consent.parent_id.to_s
78+
@draft_consent.route = "phone"
79+
80+
if @draft_consent.save
81+
redirect_to draft_consent_path("agree")
82+
else
83+
render :follow_up, status: :unprocessable_content
84+
end
85+
end
86+
end
87+
88+
def edit_confirm_refusal
89+
render :confirm_refusal
90+
end
91+
92+
def update_confirm_refusal
93+
if confirm_refusal_params[:confirmed].nil?
94+
@consent.errors.add(:confirmed, :blank)
95+
render :confirm_refusal, status: :unprocessable_content
96+
elsif confirm_refusal_params[:confirmed] == "true"
97+
ActiveRecord::Base.transaction do
98+
@consent.resolve_follow_up!(
99+
outcome: :confirmed,
100+
notes: confirm_refusal_params[:notes].to_s
101+
)
102+
end
103+
104+
redirect_to session_patient_programme_consent_path,
105+
flash: {
106+
success: "Consent from #{@consent.name} updated."
107+
}
108+
else
109+
redirect_to session_patient_programme_consent_path
110+
end
111+
end
112+
54113
def edit_withdraw
55114
render :withdraw
56115
end
@@ -114,6 +173,10 @@ def update_patient_status
114173
PatientStatusUpdater.call(patient: @patient)
115174
end
116175

176+
def ensure_can_follow_up
177+
redirect_to action: :show unless @consent.can_follow_up?
178+
end
179+
117180
def ensure_can_withdraw
118181
redirect_to action: :show unless @consent.can_withdraw?
119182
end
@@ -131,6 +194,14 @@ def create_params
131194
}
132195
end
133196

197+
def follow_up_params
198+
params.permit(consent: :decision_stands)[:consent] || {}
199+
end
200+
201+
def confirm_refusal_params
202+
params.permit(consent: %i[confirmed notes])[:consent] || {}
203+
end
204+
134205
def withdraw_params
135206
params.expect(consent: %i[reason_for_refusal notes]).merge(
136207
response: "refused",

app/models/consent.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class Consent < ApplicationRecord
6666
include Notable
6767
include Refusable
6868

69+
attr_accessor :confirmed, :decision_stands
70+
6971
audited associated_with: :patient
7072

7173
belongs_to :patient
@@ -144,6 +146,12 @@ def can_invalidate?
144146
not_invalidated?
145147
end
146148

149+
def can_follow_up?
150+
not_invalidated? && refusal_with_follow_up?
151+
end
152+
153+
def follow_up_resolved? = follow_up_resolved_at.present?
154+
147155
def responded_at
148156
invalidated_at || withdrawn_at || submitted_at
149157
end
@@ -252,6 +260,23 @@ def update_vaccination_records_no_notify!
252260
end
253261
end
254262

263+
def resolve_follow_up!(outcome:, notes: nil, invalidate: false)
264+
ActiveRecord::Base.transaction do
265+
attrs = {
266+
follow_up_requested: false,
267+
follow_up_outcome: outcome,
268+
follow_up_resolved_at: Time.current
269+
}
270+
271+
attrs[:invalidated_at] = Time.current if invalidate
272+
attrs[:notes] = notes if notes.present?
273+
274+
update!(attrs)
275+
276+
PatientStatusUpdater.call(patient: patient)
277+
end
278+
end
279+
255280
def notifier = Notifier::Consent.new(self)
256281

257282
class ConsentFormNotRecorded < StandardError

app/models/draft_consent.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class DraftConsent
4040
attribute :triage_notes, :string
4141
attribute :triage_status_option, :string
4242
attribute :vaccine_methods, array: true, default: []
43+
attribute :follow_up_consent_id, :integer
44+
attribute :follow_up_flow, :boolean, default: false
4345
attribute :vaccine_stock_is_available, :boolean
4446
attribute :without_gelatine, :boolean
4547

@@ -52,7 +54,7 @@ def initialize(current_user:, **attributes)
5254

5355
def wizard_steps
5456
[
55-
:who,
57+
(:who unless follow_up_flow?),
5658
(:parent_details unless via_self_consent?),
5759
(:route unless via_self_consent?),
5860
(:mmrv_vaccine_availability if eligible_for_mmrv?),
@@ -341,6 +343,8 @@ def write_to!(consent, triage_form:)
341343
end
342344
end
343345

346+
def follow_up_flow? = follow_up_flow == true
347+
344348
def via_self_consent? = route == "self_consent"
345349

346350
def send_confirmation? = notify_parent_on_refusal != false
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<% content_for :before_main do %>
2+
<%= govuk_back_link(href: follow_up_session_patient_programme_consent_path) %>
3+
<% end %>
4+
5+
<%= form_with model: @consent, url: confirm_refusal_session_patient_programme_consent_path, method: :post do |f| %>
6+
<%= f.mavis_error_summary %>
7+
8+
<% page_title = "Update consent response" %>
9+
<%= h1 page_title: do %>
10+
<span class="nhsuk-caption-l">
11+
Consent response from <%= @consent.name %>
12+
</span>
13+
<%= page_title %>
14+
<% end %>
15+
16+
<%= f.govuk_text_area :notes, label: { text: "Notes" } %>
17+
18+
<%= f.govuk_radio_buttons_fieldset :confirmed,
19+
legend: { text: "Confirm consent refusal?" } do %>
20+
<%= f.govuk_radio_button :confirmed, "true",
21+
label: { text: "Yes" },
22+
link_errors: true %>
23+
<%= f.govuk_radio_button :confirmed, "false",
24+
label: { text: "No" } %>
25+
<% end %>
26+
27+
<%= f.govuk_submit "Save changes" %>
28+
<% end %>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<% content_for :before_main do %>
2+
<%= govuk_back_link(href: session_patient_programme_consent_path) %>
3+
<% end %>
4+
5+
<%= form_with model: @consent, url: follow_up_session_patient_programme_consent_path, method: :post do |f| %>
6+
<%= f.mavis_error_summary %>
7+
8+
<% page_title = "Follow up refusal" %>
9+
<%= h1 page_title: do %>
10+
<span class="nhsuk-caption-l">
11+
Consent response from <%= @consent.name %>
12+
</span>
13+
<%= page_title %>
14+
<% end %>
15+
16+
<div class="nhsuk-inset-text">
17+
<span class="nhsuk-u-visually-hidden">Information: </span>
18+
<%= render AppConsentSummaryComponent.new(@consent, show_parent_name: true, show_email_address: true, show_phone_number: true, show_programme: true, show_notes: true) %>
19+
</div>
20+
21+
<%= f.govuk_radio_buttons_fieldset :decision_stands,
22+
legend: { text: "Does their original decision still stand?" } do %>
23+
<%= f.govuk_radio_button :decision_stands, "true",
24+
label: { text: "Yes" },
25+
link_errors: true %>
26+
<%= f.govuk_radio_button :decision_stands, "false",
27+
label: { text: "No" } %>
28+
<% end %>
29+
30+
<%= f.govuk_submit "Continue" %>
31+
<% end %>

app/views/patient_sessions/consents/show.html.erb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
<%= h1 "Consent response from #{@consent.name}" %>
66

77
<%= render AppActionListComponent.new do |action_list| %>
8+
<% if @consent.can_follow_up? %>
9+
<% action_list.with_item(
10+
text: "Follow up",
11+
href: follow_up_session_patient_programme_consent_path,
12+
) %>
13+
<% end %>
14+
815
<% if @consent.can_withdraw? %>
916
<% action_list.with_item(
1017
text: "Withdraw consent",

config/locales/en.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ en:
447447
blank: Choose a file
448448
consent:
449449
attributes:
450+
confirmed:
451+
blank: Select yes or no
452+
decision_stands:
453+
blank: Select yes or no
450454
notes:
451455
blank: Enter notes
452456
too_long: Enter notes that are less than %{count} characters long

config/routes.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@
315315
post "send-request", on: :collection, action: :send_request
316316

317317
member do
318+
get "follow-up", action: :edit_follow_up
319+
post "follow-up", action: :update_follow_up
320+
321+
get "confirm-refusal", action: :edit_confirm_refusal
322+
post "confirm-refusal", action: :update_confirm_refusal
323+
318324
get "withdraw", action: :edit_withdraw
319325
post "withdraw", action: :update_withdraw
320326

0 commit comments

Comments
 (0)