Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
from django.db.models import TextChoices
from django.forms import Textarea

from manage_breast_screening.core.services.auditor import Auditor
from manage_breast_screening.nhsuk_forms.fields.char_field import CharField
from manage_breast_screening.nhsuk_forms.fields.choice_fields import (
ChoiceField,
MultipleChoiceField,
)
from manage_breast_screening.nhsuk_forms.fields.integer_field import IntegerField
from manage_breast_screening.nhsuk_forms.forms import FormWithConditionalFields
from manage_breast_screening.participants.models.breast_cancer_history_item import (
BreastCancerHistoryItem,
)


class BreastCancerHistoryForm(FormWithConditionalFields):
class DiagnosisLocationChoices(TextChoices):
RIGHT_BREAST = "RIGHT_BREAST", "Right breast"
LEFT_BREAST = "LEFT_BREAST", "Left breast"
DONT_KNOW = "DONT_KNOW", "Don't know"

diagnosis_location = MultipleChoiceField(
label="In which breasts was cancer diagnosed?",
choices=DiagnosisLocationChoices,
error_messages={"required": "Select which breasts cancer was diagnosed in"},
exclusive_choices={DiagnosisLocationChoices.DONT_KNOW},
)
# todo: constrain min/max
diagnosis_year = IntegerField(
label="Year of diagnosis (optional)",
label_classes="nhsuk-label--m",
classes="nhsuk-input--width-4",
hint="Leave blank if unknown",
required=False,
)

right_breast_procedure = ChoiceField(
label="Right breast (or axilla)",
visually_hidden_label_prefix="What procedure have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Procedure,
error_messages={
"required": "Select which procedure they have had in the right breast"
},
)
left_breast_procedure = ChoiceField(
label="Left breast (or axilla)",
visually_hidden_label_prefix="What procedure have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Procedure,
error_messages={
"required": "Select which procedure they have had in the left breast"
},
)

right_breast_other_surgery = MultipleChoiceField(
label="Right breast (or axilla)",
visually_hidden_label_prefix="What other surgery have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Surgery,
exclusive_choices={BreastCancerHistoryItem.Surgery.NO_SURGERY},
error_messages={
"required": "Select any other surgery they have had in the right breast"
},
)
left_breast_other_surgery = MultipleChoiceField(
label="Left breast (or axilla)",
visually_hidden_label_prefix="What other surgery have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Surgery,
exclusive_choices={BreastCancerHistoryItem.Surgery.NO_SURGERY},
error_messages={
"required": "Select any other surgery they have had in the left breast"
},
)

right_breast_treatment = MultipleChoiceField(
label="Right breast (or axilla)",
visually_hidden_label_prefix="What treatment have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Treatment,
exclusive_choices={BreastCancerHistoryItem.Treatment.NO_RADIOTHERAPY},
error_messages={
"required": "Select what treatment they have had in the right breast"
},
)
left_breast_treatment = MultipleChoiceField(
label="Left breast (or axilla)",
visually_hidden_label_prefix="What treatment have they had in their ",
visually_hidden_label_suffix="?",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.Treatment,
exclusive_choices={BreastCancerHistoryItem.Treatment.NO_RADIOTHERAPY},
error_messages={
"required": "Select what treatment they have had in the left breast"
},
)

systemic_treatments = MultipleChoiceField(
visually_hidden_label_prefix="What treatment have they had that are ",
visually_hidden_label_suffix="?",
label="Systemic treatments",
label_classes="nhsuk-fieldset__legend--s",
choices=BreastCancerHistoryItem.SystemicTreatment,
exclusive_choices={
BreastCancerHistoryItem.SystemicTreatment.NO_SYSTEMIC_TREATMENTS
},
error_messages={"required": "Select what systemic treatments they have had"},
)
systemic_treatments_other_treatment_details = CharField(
label="Provide details",
required=False,
error_messages={"required": "Provide details of the other systemic treatment"},
)

