Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)


class ImplantedMedicalDeviceHistoryForm(FormWithConditionalFields):
class ImplantedMedicalDeviceHistoryBaseForm(FormWithConditionalFields):
def __init__(self, *args, participant, **kwargs):
super().__init__(*args, **kwargs)

Expand Down Expand Up @@ -74,21 +74,6 @@ def model_values(self):
additional_details=self.cleaned_data.get("additional_details", ""),
)

def create(self, appointment, request):
auditor = Auditor.from_request(request)
field_values = self.model_values()

implanted_medical_device_history = (
appointment.implanted_medical_device_history_items.create(
appointment=appointment,
**field_values,
)
)

auditor.audit_create(implanted_medical_device_history)

return implanted_medical_device_history

def full_clean(self):
# if a removal_year is provided then remove it if device_has_been_removed is False
if self.data.get("removal_year") and not self.data.get(
Expand All @@ -114,3 +99,54 @@ def clean(self):
code="required",
),
)


class ImplantedMedicalDeviceHistoryForm(ImplantedMedicalDeviceHistoryBaseForm):
def create(self, appointment, request):
auditor = Auditor.from_request(request)
field_values = self.model_values()

implanted_medical_device_history = (
appointment.implanted_medical_device_history_items.create(
appointment=appointment,
**field_values,
)
)

auditor.audit_create(implanted_medical_device_history)

return implanted_medical_device_history


class ImplantedMedicalDeviceHistoryUpdateForm(ImplantedMedicalDeviceHistoryBaseForm):
def __init__(self, instance, *args, **kwargs):
self.instance = instance

kwargs["participant"] = instance.participant
kwargs["initial"] = {
"device": instance.device,
"other_medical_device_details": instance.other_medical_device_details,
"device_has_been_removed": instance.device_has_been_removed,
"removal_year": instance.removal_year,
"procedure_year": instance.procedure_year,
"additional_details": instance.additional_details,
}

super().__init__(*args, **kwargs)

def update(self, request):
self.instance.device = self.cleaned_data["device"]
self.instance.other_medical_device_details = self.cleaned_data[
"other_medical_device_details"
]
self.instance.device_has_been_removed = self.cleaned_data[
"device_has_been_removed"
]
self.instance.removal_year = self.cleaned_data["removal_year"]
self.instance.procedure_year = self.cleaned_data["procedure_year"]
self.instance.additional_details = self.cleaned_data["additional_details"]
self.instance.save()

Auditor.from_request(request).audit_update(self.instance)

return self.instance
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@

{% set implanted_medical_device_history_html %}
{% for presented_item in presenter.implanted_medical_device_history %}
<a style="float: right" class="nhsuk-link nhsuk-link--no-visited-state" href="{{ presented_item.change_link.href}}">
{{ presented_item.change_link.text }}<span class="nhsuk-u-visually-hidden">{{ presented_item.change_link.visually_hidden_text }}</span>
</a><br>
{{ summaryList(presented_item.summary_list_params) }}
{% endfor %}
<a href="{{ presenter.add_implanted_medical_device_history_link.href }}" class="nhsuk-link nhsuk-link--no-visited-state">{{ presenter.add_implanted_medical_device_history_link.text }}</a><br>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from django.urls import reverse

from manage_breast_screening.core.template_helpers import (
nl2br,
)


class ImplantedMedicalDeviceHistoryItemPresenter:
def __init__(self, implanted_medical_device_history_item):
def __init__(self, implanted_medical_device_history_item, counter=None):
self._item = implanted_medical_device_history_item

# If there are more than one of these items, we add a counter to the
# visually hidden text
self.counter = counter

self.device = self._item.get_device_display()
self.other_medical_device_details = (
self._item.other_medical_device_details or "N/A"
Expand Down Expand Up @@ -48,3 +54,21 @@ def summary_list_params(self):
},
],
}

@property
def change_link(self):
return {
"href": reverse(
"mammograms:change_implanted_medical_device_history_item",
kwargs={
"pk": self._item.appointment_id,
"history_item_pk": self._item.pk,
},
),
"text": "Change",
"visually_hidden_text": (
f" item {self.counter}"
if self.counter
else " implanted medical device item"
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,22 @@ def __init__(self, appointment):
MastectomyOrLumpectomyHistoryItemPresenter(item)
for item in appointment.mastectomy_or_lumpectomy_history_items.all()
]
self.implanted_medical_device_history = [
ImplantedMedicalDeviceHistoryItemPresenter(item)
for item in appointment.implanted_medical_device_history_items.all()
]

implanted_medical_device_history = list(
appointment.implanted_medical_device_history_items.all()
)
if len(implanted_medical_device_history) == 1:
self.implanted_medical_device_history = [
ImplantedMedicalDeviceHistoryItemPresenter(
implanted_medical_device_history[0]
)
]
else:
self.implanted_medical_device_history = [
ImplantedMedicalDeviceHistoryItemPresenter(item, counter=counter)
for counter, item in enumerate(implanted_medical_device_history, 1)
]

self.breast_augmentation_history = [
BreastAugmentationHistoryItemPresenter(item)
for item in appointment.breast_augmentation_history_items.all()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,37 @@
from manage_breast_screening.participants.models.implanted_medical_device_history_item import (
ImplantedMedicalDeviceHistoryItem,
)
from manage_breast_screening.participants.tests.factories import AppointmentFactory
from manage_breast_screening.participants.tests.factories import (
AppointmentFactory,
ImplantedMedicalDeviceHistoryItemFactory,
)

from ...forms.implanted_medical_device_history_form import (
ImplantedMedicalDeviceHistoryForm,
ImplantedMedicalDeviceHistoryUpdateForm,
)


@pytest.fixture
def dummy_request(clinical_user):
request = RequestFactory().get("/test-form")
request.user = clinical_user
return request


@pytest.mark.django_db
class TestImplantedMedicalDeviceHistoryForm:
def test_no_data(self, clinical_user):
def test_no_data(self):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(), participant=appointment.participant
)

assert not form.is_valid()
assert form.errors == {"device": ["Select the device type"]}

def test_other_device_without_information(self, clinical_user):
def test_other_device_without_information(self):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand All @@ -50,10 +56,8 @@ def test_other_device_without_information(self, clinical_user):
"other_medical_device_details": ["Provide details of the device"]
}

