Skip to content

Commit f9a69d0

Browse files
committed
code review changes for breast augmentation
1 parent 4122114 commit f9a69d0

File tree

7 files changed

+87
-49
lines changed

7 files changed

+87
-49
lines changed

manage_breast_screening/data/east_tester_one_week_ago_clinic_data.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ clinic:
135135
- OTHER_AUGMENTATION
136136
- left_breast_procedures:
137137
- NO_PROCEDURES
138+
- implants_have_been_removed: False
138139
- id: 848c9ecf-94af-45f7-b072-29ba1f82d24b
139140
duration_in_minutes: 8
140141
starts_at_time: 09:32

manage_breast_screening/mammograms/forms/breast_augmentation_history_form.py

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

33
from django import forms
44
from django.db.models import TextChoices
5+
from django.forms import Form
56
from django.forms.widgets import Textarea
67

78
from manage_breast_screening.core.services.auditor import Auditor
@@ -12,7 +13,6 @@
1213
from manage_breast_screening.nhsuk_forms.fields.choice_fields import (
1314
MultipleChoiceField,
1415
)
15-
from manage_breast_screening.nhsuk_forms.forms import FormWithConditionalFields
1616
from manage_breast_screening.participants.models.breast_augmentation_history_item import (
1717
BreastAugmentationHistoryItem,
1818
)
@@ -22,7 +22,7 @@ class RemovalStatusChoices(TextChoices):
2222
HAS_BEEN_REMOVED = "HAS_BEEN_REMOVED", "Implants have been removed"
2323

2424

25-
class BreastAugmentationHistoryForm(FormWithConditionalFields):
25+
class BreastAugmentationHistoryForm(Form):
2626
right_breast_procedures = MultipleChoiceField(
2727
label="Right breast",
2828
label_classes="nhsuk-fieldset__legend--s",
@@ -90,24 +90,20 @@ def __init__(self, *args, participant, **kwargs):
9090
min_value=min_year,
9191
max_value=max_year,
9292
error_messages={
93-
"required": "Enter the year the implant was removed",
9493
"min_value": year_outside_range_error_message,
9594
"max_value": year_outside_range_error_message,
9695
"invalid": year_invalid_format_error_message,
9796
},
9897
)
9998

100-
self.given_field_value(
101-
"removal_status", RemovalStatusChoices.HAS_BEEN_REMOVED
102-
).require_field("removal_year")
103-
10499
def model_values(self):
105100
return dict(
106101
left_breast_procedures=self.cleaned_data.get("left_breast_procedures", []),
107102
right_breast_procedures=self.cleaned_data.get(
108103
"right_breast_procedures", []
109104
),
110-
removal_year=self.cleaned_data.get("removal_year", ""),
105+
implants_have_been_removed=_have_implants_been_removed(self.cleaned_data),
106+
removal_year=self.cleaned_data.get("removal_year"),
111107
procedure_year=self.cleaned_data.get("procedure_year", ""),
112108
additional_details=self.cleaned_data.get("additional_details", ""),
113109
)
@@ -129,6 +125,11 @@ def clean(self):
129125
cleaned_data = super().clean()
130126
procedure_year = cleaned_data.get("procedure_year")
131127
removal_year = cleaned_data.get("removal_year")
128+
129+
if removal_year and not _have_implants_been_removed(cleaned_data):
130+
removal_year = None
131+
cleaned_data["removal_year"] = removal_year
132+
132133
if procedure_year and removal_year and procedure_year > removal_year:
133134
self.add_error(
134135
"removal_year",
@@ -139,3 +140,7 @@ def clean(self):
139140
)
140141

141142
return cleaned_data
143+
144+
145+
def _have_implants_been_removed(data):
146+
return RemovalStatusChoices.HAS_BEEN_REMOVED in data.get("removal_status", [])

manage_breast_screening/mammograms/tests/forms/test_breast_augmentation_history_form.py

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ def test_removal_year_invalid_format(self, clinical_user):
156156
assert form.errors == {
157157
"removal_year": [
158158
"Enter year as a number.",
159-
"Enter the year the implant was removed",
160159
]
161160
}
162161

@@ -244,7 +243,6 @@ def test_removal_year_outside_range(self, clinical_user, removal_year):
244243
assert form.errors == {
245244
"removal_year": [
246245
year_outside_range_error_message,
247-
"Enter the year the implant was removed",
248246
]
249247
}
250248

@@ -288,34 +286,6 @@ def test_removal_year_before_procedure_year(
288286
"removal_year": ["Year removed cannot be before year of procedure"]
289287
}
290288

