diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index 789d4498a..95d1f9a4a 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -647,7 +647,6 @@ class CisaRepresentativeForm(BaseDeletableRegistrarForm): cisa_representative_email = forms.EmailField( required=True, max_length=None, - error_messages={"invalid": ("Enter your email address in the required format, like name@example.com.")}, label="Your representative’s email", validators=[ MaxLengthValidator( @@ -655,14 +654,17 @@ class CisaRepresentativeForm(BaseDeletableRegistrarForm): message="Response must be less than 320 characters.", ) ], + error_messages={ + "invalid": ("Enter your email address in the required format, like name@example.com."), + "required": ("Enter the email address of your CISA regional representative."), + }, ) class CisaRepresentativeYesNoForm(BaseYesNoForm): """Yes/no toggle for the CISA regions question on additional details""" - # Note that these can be set as functions/init if you need more fine-grained control - form_is_checked = property(lambda self: self.domain_request.has_cisa_representative()) # type: ignore + form_is_checked = property(lambda self: self.domain_request.has_cisa_representative) field_name = "has_cisa_representative" @@ -677,6 +679,12 @@ class AdditionalDetailsForm(BaseDeletableRegistrarForm): message="Response must be less than 2000 characters.", ) ], + error_messages={ + "required": ( + "Provide additional details you’d like us to know. " + "If you have nothing to add, select “No.”" + ) + }, ) @@ -684,7 +692,7 @@ class AdditionalDetailsYesNoForm(BaseYesNoForm): """Yes/no toggle for the anything else question on additional details""" # Note that these can be set as functions/init if you need more fine-grained control. - form_is_checked = property(lambda self: self.domain_request.has_anything_else_text()) # type: ignore + form_is_checked = property(lambda self: self.domain_request.has_anything_else_text) # type: ignore field_name = "has_anything_else_text" diff --git a/src/registrar/forms/utility/wizard_form_helper.py b/src/registrar/forms/utility/wizard_form_helper.py index 2ae50f908..f15382b44 100644 --- a/src/registrar/forms/utility/wizard_form_helper.py +++ b/src/registrar/forms/utility/wizard_form_helper.py @@ -263,6 +263,8 @@ class BaseYesNoForm(RegistrarForm): }, ) + print(f"wjat are the error messages? {choice_field.error_messages}") + return choice_field def get_initial_value(self): diff --git a/src/registrar/migrations/0086_domainrequest_has_anything_else_text_and_more.py b/src/registrar/migrations/0086_domainrequest_has_anything_else_text_and_more.py new file mode 100644 index 000000000..5b1d24711 --- /dev/null +++ b/src/registrar/migrations/0086_domainrequest_has_anything_else_text_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.10 on 2024-04-18 17:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrar", "0085_domaininformation_cisa_representative_email_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="domainrequest", + name="has_anything_else_text", + field=models.BooleanField( + blank=True, help_text="Determines if the user has a anything_else or not", null=True + ), + ), + migrations.AddField( + model_name="domainrequest", + name="has_cisa_representative", + field=models.BooleanField( + blank=True, help_text="Determines if the user has a representative email or not", null=True + ), + ), + ] diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 1e8091c44..0b6e9a2b4 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -647,6 +647,15 @@ class DomainRequest(TimeStampedModel): verbose_name="Additional details", ) + # This is a drop-in replacement for a has_anything_else_text() function. + # In order to track if the user has clicked the yes/no field (while keeping a none default), we need + # a tertiary state. We should not display this in /admin. + has_anything_else_text = models.BooleanField( + null=True, + blank=True, + help_text="Determines if the user has a anything_else or not", + ) + cisa_representative_email = models.EmailField( null=True, blank=True, @@ -655,6 +664,15 @@ class DomainRequest(TimeStampedModel): max_length=320, ) + # This is a drop-in replacement for an has_cisa_representative() function. + # In order to track if the user has clicked the yes/no field (while keeping a none default), we need + # a tertiary state. We should not display this in /admin. + has_cisa_representative = models.BooleanField( + null=True, + blank=True, + help_text="Determines if the user has a representative email or not", + ) + is_policy_acknowledged = models.BooleanField( null=True, blank=True, @@ -707,8 +725,25 @@ class DomainRequest(TimeStampedModel): def save(self, *args, **kwargs): """Save override for custom properties""" self.sync_organization_type() + self.sync_yes_no_form_fields() + super().save(*args, **kwargs) + def sync_yes_no_form_fields(self): + """Some yes/no forms use a db field to track whether it was checked or not. + We handle that here for def save(). + """ + # This check is required to ensure that the form doesn't start out checked + if self.has_cisa_representative is not None: + self.has_cisa_representative = ( + self.cisa_representative_email != "" and self.cisa_representative_email is not None + ) + + if self.anything_else is not None: + self.has_anything_else_text = ( + self.anything_else != "" and self.anything_else is not None + ) + def __str__(self): try: if self.requested_domain and self.requested_domain.name: @@ -1047,16 +1082,8 @@ class DomainRequest(TimeStampedModel): """Does this domain request have other contacts listed?""" return self.other_contacts.exists() - def has_anything_else_text(self) -> bool: - """Does this domain request have an 'anything else?' entry""" - return self.anything_else != "" and self.anything_else is not None - - def has_cisa_representative(self) -> bool: - """Does this domain request have cisa representative?""" - return self.cisa_representative_email != "" and self.cisa_representative_email is not None - def has_additional_details(self) -> bool: - return self.has_anything_else_text() or self.has_cisa_representative() + return self.has_anything_else_text() or self.has_cisa_representative def is_federal(self) -> Union[bool, None]: """Is this domain request for a federal agency?