Skip to content

Commit 84bd85f

Browse files
committed
Add complete all and continue buttons to medical info page
- Add these buttons to the top and bottom of the page, as submit buttons on a form that POSTs to the current URL - Rework RecordMedicalInformationForm to back these forms, and have its save function create all missing medical info review records for the appointment - Have the view wrap the save call to this form in a transaction (as we're potentially writing multiple database records) - Redirect to Awaiting Images when done
1 parent 122a89a commit 84bd85f

5 files changed

Lines changed: 124 additions & 19 deletions

File tree

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
from django import forms
22

3-
from manage_breast_screening.nhsuk_forms.fields import ChoiceField
3+
from manage_breast_screening.participants.models import MedicalInformationSection
44

55

66
class RecordMedicalInformationForm(forms.Form):
7-
decision = ChoiceField(
8-
label="Can imaging go ahead?",
9-
choices=(
10-
("continue", "Yes, mark incomplete sections as ‘none’ or ‘no’"),
11-
("dropout", "No, screening cannot proceed"),
12-
),
13-
required=True,
14-
widget=forms.RadioSelect(),
15-
)
7+
def __init__(self, *args, appointment, user, **kwargs):
8+
self.appointment = appointment
9+
self.user = user
10+
super().__init__(*args, **kwargs)
1611

1712
def save(self):
18-
pass
13+
all_sections = [choice[0] for choice in MedicalInformationSection.choices]
14+
reviewed_sections = set(
15+
self.appointment.medical_information_reviews.values_list(
16+
"section", flat=True
17+
)
18+
)
19+
missing_sections = set(all_sections) - reviewed_sections
20+
21+
for section in missing_sections:
22+
self.appointment.medical_information_reviews.create(
23+
section=section,
24+
reviewed_by=self.user,
25+
)

manage_breast_screening/mammograms/jinja2/mammograms/record_medical_information.jinja

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,13 @@
285285
{% endcall %}
286286

287287
{% endblock %}
288+
289+
{% block wizard_form %}
290+
<form method="post">
291+
{{ csrf_input }}
292+
{{ button({
293+
"text": "Complete all and continue",
294+
"classes": "nhsuk-u-margin-bottom-4"
295+
}) }}
296+
</form>
297+
{% endblock %}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
3+
from manage_breast_screening.mammograms.forms import RecordMedicalInformationForm
4+
from manage_breast_screening.participants.models import MedicalInformationSection
5+
from manage_breast_screening.participants.tests.factories import AppointmentFactory
6+
7+
8+
@pytest.mark.django_db
9+
class TestRecordMedicalInformationForm:
10+
def test_save_creates_reviews_for_all_missing_sections(self, clinical_user):
11+
appointment = AppointmentFactory.create()
12+
13+
assert appointment.medical_information_reviews.count() == 0
14+
15+
form = RecordMedicalInformationForm(
16+
appointment=appointment,
17+
user=clinical_user,
18+
)
19+
form.save()
20+
21+
assert appointment.medical_information_reviews.count() == 5
22+
all_sections = {choice[0] for choice in MedicalInformationSection.choices}
23+
reviewed_sections = set(
24+
appointment.medical_information_reviews.values_list("section", flat=True)
25+
)
26+
assert reviewed_sections == all_sections
27+
for review in appointment.medical_information_reviews.all():
28+
assert review.reviewed_by == clinical_user
29+
30+
def test_save_does_nothing_when_all_sections_already_reviewed(
31+
self, clinical_user, django_assert_num_queries
32+
):
33+
appointment = AppointmentFactory.create()
34+
35+
for section, _ in MedicalInformationSection.choices:
36+
appointment.medical_information_reviews.create(
37+
section=section,
38+
reviewed_by=clinical_user,
39+
)
40+
41+
assert appointment.medical_information_reviews.count() == 5
42+
43+
form = RecordMedicalInformationForm(
44+
appointment=appointment,
45+
user=clinical_user,
46+
)
47+
form.save()
48+
49+
assert appointment.medical_information_reviews.count() == 5

manage_breast_screening/mammograms/views/appointment_views.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22

33
from django.contrib import messages
4+
from django.db import DatabaseError, IntegrityError, transaction
45
from django.http import Http404
56
from django.shortcuts import redirect, render
67
from django.urls import reverse, reverse_lazy
@@ -210,15 +211,26 @@ def get_context_data(self, **kwargs):
210211

211212
return context
212213

213-
def form_valid(self, form):
214-
form.save()
215-
216-
appointment = self.appointment
214+
def get_form_kwargs(self):
215+
kwargs = super().get_form_kwargs()
216+
kwargs["appointment"] = self.appointment
217+
kwargs["user"] = self.request.user
218+
return kwargs
217219

218-
if form.cleaned_data["decision"] == "continue":
219-
return redirect("mammograms:awaiting_images", pk=appointment.pk)
220-
else:
221-
return redirect("mammograms:appointment_cannot_go_ahead", pk=appointment.pk)
220+
def form_valid(self, form):
221+
try:
222+
with transaction.atomic():
223+
form.save()
224+
return redirect("mammograms:awaiting_images", pk=self.appointment.pk)
225+
except (IntegrityError, DatabaseError):
226+
messages.add_message(
227+
self.request,
228+
messages.WARNING,
229+
"Unable to complete all sections. Please try again.",
230+
)
231+
return redirect(
232+
"mammograms:record_medical_information", pk=self.appointment.pk
233+
)
222234

223235

224236
class AppointmentCannotGoAhead(InProgressAppointmentMixin, FormView):

manage_breast_screening/tests/system/clinical/test_reviewing_medical_information.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ def test_reviewing_each_medical_information_section(self):
2727
self.when_i_click_next_section(section)
2828
self.then_the_next_section_is_in_focus(next_section, anchor)
2929

30+
def test_complete_all_and_continue(self):
31+
self.given_i_am_logged_in_as_a_clinical_user()
32+
self.and_there_is_an_appointment()
33+
self.and_i_am_on_the_record_medical_information_page()
34+
35+
self.when_i_click_complete_all_and_continue()
36+
self.then_i_am_redirected_to_the_images_page()
37+
self.and_all_sections_are_reviewed()
38+
3039
def and_there_is_an_appointment(self):
3140
self.participant = ParticipantFactory()
3241
self.screening_episode = ScreeningEpisodeFactory(participant=self.participant)
@@ -76,6 +85,24 @@ def then_the_next_section_is_in_focus(self, section_heading: str, anchor: str):
7685
heading = self.page.get_by_role("heading", level=2, name=section_heading)
7786
expect(heading).to_be_in_viewport()
7887

88+
def when_i_click_complete_all_and_continue(self):
89+
button = self.page.get_by_role("button", name="Complete all and continue")
90+
button.click()
91+
92+
def then_i_am_redirected_to_the_images_page(self):
93+
self.expect_url("mammograms:awaiting_images", pk=self.appointment.pk)
94+
95+
def and_all_sections_are_reviewed(self):
96+
self.page.goto(
97+
self.live_server_url
98+
+ reverse(
99+
"mammograms:record_medical_information",
100+
kwargs={"pk": self.appointment.pk},
101+
)
102+
)
103+
for section_heading, _, _ in self._medical_information_sections():
104+
self.then_section_has_reviewed_tag(section_heading)
105+
79106
def _medical_information_sections(self):
80107
return [
81108
("Mammogram history", "symptoms", "Symptoms"),

0 commit comments

Comments
 (0)