Skip to content

Commit dc6e9f9

Browse files
authored
Merge pull request #777 from NHSDigital/DTOSS-11524-update-implants-and-augmentation
Medical history - update implants and augmentation
2 parents fb844a3 + 3d4dea8 commit dc6e9f9

13 files changed

+444
-87
lines changed

manage_breast_screening/mammograms/forms/breast_augmentation_history_form.py

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
CharField,
99
YearField,
1010
)
11-
from manage_breast_screening.nhsuk_forms.fields.choice_fields import (
12-
MultipleChoiceField,
13-
)
11+
from manage_breast_screening.nhsuk_forms.fields.choice_fields import MultipleChoiceField
1412
from manage_breast_screening.participants.models.breast_augmentation_history_item import (
1513
BreastAugmentationHistoryItem,
1614
)
1715

1816

19-
class BreastAugmentationHistoryForm(Form):
17+
class BreastAugmentationHistoryBaseForm(Form):
2018
right_breast_procedures = MultipleChoiceField(
2119
label="Right breast",
2220
label_classes="nhsuk-fieldset__legend--s",
@@ -80,19 +78,6 @@ def model_values(self):
8078
additional_details=self.cleaned_data.get("additional_details", ""),
8179
)
8280

83-
def create(self, appointment, request):
84-
auditor = Auditor.from_request(request)
85-
field_values = self.model_values()
86-
breast_augmentation_history = (
87-
appointment.breast_augmentation_history_items.create(
88-
appointment=appointment,
89-
**field_values,
90-
)
91-
)
92-
auditor.audit_create(breast_augmentation_history)
93-
94-
return breast_augmentation_history
95-
9681
def full_clean(self):
9782
# if a removal_year is provided then remove it if implants_have_been_removed is False
9883
if self.data.get("removal_year") and not self.data.get(
@@ -121,3 +106,50 @@ def clean(self):
121106
)
122107

123108
return cleaned_data
109+
110+
111+
class BreastAugmentationHistoryForm(BreastAugmentationHistoryBaseForm):
112+
def create(self, appointment, request):
113+
auditor = Auditor.from_request(request)
114+
field_values = self.model_values()
115+
breast_augmentation_history = (
116+
appointment.breast_augmentation_history_items.create(
117+
appointment=appointment,
118+
**field_values,
119+
)
120+
)
121+
auditor.audit_create(breast_augmentation_history)
122+
123+
return breast_augmentation_history
124+
125+
126+
class BreastAugmentationHistoryUpdateForm(BreastAugmentationHistoryBaseForm):
127+
def __init__(self, instance, *args, **kwargs):
128+
self.instance = instance
129+
130+
kwargs["initial"] = {
131+
"right_breast_procedures": instance.right_breast_procedures,
132+
"left_breast_procedures": instance.left_breast_procedures,
133+
"procedure_year": instance.procedure_year,
134+
"implants_have_been_removed": instance.implants_have_been_removed,
135+
"removal_year": instance.removal_year,
136+
"additional_details": instance.additional_details,
137+
}
138+
139+
super().__init__(*args, **kwargs)
140+
141+
def update(self, request):
142+
# fmt: off
143+
self.instance.right_breast_procedures = self.cleaned_data["right_breast_procedures"]
144+
self.instance.left_breast_procedures = self.cleaned_data["left_breast_procedures"]
145+
self.instance.procedure_year = self.cleaned_data["procedure_year"]
146+
self.instance.implants_have_been_removed = self.cleaned_data["implants_have_been_removed"]
147+
self.instance.removal_year = self.cleaned_data["removal_year"]
148+
self.instance.additional_details = self.cleaned_data["additional_details"]
149+
# fmt: on
150+
151+
self.instance.save()
152+
153+
Auditor.from_request(request).audit_update(self.instance)
154+
155+
return self.instance

manage_breast_screening/mammograms/jinja2/mammograms/record_medical_information.jinja

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@
6565

6666
{% set breast_augmentation_history_html %}
6767
{% for presented_item in presenter.breast_augmentation_history %}
68+
<a style="float: right" class="nhsuk-link nhsuk-link--no-visited-state" href="{{ presented_item.change_link.href}}">
69+
{{ presented_item.change_link.text }}<span class="nhsuk-u-visually-hidden">{{ presented_item.change_link.visually_hidden_text }}</span>
70+
</a><br>
6871
{{ summaryList(presented_item.summary_list_params) }}
6972
{% endfor %}
7073
<a href="{{ presenter.add_breast_augmentation_history_link.href }}" class="nhsuk-link nhsuk-link--no-visited-state">{{ presenter.add_breast_augmentation_history_link.text }}</a><br>

manage_breast_screening/mammograms/presenters/breast_augmentation_history_item_presenter.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
from django.urls import reverse
2+
13
from manage_breast_screening.core.template_helpers import multiline_content, nl2br
24
from manage_breast_screening.participants.models.breast_augmentation_history_item import (
35
BreastAugmentationHistoryItem,
46
)
57

68

