diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 2e5a531d1..0af91327b 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -182,6 +182,11 @@ urlpatterns = [ views.DomainOrgNameAddressView.as_view(), name="domain-org-name-address", ), + path( + "domain//suborganization", + views.DomainSubOrganizationView.as_view(), + name="domain-suborganization", + ), path( "domain//senior-official", views.DomainSeniorOfficialView.as_view(), diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 9b8f1b7fc..f3ab46727 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -16,7 +16,7 @@ from registrar.utility.errors import ( SecurityEmailErrorCodes, ) -from ..models import Contact, DomainInformation, Domain, User +from ..models import Contact, DomainInformation, Domain, User, Suborganization from .common import ( ALGORITHM_CHOICES, DIGEST_TYPE_CHOICES, @@ -508,6 +508,41 @@ class DomainOrgNameAddressForm(forms.ModelForm): return old_value == new_value +class DomainSuborganizationForm(forms.ModelForm): + """Form for updating the suborganization""" + + class Meta: + model = DomainInformation + fields = [ + "sub_organization", + ] + error_messages = { + "sub_organization": {"required": "Select a suborganization."}, + } + widgets = { + "sub_organization": forms.Select( + attrs={ + "required": False, + }, + ), + } + + # the database fields have blank=True so ModelForm doesn't create + # required fields by default. Use this list in __init__ to mark each + # of these fields as required + required = ["sub_organization"] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["sub_organization"].required = False + if self.instance and self.instance.portfolio: + self.fields['sub_organization'].queryset = Suborganization.objects.filter( + portfolio=self.instance.portfolio + ) + else: + self.fields['sub_organization'].queryset = Suborganization.objects.none() + + class DomainDnssecForm(forms.Form): """Form for enabling and disabling dnssec""" diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index d61e5f45c..158874c64 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -54,15 +54,12 @@ {% endif %} - -
  • - {% url 'domain-org-name-address' pk=domain.id as url %} - - Organization name and mailing address - -
  • + + {% if is_org_user %} + {% include "includes/domain_sidenav_item.html" with url_name="domain-suborganization" item_text="Suborganization"%} + {% else %} + {% include "includes/domain_sidenav_item.html" with url_name="domain-org-name-address" item_text="Organization name and mailing address"%} + {% endif %}
  • {% url 'domain-senior-official' pk=domain.id as url %} diff --git a/src/registrar/templates/domain_suborganization.html b/src/registrar/templates/domain_suborganization.html new file mode 100644 index 000000000..ed0cb69f3 --- /dev/null +++ b/src/registrar/templates/domain_suborganization.html @@ -0,0 +1,25 @@ +{% extends "domain_base.html" %} +{% load static field_helpers%} + +{% block title %}Suborganization{% endblock %} + +{% block domain_content %} + {# this is right after the messages block in the parent template #} + {% include "includes/form_errors.html" with form=form %} + +

    Organization name and mailing address

    + +

    + The name of your suborganization will be publicly listed as the domain registrant. + This list of suborganizations has been populated the .gov program. + If you believe there is an error please contact help@get.gov. +

    + + {% include "includes/required_fields.html" %} +
    + {% csrf_token %} + {% input_with_errors form.sub_organization %} + +
    + +{% endblock %} diff --git a/src/registrar/templates/includes/domain_sidenav_item.html b/src/registrar/templates/includes/domain_sidenav_item.html new file mode 100644 index 000000000..3c8210694 --- /dev/null +++ b/src/registrar/templates/includes/domain_sidenav_item.html @@ -0,0 +1,8 @@ +
  • + {% url url_name pk=domain.id as url %} + + {{ item_text }} + +
  • \ No newline at end of file diff --git a/src/registrar/views/__init__.py b/src/registrar/views/__init__.py index 37977f334..c224e72c0 100644 --- a/src/registrar/views/__init__.py +++ b/src/registrar/views/__init__.py @@ -3,6 +3,7 @@ from .domain import ( DomainView, DomainSeniorOfficialView, DomainOrgNameAddressView, + DomainSubOrganizationView, DomainDNSView, DomainNameserversView, DomainDNSSECView, diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 766bef7c2..a56629a5b 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -16,6 +16,7 @@ from django.urls import reverse from django.views.generic.edit import FormMixin from django.conf import settings +from registrar.forms.domain import DomainSuborganizationForm from registrar.models import ( Domain, DomainRequest, @@ -221,6 +222,34 @@ class DomainOrgNameAddressView(DomainFormBaseView): return super().form_valid(form) +class DomainSubOrganizationView(DomainFormBaseView): + """Suborganization view""" + + model = Domain + template_name = "domain_suborganization.html" + context_object_name = "domain" + form_class = DomainSuborganizationForm + + def get_form_kwargs(self, *args, **kwargs): + """Add domain_info.organization_name instance to make a bound form.""" + form_kwargs = super().get_form_kwargs(*args, **kwargs) + form_kwargs["instance"] = self.object.domain_info + return form_kwargs + + def get_success_url(self): + """Redirect to the overview page for the domain.""" + return reverse("domain-suborganization", kwargs={"pk": self.object.pk}) + + def form_valid(self, form): + """The form is valid, save the organization name and mailing address.""" + form.save() + + messages.success(self.request, "The suborganization name for this domain has been updated.") + + # superclass has the redirect + return super().form_valid(form) + + class DomainSeniorOfficialView(DomainFormBaseView): """Domain senior official editing view."""