From a789b34bc001f467dff389e1f87d1b9a65d98e09 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 17 May 2024 12:19:54 -0600 Subject: [PATCH 001/200] Updates to Cisa Rep fields in Additional Details. Refactored Cisa Rep to utilize ContactsModel --- src/registrar/forms/domain_request_wizard.py | 68 ++++++++++++++++--- ...tion_cisa_representative_email_and_more.py | 46 +++++++++++++ src/registrar/models/domain_information.py | 8 ++- src/registrar/models/domain_request.py | 20 +++--- .../domain_request_additional_details.html | 9 +-- 5 files changed, 126 insertions(+), 25 deletions(-) create mode 100644 src/registrar/migrations/0095_remove_domaininformation_cisa_representative_email_and_more.py diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index 0e9e87f9d..96ebbfebf 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -646,21 +646,72 @@ class NoOtherContactsForm(BaseDeletableRegistrarForm): ) -class CisaRepresentativeForm(BaseDeletableRegistrarForm): - cisa_representative_email = forms.EmailField( - required=True, +# class CisaRepresentativeForm(BaseDeletableRegistrarForm): +# cisa_representative_email = forms.EmailField( +# required=False, +# max_length=None, +# label="Your representative’s email", +# validators=[ +# MaxLengthValidator( +# 320, +# 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 CisaRepresentativeForm(RegistrarForm): + JOIN = "cisa_representative" + + logger.debug("GETTING CISA REP") + + def to_database(self, obj): + logger.debug("SAVING CISA REP") + if not self.is_valid(): + return + contact = getattr(obj, "cisa_representative", None) + logger.debug("EXISTING REP: %s" % contact) + if contact is not None and not contact.has_more_than_one_join("cisa_representative_domain_requests"): + # if contact exists in the database and is not joined to other entities + super().to_database(contact) + else: + # no contact exists OR contact exists which is joined also to other entities; + # in either case, create a new contact and update it + contact = Contact() + super().to_database(contact) + logger.debug("NEW REP: %s" % contact) + obj.cisa_representative = contact + obj.save() + + @classmethod + def from_database(cls, obj): + contact = getattr(obj, "cisa_representative", None) + return super().from_database(contact) + + first_name = forms.CharField( + label="First name / given name", + error_messages={"required": "Enter your first name / given name."}, + ) + last_name = forms.CharField( + label="Last name / family name", + error_messages={"required": "Enter your last name / family name."}, + ) + email = forms.EmailField( + label="Email", max_length=None, - label="Your representative’s email", + 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."), + }, validators=[ MaxLengthValidator( 320, 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."), - }, ) @@ -668,6 +719,7 @@ class CisaRepresentativeYesNoForm(BaseYesNoForm): """Yes/no toggle for the CISA regions question on additional details""" form_is_checked = property(lambda self: self.domain_request.has_cisa_representative) # type: ignore + logger.debug("CHECKING FOR YES/NO CHECK -- %s" % form_is_checked) field_name = "has_cisa_representative" diff --git a/src/registrar/migrations/0095_remove_domaininformation_cisa_representative_email_and_more.py b/src/registrar/migrations/0095_remove_domaininformation_cisa_representative_email_and_more.py new file mode 100644 index 000000000..7e7fb5ee6 --- /dev/null +++ b/src/registrar/migrations/0095_remove_domaininformation_cisa_representative_email_and_more.py @@ -0,0 +1,46 @@ +# Generated by Django 4.2.10 on 2024-05-16 23:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrar", "0094_create_groups_v12"), + ] + + operations = [ + migrations.RemoveField( + model_name="domaininformation", + name="cisa_representative_email", + ), + migrations.RemoveField( + model_name="domainrequest", + name="cisa_representative_email", + ), + migrations.AddField( + model_name="domaininformation", + name="cisa_representative", + field=models.ForeignKey( + blank=True, + help_text='Cisa Representative listed under "additional information" in the request form', + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="cisa_representative_domain_requests_information", + to="registrar.contact", + ), + ), + migrations.AddField( + model_name="domainrequest", + name="cisa_representative", + field=models.ForeignKey( + blank=True, + help_text='Cisa Representative listed under "additional information" in the request form', + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="cisa_representative_domain_requests", + to="registrar.contact", + ), + ), + ] diff --git a/src/registrar/models/domain_information.py b/src/registrar/models/domain_information.py index 264e322b8..bf6db1a28 100644 --- a/src/registrar/models/domain_information.py +++ b/src/registrar/models/domain_information.py @@ -206,11 +206,13 @@ class DomainInformation(TimeStampedModel): verbose_name="Additional details", ) - cisa_representative_email = models.EmailField( + cisa_representative = models.ForeignKey( + "registrar.Contact", null=True, blank=True, - verbose_name="CISA regional representative", - max_length=320, + related_name="cisa_representative_domain_requests_information", + on_delete=models.PROTECT, + help_text='Cisa Representative listed under "additional information" in the request form', ) is_policy_acknowledged = models.BooleanField( diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 2501cdc87..a1668a6c8 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -457,11 +457,14 @@ class DomainRequest(TimeStampedModel): help_text="Determines if the user has a anything_else or not", ) - cisa_representative_email = models.EmailField( + + cisa_representative = models.ForeignKey( + "registrar.Contact", null=True, blank=True, - verbose_name="CISA regional representative", - max_length=320, + related_name="cisa_representative_domain_requests", + on_delete=models.PROTECT, + help_text='Cisa Representative listed under "additional information" in the request form', ) # This is a drop-in replacement for an has_cisa_representative() function. @@ -534,15 +537,16 @@ class DomainRequest(TimeStampedModel): We handle that here for def save(). """ + cisa_rep_is_not_none = self.cisa_representative is not None + logger.debug("CISA REPRESENTATIVE IS %s" % cisa_rep_is_not_none) + # This ensures that if we have prefilled data, the form is prepopulated - if self.cisa_representative_email is not None: - self.has_cisa_representative = self.cisa_representative_email != "" + if cisa_rep_is_not_none: + self.has_cisa_representative = True # 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 - ) + self.has_cisa_representative = cisa_rep_is_not_none # This ensures that if we have prefilled data, the form is prepopulated if self.anything_else is not None: diff --git a/src/registrar/templates/domain_request_additional_details.html b/src/registrar/templates/domain_request_additional_details.html index e13d3c7ee..e8bdb5620 100644 --- a/src/registrar/templates/domain_request_additional_details.html +++ b/src/registrar/templates/domain_request_additional_details.html @@ -9,7 +9,6 @@ {# commented out so it does not appear at this point on this page #} {% endblock %} - {% block form_fields %}
@@ -22,13 +21,13 @@ {% input_with_errors forms.0.has_cisa_representative %} {% endwith %} {# forms.0 is a small yes/no form that toggles the visibility of "cisa representative" formset #} -
- {% input_with_errors forms.1.cisa_representative_email %} + {% input_with_errors forms.1.first_name %} + {% input_with_errors forms.1.last_name %} + {% input_with_errors forms.1.email %} {# forms.1 is a form for inputting the e-mail of a cisa representative #} -
@@ -42,7 +41,6 @@ {% input_with_errors forms.2.has_anything_else_text %} {% endwith %} {# forms.2 is a small yes/no form that toggles the visibility of "cisa representative" formset #} -
@@ -50,6 +48,5 @@ {% input_with_errors forms.3.anything_else %} {% endwith %} {# forms.3 is a form for inputting the e-mail of a cisa representative #} -
{% endblock %} From 321590ec5c22b21d7ba01b67708cbabb7583beab Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 17 May 2024 12:28:44 -0600 Subject: [PATCH 002/200] updated summary --- src/registrar/forms/domain_request_wizard.py | 17 ----------------- .../templates/domain_request_review.html | 2 +- .../templates/domain_request_status.html | 2 +- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index 96ebbfebf..9a2f206fd 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -646,23 +646,6 @@ class NoOtherContactsForm(BaseDeletableRegistrarForm): ) -# class CisaRepresentativeForm(BaseDeletableRegistrarForm): -# cisa_representative_email = forms.EmailField( -# required=False, -# max_length=None, -# label="Your representative’s email", -# validators=[ -# MaxLengthValidator( -# 320, -# 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 CisaRepresentativeForm(RegistrarForm): JOIN = "cisa_representative" diff --git a/src/registrar/templates/domain_request_review.html b/src/registrar/templates/domain_request_review.html index 5f359e95f..47b55ec12 100644 --- a/src/registrar/templates/domain_request_review.html +++ b/src/registrar/templates/domain_request_review.html @@ -158,7 +158,7 @@ {% if step == Step.ADDITIONAL_DETAILS %} {% namespaced_url 'domain-request' step as domain_request_url %} {% with title=form_titles|get_item:step value=domain_request.requested_domain.name|default:"Incomplete" %} - {% include "includes/summary_item.html" with title=title sub_header_text='CISA regional representative' value=domain_request.cisa_representative_email heading_level=heading_level editable=True edit_link=domain_request_url custom_text_for_value_none='No' %} + {% include "includes/summary_item.html" with title=title sub_header_text='CISA regional representative' value=domain_request.cisa_representative contact='true' heading_level=heading_level editable=True edit_link=domain_request_url custom_text_for_value_none='No' %} {% endwith %}

Anything else

diff --git a/src/registrar/templates/domain_request_status.html b/src/registrar/templates/domain_request_status.html index 0ea16e3a3..938846714 100644 --- a/src/registrar/templates/domain_request_status.html +++ b/src/registrar/templates/domain_request_status.html @@ -118,7 +118,7 @@ {# We always show this field even if None #} {% if DomainRequest %} - {% include "includes/summary_item.html" with title='Additional details' sub_header_text='CISA regional representative' value=DomainRequest.cisa_representative_email custom_text_for_value_none='No' heading_level=heading_level %} + {% include "includes/summary_item.html" with title='Additional details' sub_header_text='CISA regional representative' value=DomainRequest.cisa_representative contact='true' custom_text_for_value_none='No' heading_level=heading_level %}

Anything else