79
class BreastAugmentationHistoryItemPresenter:
8-
def __init__(self, breast_augmentation_history_item):
10+
def __init__(self, breast_augmentation_history_item, counter=None):
911
self._item = breast_augmentation_history_item
12+
self.counter = counter
1013

1114
self.right_breast_procedures = self._format_multiple_choices(
1215
self._item.right_breast_procedures, BreastAugmentationHistoryItem.Procedure
@@ -57,3 +60,21 @@ def summary_list_params(self):
5760

5861
def _format_multiple_choices(self, choices, ChoiceClass):
5962
return ", ".join(ChoiceClass(choice).label for choice in choices)
63+
64+
@property
65+
def change_link(self):
66+
return {
67+
"href": reverse(
68+
"mammograms:change_breast_augmentation_history_item",
69+
kwargs={
70+
"pk": self._item.appointment_id,
71+
"history_item_pk": self._item.pk,
72+
},
73+
),
74+
"text": "Change",
75+
"visually_hidden_text": (
76+
f" breast implants or augmentation item {self.counter}"
77+
if self.counter
78+
else " breast implants or augmentation item"
79+
),
80+
}

manage_breast_screening/mammograms/presenters/medical_information_presenter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ def __init__(self, appointment):
5151
ImplantedMedicalDeviceHistoryItemPresenter,
5252
)
5353

54-
self.breast_augmentation_history = [
55-
BreastAugmentationHistoryItemPresenter(item)
56-
for item in appointment.breast_augmentation_history_items.all()
57-
]
54+
self.breast_augmentation_history = self._present_items(
55+
appointment.breast_augmentation_history_items.all(),
56+
BreastAugmentationHistoryItemPresenter,
57+
)
5858
self.other_procedure_history = [
5959
OtherProcedureHistoryItemPresenter(item)
6060
for item in appointment.other_procedure_history_items.all()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pytest
2+
from django.test import RequestFactory
3+
4+
5+
@pytest.fixture
6+
def dummy_request(clinical_user):
7+
request = RequestFactory().get("/test-form")
8+
request.user = clinical_user
9+
return request

manage_breast_screening/mammograms/tests/forms/test_breast_augmentation_history_form.py

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99
from manage_breast_screening.participants.models.breast_augmentation_history_item import (
1010
BreastAugmentationHistoryItem,
1111
)
12-
from manage_breast_screening.participants.tests.factories import AppointmentFactory
12+
from manage_breast_screening.participants.tests.factories import (
13+
AppointmentFactory,
14+
BreastAugmentationHistoryItemFactory,
15+
)
1316

14-
from ...forms.breast_augmentation_history_form import BreastAugmentationHistoryForm
17+
from ...forms.breast_augmentation_history_form import (
18+
BreastAugmentationHistoryForm,
19+
BreastAugmentationHistoryUpdateForm,
20+
)
1521

1622

1723
@pytest.mark.django_db
@@ -432,3 +438,77 @@ def test_success(self, clinical_user, data):
432438
assert obj.implants_have_been_removed == ("implants_have_been_removed" in data)
433439
assert obj.removal_year == data.get("removal_year", None)
434440
assert obj.additional_details == data.get("additional_details", "")
441+
442+
443+
@pytest.mark.django_db
444+
class TestBreastAugmentationHistoryUpdateForm:
445+
@pytest.fixture
446+
def instance(self):
447+
return BreastAugmentationHistoryItemFactory(
448+
right_breast_procedures=[
449+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
450+
],
451+
left_breast_procedures=[
452+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
453+
],
454+
procedure_year=2000,
455+
implants_have_been_removed=False,
456+
)
457+
458+
def test_no_data(self, instance):
459+
form = BreastAugmentationHistoryUpdateForm(instance, QueryDict())
460+
461+
assert not form.is_valid()
462+
assert form.errors == {
463+
"left_breast_procedures": ["Select procedures for the left breast"],
464+
"right_breast_procedures": ["Select procedures for the right breast"],
465+
}
466+
467+
def test_initial(self, instance):
468+
form = BreastAugmentationHistoryUpdateForm(instance, QueryDict())
469+
assert form.initial == {
470+
"right_breast_procedures": [
471+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
472+
],
473+
"left_breast_procedures": [
474+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
475+
],
476+
"procedure_year": 2000,
477+
"removal_year": None,
478+
"implants_have_been_removed": False,
479+
"additional_details": "",
480+
}
481+
482+
def test_success(self, instance, dummy_request):
483+
form = BreastAugmentationHistoryUpdateForm(
484+
instance,
485+
QueryDict(
486+
urlencode(
487+
{
488+
"right_breast_procedures": [
489+
BreastAugmentationHistoryItem.Procedure.OTHER_AUGMENTATION
490+
],
491+
"left_breast_procedures": [
492+
BreastAugmentationHistoryItem.Procedure.NO_PROCEDURES
493+
],
494+
"procedure_year": "2001",
495+
"removal_year": "",
496+
"additional_details": "abc",
497+
},
498+
doseq=True,
499+
)
500+
),
501+
)
502+
503+
assert form.is_valid()
504+
505+
obj = form.update(request=dummy_request)
506+
assert obj.right_breast_procedures == [
507+
BreastAugmentationHistoryItem.Procedure.OTHER_AUGMENTATION
508+
]
509+
assert obj.left_breast_procedures == [
510+
BreastAugmentationHistoryItem.Procedure.NO_PROCEDURES
511+
]
512+
assert obj.procedure_year == 2001
513+
assert obj.removal_year is None
514+
assert obj.additional_details == "abc"

manage_breast_screening/mammograms/tests/forms/test_cyst_history_form.py

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

33
import pytest
44
from django.http import QueryDict
5-
from django.test import RequestFactory
65

76
from manage_breast_screening.participants.models.cyst_history_item import (
87
CystHistoryItem,
@@ -15,13 +14,6 @@
1514
from ...forms.cyst_history_form import CystHistoryForm, CystHistoryUpdateForm
1615

1716

18-
@pytest.fixture
19-
def dummy_request(clinical_user):
20-
request = RequestFactory().get("/test-form")
21-
request.user = clinical_user
22-
return request
23-
24-
2517
@pytest.mark.django_db
2618
class TestCystHistoryForm:
2719
def test_no_data(self):

manage_breast_screening/mammograms/tests/presenters/test_breast_augmentation_history_item_presenter.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,23 @@ def test_single(self):
5959
},
6060
],
6161
}
62+
63+
def test_change_link(self):
64+
item = BreastAugmentationHistoryItemFactory.build()
65+
66+
presenter = BreastAugmentationHistoryItemPresenter(item)
67+
assert presenter.change_link == {
68+
"href": f"/mammograms/{item.appointment_id}/record-medical-information/breast-augmentation-history/{item.pk}",
69+
"text": "Change",
70+
"visually_hidden_text": " breast implants or augmentation item",
71+
}
72+
73+
def test_change_link_with_counter(self):
74+
item = BreastAugmentationHistoryItemFactory.build()
75+
76+
presenter = BreastAugmentationHistoryItemPresenter(item, counter=2)
77+
assert presenter.change_link == {
78+
"href": f"/mammograms/{item.appointment_id}/record-medical-information/breast-augmentation-history/{item.pk}",
79+
"text": "Change",
80+
"visually_hidden_text": " breast implants or augmentation item 2",
81+
}