def test_procedure_year_invalid_format(self, clinical_user):
def test_procedure_year_invalid_format(self):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand All @@ -70,10 +74,8 @@ def test_procedure_year_invalid_format(self, clinical_user):
assert not form.is_valid()
assert form.errors == {"procedure_year": ["Enter a whole number."]}

def test_removal_year_invalid_format(self, clinical_user):
def test_removal_year_invalid_format(self):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand Down Expand Up @@ -105,13 +107,15 @@ def test_removal_year_invalid_format(self, clinical_user):
3000,
],
)
def test_procedure_year_outside_range(self, clinical_user, procedure_year):
def test_procedure_year_outside_range(self, procedure_year):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

max_year = datetime.date.today().year
min_year = max_year - 80
year_outside_range_error_message = (
self.create_year_outside_range_error_messsage(procedure_year)
(f"Year must be {max_year} or earlier")
if procedure_year > max_year
else (f"Year must be {min_year} or later")
)
form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand All @@ -138,13 +142,15 @@ def test_procedure_year_outside_range(self, clinical_user, procedure_year):
3000,
],
)
def test_removal_year_outside_range(self, clinical_user, removal_year):
def test_removal_year_outside_range(self, removal_year):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

max_year = datetime.date.today().year
min_year = max_year - 80
year_outside_range_error_message = (
self.create_year_outside_range_error_messsage(removal_year)
(f"Year must be {max_year} or earlier")
if removal_year > max_year
else (f"Year must be {min_year} or later")
)
form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand Down Expand Up @@ -174,12 +180,8 @@ def test_removal_year_outside_range(self, clinical_user, removal_year):
(datetime.date.today().year - 79, datetime.date.today().year - 80),
],
)
def test_removal_year_before_procedure_year(
self, clinical_user, procedure_year, removal_year
):
def test_removal_year_before_procedure_year(self, procedure_year, removal_year):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand All @@ -200,10 +202,8 @@ def test_removal_year_before_procedure_year(
"removal_year": ["Year removed cannot be before year of procedure"]
}

def test_removal_year_when_not_removed(self, clinical_user):
def test_removal_year_when_not_removed(self, dummy_request):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(
Expand All @@ -229,7 +229,7 @@ def test_removal_year_when_not_removed(self, clinical_user):

assert form.is_valid()

obj = form.create(appointment=appointment, request=request)
obj = form.create(appointment=appointment, request=dummy_request)

obj.refresh_from_db()
assert obj.appointment == appointment
Expand Down Expand Up @@ -273,10 +273,8 @@ def test_removal_year_when_not_removed(self, clinical_user):
},
],
)
def test_success(self, clinical_user, data):
def test_success(self, data, dummy_request):
appointment = AppointmentFactory()
request = RequestFactory().get("/test-form")
request.user = clinical_user

form = ImplantedMedicalDeviceHistoryForm(
QueryDict(urlencode(data, doseq=True)),
Expand All @@ -285,7 +283,7 @@ def test_success(self, clinical_user, data):

assert form.is_valid()

obj = form.create(appointment=appointment, request=request)
obj = form.create(appointment=appointment, request=dummy_request)

assert obj.appointment == appointment
assert obj.device == data.get("device")
Expand All @@ -296,11 +294,52 @@ def test_success(self, clinical_user, data):
assert obj.removal_year == data.get("removal_year", None)
assert obj.additional_details == data.get("additional_details", "")

def create_year_outside_range_error_messsage(self, request_year):
max_year = datetime.date.today().year
min_year = max_year - 80
return (
(f"Year must be {max_year} or earlier")
if request_year > max_year
else (f"Year must be {min_year} or later")

@pytest.mark.django_db
class TestImplantedMedicalDeviceHistoryUpdateForm:
@pytest.fixture
def instance(self):
return ImplantedMedicalDeviceHistoryItemFactory(
device=ImplantedMedicalDeviceHistoryItem.Device.CARDIAC_DEVICE
)

def test_no_data(self, instance):
form = ImplantedMedicalDeviceHistoryUpdateForm(instance, QueryDict())

assert not form.is_valid()
assert form.errors == {"device": ["Select the device type"]}

@pytest.mark.parametrize(
"data",
[
{
"device": ImplantedMedicalDeviceHistoryItem.Device.HICKMAN_LINE,
},
{
"device": ImplantedMedicalDeviceHistoryItem.Device.OTHER_MEDICAL_DEVICE,
"other_medical_device_details": "Some details about the device",
"procedure_year": 2010,
"device_has_been_removed": True,
"removal_year": 2015,
"additional_details": "Some additional details",
},
],
)
def test_success(self, instance, data, dummy_request):
form = ImplantedMedicalDeviceHistoryUpdateForm(
instance,
QueryDict(urlencode(data, doseq=True)),
)

assert form.is_valid()

obj = form.update(request=dummy_request)

assert obj.appointment == instance.appointment
assert obj.device == data.get("device")
assert obj.other_medical_device_details == data.get(
"other_medical_device_details", ""
)
assert obj.procedure_year == data.get("procedure_year", None)
assert obj.removal_year == data.get("removal_year", None)
assert obj.additional_details == data.get("additional_details", "")
Loading