1- import datetime
2-
31from django import forms
4- from django .db .models import TextChoices
52from django .forms .widgets import Textarea
63
74from manage_breast_screening .core .services .auditor import Auditor
85from manage_breast_screening .nhsuk_forms .fields import (
6+ BooleanField ,
97 CharField ,
108 ChoiceField ,
11- IntegerField ,
12- )
13- from manage_breast_screening .nhsuk_forms .fields .choice_fields import (
14- MultipleChoiceField ,
9+ YearField ,
1510)
1611from manage_breast_screening .nhsuk_forms .forms import FormWithConditionalFields
1712from manage_breast_screening .participants .models .implanted_medical_device_history_item import (
1813 ImplantedMedicalDeviceHistoryItem ,
1914)
2015
2116
22- class RemovalStatusChoices (TextChoices ):
23- HAS_BEEN_REMOVED = "HAS_BEEN_REMOVED" , "Implanted device has been removed"
24-
25-
2617class ImplantedMedicalDeviceHistoryForm (FormWithConditionalFields ):
18+ other_medical_device_details = CharField (
19+ required = False ,
20+ label = "Provide details" ,
21+ error_messages = {"required" : "Provide details of the device" },
22+ classes = "nhsuk-u-width-two-thirds" ,
23+ )
24+ procedure_year = YearField (
25+ hint = "Leave blank if unknown" ,
26+ required = False ,
27+ label = "Year of procedure (optional)" ,
28+ label_classes = "nhsuk-label--m" ,
29+ classes = "nhsuk-input--width-4" ,
30+ )
31+ device_has_been_removed = BooleanField (
32+ required = False ,
33+ label = "Implanted device has been removed" ,
34+ classes = "app-checkboxes" ,
35+ )
36+ removal_year = YearField (
37+ required = False ,
38+ label = "Year removed (if available)" ,
39+ classes = "nhsuk-input--width-4" ,
40+ )
41+ additional_details = CharField (
42+ hint = "Include any other relevant information about the device or procedure" ,
43+ required = False ,
44+ label = "Additional details (optional)" ,
45+ label_classes = "nhsuk-label--m" ,
46+ widget = Textarea (attrs = {"rows" : 4 }),
47+ max_words = 500 ,
48+ error_messages = {"max_words" : "Additional details must be 500 words or less" },
49+ )
50+
2751 def __init__ (self , * args , participant , ** kwargs ):
2852 super ().__init__ (* args , ** kwargs )
2953
30- # if entered, years should be between 80 years ago and this year
31- max_year = datetime .date .today ().year
32- min_year = max_year - 80
33- year_outside_range_error_message = (
34- f"Year should be between { min_year } and { max_year } ."
35- )
36- year_invalid_format_error_message = "Enter year as a number."
37-
3854 self .fields ["device" ] = ChoiceField (
3955 choices = ImplantedMedicalDeviceHistoryItem .Device ,
4056 label = f"What device does { participant .first_name } have?" ,
4157 error_messages = {"required" : "Select the device type" },
4258 )
43- self .fields ["other_medical_device_details" ] = CharField (
44- required = False ,
45- label = "Provide details" ,
46- error_messages = {"required" : "Provide details of the device" },
47- classes = "nhsuk-u-width-two-thirds" ,
48- )
49- self .fields ["procedure_year" ] = IntegerField (
50- hint = "Leave blank if unknown" ,
51- required = False ,
52- label = "Year of procedure (optional)" ,
53- label_classes = "nhsuk-label--m" ,
54- classes = "nhsuk-input--width-4" ,
55- min_value = min_year ,
56- max_value = max_year ,
57- error_messages = {
58- "min_value" : year_outside_range_error_message ,
59- "max_value" : year_outside_range_error_message ,
60- "invalid" : year_invalid_format_error_message ,
61- },
62- )
63- self .fields ["removal_status" ] = MultipleChoiceField (
64- required = False ,
65- choices = RemovalStatusChoices ,
66- widget = forms .CheckboxSelectMultiple ,
67- label = "Removed implants" ,
68- classes = "app-checkboxes" ,
69- )
70- self .fields ["removal_year" ] = IntegerField (
71- required = False ,
72- label = "Year removed" ,
73- classes = "nhsuk-input--width-4" ,
74- min_value = min_year ,
75- max_value = max_year ,
76- error_messages = {
77- "required" : "Enter the year the device was removed" ,
78- "min_value" : year_outside_range_error_message ,
79- "max_value" : year_outside_range_error_message ,
80- "invalid" : year_invalid_format_error_message ,
81- },
82- )
83- self .fields ["additional_details" ] = CharField (
84- hint = "Include any other relevant information about the device or procedure" ,
85- required = False ,
86- label = "Additional details (optional)" ,
87- label_classes = "nhsuk-label--m" ,
88- widget = Textarea (attrs = {"rows" : 4 }),
89- max_words = 500 ,
90- error_messages = {
91- "max_words" : "Additional details must be 500 words or less"
92- },
93- )
9459
9560 self .given_field_value (
9661 "device" , ImplantedMedicalDeviceHistoryItem .Device .OTHER_MEDICAL_DEVICE
9762 ).require_field ("other_medical_device_details" )
98- self .given_field_value (
99- "removal_status" , RemovalStatusChoices .HAS_BEEN_REMOVED
100- ).require_field ("removal_year" )
10163
10264 def model_values (self ):
10365 return dict (
10466 device = self .cleaned_data .get ("device" , "" ),
10567 other_medical_device_details = self .cleaned_data .get (
10668 "other_medical_device_details" , ""
10769 ),
70+ device_has_been_removed = self .cleaned_data .get ("device_has_been_removed" ),
10871 removal_year = self .cleaned_data .get ("removal_year" , "" ),
10972 procedure_year = self .cleaned_data .get ("procedure_year" , "" ),
11073 additional_details = self .cleaned_data .get ("additional_details" , "" ),
@@ -125,6 +88,19 @@ def create(self, appointment, request):
12588
12689 return implanted_medical_device_history
12790
91+ def full_clean (self ):
92+ # if a removal_year is provided then remove it if device_has_been_removed is False
93+ if self .data .get ("removal_year" ) and not self .data .get (
94+ "device_has_been_removed"
95+ ):
96+ # makes QueryDict mutable
97+ self .data = self .data .copy ()
98+ self .data ["removal_year" ] = None
99+ if hasattr (self .data , "_mutable" ):
100+ self .data ._mutable = False
101+
102+ super ().full_clean ()
103+
128104 def clean (self ):
129105 cleaned_data = super ().clean ()
130106 procedure_year = cleaned_data .get ("procedure_year" )
0 commit comments