manage_breast_screening/mammograms/tests/views/test_breast_augmentation_history_view.py renamed to manage_breast_screening/mammograms/tests/views/test_breast_augmentation_history_views.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
from urllib.parse import urlencode
2+
13
import pytest
24
from django.contrib import messages
5+
from django.http import QueryDict
36
from django.urls import reverse
47
from pytest_django.asserts import assertInHTML, assertMessages, assertRedirects
58

@@ -8,6 +11,7 @@
811
)
912
from manage_breast_screening.participants.tests.factories import (
1013
AppointmentFactory,
14+
BreastAugmentationHistoryItemFactory,
1115
)
1216

1317

@@ -77,3 +81,70 @@ def test_invalid_post_renders_response_with_errors(self, clinical_user_client):
7781
""",
7882
response.text,
7983
)
84+
85+
86+
@pytest.mark.django_db
87+
class TestChangeBreastAugmentationHistoryView:
88+
@pytest.fixture
89+
def appointment(self, clinical_user_client):
90+
return AppointmentFactory.create(
91+
clinic_slot__clinic__setting__provider=clinical_user_client.current_provider
92+
)
93+
94+
@pytest.fixture
95+
def history_item(self, appointment):
96+
return BreastAugmentationHistoryItemFactory.create(appointment=appointment)
97+
98+
def test_renders_response(self, clinical_user_client, history_item):
99+
response = clinical_user_client.http.get(
100+
reverse(
101+
"mammograms:change_breast_augmentation_history_item",
102+
kwargs={
103+
"pk": history_item.appointment_id,
104+
"history_item_pk": history_item.pk,
105+
},
106+
)
107+
)
108+
assert response.status_code == 200
109+
110+
def test_valid_post_redirects_to_appointment(
111+
self, clinical_user_client, history_item
112+
):
113+
response = clinical_user_client.http.post(
114+
reverse(
115+
"mammograms:change_breast_augmentation_history_item",
116+
kwargs={
117+
"pk": history_item.appointment_id,
118+
"history_item_pk": history_item.pk,
119+
},
120+
),
121+
QueryDict(
122+
urlencode(
123+
{
124+
"left_breast_procedures": [
125+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
126+
],
127+
"right_breast_procedures": [
128+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
129+
],
130+
},
131+
doseq=True,
132+
)
133+
),
134+
)
135+
assertRedirects(
136+
response,
137+
reverse(
138+
"mammograms:record_medical_information",
139+
kwargs={"pk": history_item.appointment_id},
140+
),
141+
)
142+
assertMessages(
143+
response,
144+
[
145+
messages.Message(
146+
level=messages.SUCCESS,
147+
message="Details of breast implants or augmentation updated",
148+
)
149+
],
150+
)

0 commit comments

Comments
 (0)