intervention_location = ChoiceField(
label="Where did surgery and treatment take place?",
choices=BreastCancerHistoryItem.InterventionLocation,
error_messages={"required": "Select where surgery and treatment took place"},
)

def __init__(self, **kwargs):
super().__init__(**kwargs)

self.given_field_value(
"systemic_treatments", BreastCancerHistoryItem.SystemicTreatment.OTHER
).require_field("systemic_treatments_other_treatment_details")

for location_value in BreastCancerHistoryItem.InterventionLocation:
self.fields[f"intervention_location_details_{location_value.lower()}"] = (
CharField(
label="Provide details",
required=False,
error_messages={
"required": "Provide details about where the surgery and treatment took place"
},
)
)

self.fields["additional_details"] = CharField(
label="Additional details (optional)",
label_classes="nhsuk-label--m",
hint="Include any other relevant information about the treatment",
required=False,
widget=Textarea({"rows": 3}),
)

self.given_field("intervention_location").require_field_with_prefix(
"intervention_location_details"
)

def model_values(self):
match self.cleaned_data.get("diagnosis_location", []):
case [
self.DiagnosisLocationChoices.RIGHT_BREAST,
self.DiagnosisLocationChoices.LEFT_BREAST,
]:
diagnosis_location = (
BreastCancerHistoryItem.DiagnosisLocationChoices.BOTH_BREASTS.value
)
case [other]:
diagnosis_location = other

location_value = self.cleaned_data["intervention_location"]

return dict(
diagnosis_location=diagnosis_location,
diagnosis_year=self.cleaned_data.get("diagnosis_year"),
right_breast_procedure=self.cleaned_data.get("right_breast_procedure"),
left_breast_procedure=self.cleaned_data.get("left_breast_procedure"),
right_breast_other_surgery=self.cleaned_data.get(
"right_breast_other_surgery"
),
left_breast_other_surgery=self.cleaned_data.get(
"left_breast_other_surgery"
),
right_breast_treatment=self.cleaned_data.get("right_breast_treatment"),
left_breast_treatment=self.cleaned_data.get("left_breast_treatment"),
systemic_treatments=self.cleaned_data.get("systemic_treatments"),
systemic_treatments_other_treatment_details=self.cleaned_data.get(
"systemic_treatments_other_treatment_details"
),
intervention_location=location_value,
intervention_location_details=self.cleaned_data.get(
f"intervention_location_details_{location_value.lower()}"
),
additional_details=self.cleaned_data.get("additional_details"),
)

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

instance = appointment.breast_cancer_history_items.create(
**field_values,
)

auditor.audit_create(instance)

return instance
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{% extends "layout-form.jinja" %}
{% from "nhsuk/components/button/macro.jinja" import button %}
{% from "mammograms/medical_information/medical_history/forms/macros.jinja" import diagnosis_location_field %}

{% block form %}

{{ diagnosis_location_field(form.diagnosis_location) }}

{{ form.diagnosis_year.as_field_group() }}