291-
def test_has_been_removed_without_removal_date(self, clinical_user):
292-
appointment = AppointmentFactory()
293-
request = RequestFactory().get("/test-form")
294-
request.user = clinical_user
295-
296-
form = BreastAugmentationHistoryForm(
297-
QueryDict(
298-
urlencode(
299-
{
300-
"right_breast_procedures": [
301-
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
302-
],
303-
"left_breast_procedures": [
304-
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
305-
],
306-
"removal_status": RemovalStatusChoices.HAS_BEEN_REMOVED,
307-
},
308-
doseq=True,
309-
),
310-
),
311-
participant=appointment.participant,
312-
)
313-
314-
assert not form.is_valid()
315-
assert form.errors == {
316-
"removal_year": ["Enter the year the implant was removed"]
317-
}
318-
319289
@pytest.mark.parametrize(
320290
"data",
321291
[
@@ -387,6 +357,15 @@ def test_has_been_removed_without_removal_date(self, clinical_user):
387357
"removal_status": RemovalStatusChoices.HAS_BEEN_REMOVED,
388358
"removal_year": 2015,
389359
},
360+
{
361+
"right_breast_procedures": [
362+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
363+
],
364+
"left_breast_procedures": [
365+
BreastAugmentationHistoryItem.Procedure.BREAST_IMPLANTS
366+
],
367+
"removal_status": RemovalStatusChoices.HAS_BEEN_REMOVED,
368+
},
390369
],
391370
)
392371
def test_success(self, clinical_user, data):
@@ -407,5 +386,8 @@ def test_success(self, clinical_user, data):
407386
assert obj.left_breast_procedures == data.get("left_breast_procedures")
408387
assert obj.right_breast_procedures == data.get("right_breast_procedures")
409388
assert obj.procedure_year == data.get("procedure_year", None)
389+
assert obj.implants_have_been_removed == (
390+
RemovalStatusChoices.HAS_BEEN_REMOVED in data.get("removal_status", [])
391+
)
410392
assert obj.removal_year == data.get("removal_year", None)
411393
assert obj.additional_details == data.get("additional_details", "")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Generated by Django 5.2.8 on 2025-11-19 17:29
2+
3+
import django.contrib.postgres.fields
4+
import manage_breast_screening.nhsuk_forms.validators
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('participants', '0042_alter_implantedmedicaldevicehistoryitem_device'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='breastaugmentationhistoryitem',
17+
name='implants_have_been_removed',
18+
field=models.BooleanField(),
19+
),
20+
migrations.AlterField(
21+
model_name='breastaugmentationhistoryitem',
22+
name='left_breast_procedures',
23+
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('BREAST_IMPLANTS', 'Breast implants (silicone or saline)'), ('OTHER_AUGMENTATION', 'Other augmentation'), ('NO_PROCEDURES', 'No procedures')]), default=list, size=None, validators=[manage_breast_screening.nhsuk_forms.validators.ExcludesOtherOptionsValidator('NO_PROCEDURES', 'No procedures')]),
24+
),
25+
migrations.AlterField(
26+
model_name='breastaugmentationhistoryitem',
27+
name='procedure_year',
28+
field=models.IntegerField(blank=True, null=True),
29+
),
30+
migrations.AlterField(
31+
model_name='breastaugmentationhistoryitem',
32+
name='removal_year',
33+
field=models.IntegerField(blank=True, null=True),
34+
),
35+
migrations.AlterField(
36+
model_name='breastaugmentationhistoryitem',
37+
name='right_breast_procedures',
38+
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('BREAST_IMPLANTS', 'Breast implants (silicone or saline)'), ('OTHER_AUGMENTATION', 'Other augmentation'), ('NO_PROCEDURES', 'No procedures')]), default=list, size=None, validators=[manage_breast_screening.nhsuk_forms.validators.ExcludesOtherOptionsValidator('NO_PROCEDURES', 'No procedures')]),
39+
),
40+
]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0042_alter_implantedmedicaldevicehistoryitem_device
1+
0043_alter_breastaugmentationhistoryitem_implants_have_been_removed_and_more

manage_breast_screening/participants/models/breast_augmentation_history_item.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from django.db import models
33

44
from manage_breast_screening.core.models import BaseModel
5+
from manage_breast_screening.nhsuk_forms.validators import ExcludesOtherOptionsValidator
56
from manage_breast_screening.participants.models.appointment import Appointment
67

78

@@ -20,18 +21,25 @@ class Procedure(models.TextChoices):
2021
on_delete=models.PROTECT,
2122
related_name="breast_augmentation_history_items",
2223
)
23-
# TODO should we be setting validators here to use ExcludesOtherOptionsValidator?
2424
right_breast_procedures = ArrayField(
25-
base_field=models.CharField(choices=Procedure), default=list
25+
base_field=models.CharField(choices=Procedure),
26+
default=list,
27+
validators=[
28+
ExcludesOtherOptionsValidator(
29+
Procedure.NO_PROCEDURES.value, Procedure.NO_PROCEDURES.label
30+
)
31+
],
2632
)
27-
# TODO should we be setting validators here to use ExcludesOtherOptionsValidator?
2833
left_breast_procedures = ArrayField(
29-
base_field=models.CharField(choices=Procedure), default=list
34+
base_field=models.CharField(choices=Procedure),
35+
default=list,
36+
validators=[
37+
ExcludesOtherOptionsValidator(
38+
Procedure.NO_PROCEDURES.value, Procedure.NO_PROCEDURES.label
39+
)
40+
],
3041
)
31-
# TODO should procedure_year be blank=True as well as null=True?
32-
procedure_year = models.IntegerField(null=True)
33-
# TODO should we remove implants_have_been_removed? could instead rely on removal_year being set or not?
34-
implants_have_been_removed = models.BooleanField(default=False)
35-
# TODO should removal_year be blank=True as well as null=True?
36-
removal_year = models.IntegerField(null=True)
42+
procedure_year = models.IntegerField(null=True, blank=True)
43+
implants_have_been_removed = models.BooleanField()
44+
removal_year = models.IntegerField(null=True, blank=True)
3745
additional_details = models.TextField(null=False, blank=True, default="")

manage_breast_screening/participants/tests/factories.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class Meta:
195195
surgery_reason = MastectomyOrLumpectomyHistoryItem.SurgeryReason.OTHER_REASON
196196
additional_details = ""
197197

198+
198199
class CystHistoryItemFactory(DjangoModelFactory):
199200
class Meta:
200201
model = models.CystHistoryItem
@@ -222,6 +223,7 @@ class Meta:
222223
left_breast_procedures = [
223224
models.BreastAugmentationHistoryItem.Procedure.NO_PROCEDURES
224225
]
226+
implants_have_been_removed = False
225227

226228

227229
class OtherProcedureHistoryItemFactory(DjangoModelFactory):

0 commit comments

Comments
 (0)