{# H2 hidden from AT as it's included in the fieldset legend of each set of radios #}
<h2 aria-hidden="true">What procedure have they had?</h2>
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-one-half">
{% do form.right_breast_procedure.add_divider_after("MASTECTOMY_NO_TISSUE_REMAINING", "or") %}
{{ form.right_breast_procedure.as_field_group() }}
</div>
<div class="nhsuk-grid-column-one-half">
{% do form.left_breast_procedure.add_divider_after("MASTECTOMY_NO_TISSUE_REMAINING", "or") %}
{{ form.left_breast_procedure.as_field_group() }}
</div>
</div>

{# H2 hidden from AT as it's included in the fieldset legend of each set of checkboxes #}
<h2 aria-hidden="true">What other surgery have they had?</h2>

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-one-half">
{% do form.right_breast_other_surgery.add_divider_after("SYMMETRISATION", "or") %}
{{ form.right_breast_other_surgery.as_field_group() }}
</div>
<div class="nhsuk-grid-column-one-half">
{% do form.left_breast_other_surgery.add_divider_after("SYMMETRISATION", "or") %}
{{ form.left_breast_other_surgery.as_field_group() }}
</div>
</div>

{# H2 hidden from AT as it's included in the fieldset legend of each set of checkboxes #}
<h2 aria-hidden="true">What treatment have they had?</h2>

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-one-half">
{% do form.right_breast_treatment.add_divider_after("LYMPH_NODE_RADIOTHERAPY", "or") %}
{{ form.right_breast_treatment.as_field_group() }}
</div>
<div class="nhsuk-grid-column-one-half">
{% do form.left_breast_treatment.add_divider_after("LYMPH_NODE_RADIOTHERAPY", "or") %}
{{ form.left_breast_treatment.as_field_group() }}
</div>
</div>

{% do form.systemic_treatments.add_divider_after("OTHER", "or") %}
{{ form.systemic_treatments.as_field_group() }}

{{ form.intervention_location.as_field_group() }}

{{ form.additional_details.as_field_group() }}

<div class="nhsuk-button-group">
{{ button({
"text": "Save"
}) }}
</div>

{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{% from "nhsuk/components/checkboxes/macro.jinja" import checkboxes %}
{% from "nhsuk/components/fieldset/macro.jinja" import fieldset %}

{# A single field with its options arranged on a grid. #}
{# Taborder is left to right, top to bottom. #}
{# Error messages belong to the field as a whole so are displayed above the grid. #}
{% macro diagnosis_location_field(form_field) %}
<div class="nhsuk-form-group {%- if form_field.errors %} nhsuk-form-group--error{% endif %}">
{% call fieldset({
"legend": {
"text": form_field.label,
"classes": "nhsuk-fieldset__legend--m"
}
}) %}

{% if form_field.errors %}
<span class="nhsuk-error-message" id="{{ form_field.name }}-error">
<span class="nhsuk-u-visually-hidden">Error:</span> {{ form_field.errors | first }}
</span>
{% endif %}

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-one-half">
{{ checkboxes({
"name": form_field.name,
"values": form_field.value(),
"idPrefix": form_field.auto_id,
"formGroup": {
"classes": "nhsuk-u-margin-bottom-2"
},
"items": [
{
"value": "RIGHT_BREAST",
"text": "Right breast"
}
]
}) }}
</div>
<div class="nhsuk-grid-column-one-half">
{{ checkboxes({
"name": form_field.name,
"values": form_field.value(),
"idPrefix": form_field.auto_id ~ "_left",
"formGroup": {
"classes": "nhsuk-u-margin-bottom-2"
},
"items": [
{
"value": "LEFT_BREAST",
"text": "Left breast"
}
]
}) }}
</div>
</div>

{{ checkboxes({
"name": form_field.name,
"values": form_field.value(),
"idPrefix": form_field.auto_id ~ "_not_known",
"items": [
{
"divider": "or"
},
{
"value": "DONT_KNOW",
"text": "Does not know",
"exclusive": true
}
]
}) }}
{% endcall %}
</div>
{% endmacro %}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
{% for presented_item in presenter.breast_cancer_history %}
{{ summaryList(presented_item.summary_list_params) }}
{% endfor %}
<a href="{{ presenter.add_breast_cancer_history_link.href }}" class="nhsuk-link nhsuk-link--no-visited-state">{{ presenter.add_breast_cancer_history_link.text }}</a><br>
{% endset %}

{% set mastectomy_or_lumpectomy_history_html %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ def add_other_symptom_link(self):
),
}

@property
def add_breast_cancer_history_link(self):
url = reverse(
"mammograms:add_breast_cancer_history_item",
kwargs={"pk": self.appointment.pk},
)

return {
"href": url,
"text": ("Add breast cancer history"),
}

@property
def add_implanted_medical_device_history_link(self):
url = reverse(
Expand Down
Loading