From 55833f04689ed335aea0c89aa4cc003620e76d21 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 2 Aug 2024 12:30:04 -0600 Subject: [PATCH 01/11] Updated step_history check to ensure side nav refreshes with correct settings --- src/registrar/forms/domain_request_wizard.py | 4 +-- src/registrar/tests/test_forms.py | 4 +-- src/registrar/views/domain_request.py | 29 ++++++++++++++------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index 431aa30a7..d97dd0de7 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -679,7 +679,7 @@ class CisaRepresentativeYesNoForm(BaseYesNoForm): field_name = "has_cisa_representative" -class AdditionalDetailsForm(BaseDeletableRegistrarForm): +class AnythingElseForm(BaseDeletableRegistrarForm): anything_else = forms.CharField( required=True, label="Anything else?", @@ -698,7 +698,7 @@ class AdditionalDetailsForm(BaseDeletableRegistrarForm): ) -class AdditionalDetailsYesNoForm(BaseYesNoForm): +class AnythingElseYesNoForm(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. diff --git a/src/registrar/tests/test_forms.py b/src/registrar/tests/test_forms.py index 05ce46114..a8d85597b 100644 --- a/src/registrar/tests/test_forms.py +++ b/src/registrar/tests/test_forms.py @@ -15,7 +15,7 @@ from registrar.forms.domain_request_wizard import ( RequirementsForm, TribalGovernmentForm, PurposeForm, - AdditionalDetailsForm, + AnythingElseForm, AboutYourOrganizationForm, ) from registrar.forms.domain import ContactForm @@ -274,7 +274,7 @@ class TestFormValidation(MockEppLib): def test_anything_else_form_about_your_organization_character_count_invalid(self): """Response must be less than 2000 characters.""" - form = AdditionalDetailsForm( + form = AnythingElseForm( data={ "anything_else": "Bacon ipsum dolor amet fatback strip steak pastrami" "shankle, drumstick doner chicken landjaeger turkey andouille." diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index 08e23e402..7aa82d80e 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -217,8 +217,11 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): if current_url == self.EDIT_URL_NAME and "id" in kwargs: del self.storage self.storage["domain_request_id"] = kwargs["id"] - self.storage["step_history"] = self.db_check_for_unlocking_steps() - + + # refresh step_history to ensure we don't erroneously unlock unfinished + # steps just because we visited it + self.storage["step_history"] = self.db_check_for_unlocking_steps() + # if accessing this class directly, redirect to either to an acknowledgement # page or to the first step in the processes (if an edit rather than a new request); # subclasseswill NOT be redirected. The purpose of this is to allow code to @@ -341,10 +344,21 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): """Helper for get_context_data Queries the DB for a domain request and returns a list of unlocked steps.""" + + # The way this works is as follows: + # Each step is assigned a true/false value to determine if it is + # "unlocked" or not. This dictionary of values is looped through + # at the end of this function and any step with a "true" value is + # added to a simple array that is returned at the end of this function. + # This array is eventually passed to the frontend context (eg. domain_request_sidebar.html), + # and is used to determine how steps appear in the side nav. + # It is worth noting that any step assigned "false" here will be EXCLUDED + # from the list of "unlocked" steps. + history_dict = { "generic_org_type": self.domain_request.generic_org_type is not None, "tribal_government": self.domain_request.tribe_name is not None, - "organization_federal": self.domain_request.federal_type is not None, + "organization_federal": True, "organization_election": self.domain_request.is_election_board is not None, "organization_contact": ( self.domain_request.federal_agency is not None @@ -355,7 +369,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): or self.domain_request.zipcode is not None or self.domain_request.urbanization is not None ), - "about_your_organization": self.domain_request.about_your_organization is not None, + "about_your_organization": True, "senior_official": self.domain_request.senior_official is not None, "current_sites": ( self.domain_request.current_websites.exists() or self.domain_request.requested_domain is not None @@ -368,8 +382,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): or self.domain_request.no_other_contacts_rationale is not None ), "additional_details": ( - (self.domain_request.anything_else is not None and self.domain_request.has_cisa_representative) - or self.domain_request.is_policy_acknowledged is not None + (self.domain_request.has_anything_else_text and self.domain_request.has_cisa_representative) ), "requirements": self.domain_request.is_policy_acknowledged is not None, "review": self.domain_request.is_policy_acknowledged is not None, @@ -626,8 +639,8 @@ class AdditionalDetails(DomainRequestWizard): forms = [ forms.CisaRepresentativeYesNoForm, forms.CisaRepresentativeForm, - forms.AdditionalDetailsYesNoForm, - forms.AdditionalDetailsForm, + forms.AnythingElseYesNoForm, + forms.AnythingElseForm, ] def is_valid(self, forms: list) -> bool: From 2a5b31fa42d67281266650bbdae2e095b5a03d2d Mon Sep 17 00:00:00 2001 From: CocoByte Date: Mon, 5 Aug 2024 12:07:19 -0600 Subject: [PATCH 02/11] Restore step logic for organization_federal --- src/registrar/views/domain_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index 7aa82d80e..7352460ce 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -358,7 +358,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): history_dict = { "generic_org_type": self.domain_request.generic_org_type is not None, "tribal_government": self.domain_request.tribe_name is not None, - "organization_federal": True, + "organization_federal": self.domain_request.federal_type is not None, "organization_election": self.domain_request.is_election_board is not None, "organization_contact": ( self.domain_request.federal_agency is not None From adb7a6ca19247d89a844a49aeacf05756529a7ff Mon Sep 17 00:00:00 2001 From: CocoByte Date: Mon, 12 Aug 2024 17:11:38 -0600 Subject: [PATCH 03/11] Fixed logic for Additional Details section (bonus bug fix). Also linted --- src/registrar/models/domain_information.py | 10 ++++++++-- src/registrar/models/domain_request.py | 10 ++++++++-- src/registrar/views/domain_request.py | 16 ++++++++++------ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/registrar/models/domain_information.py b/src/registrar/models/domain_information.py index 894bbe6fe..92cd4d0f1 100644 --- a/src/registrar/models/domain_information.py +++ b/src/registrar/models/domain_information.py @@ -296,23 +296,29 @@ class DomainInformation(TimeStampedModel): """Some yes/no forms use a db field to track whether it was checked or not. We handle that here for def save(). """ + # Check if the firstname or lastname of cisa representative has any data. + # Then set the has_cisa_representative flag accordingly (so that it isn't + # "none", which indicates an incomplete form). # This ensures that if we have prefilled data, the form is prepopulated if self.cisa_representative_first_name is not None or self.cisa_representative_last_name is not None: self.has_cisa_representative = ( self.cisa_representative_first_name != "" and self.cisa_representative_last_name != "" ) - # This check is required to ensure that the form doesn't start out checked + # Check for blank data and update has_cisa_representative accordingly (if it isn't None) if self.has_cisa_representative is not None: self.has_cisa_representative = ( self.cisa_representative_first_name != "" and self.cisa_representative_first_name is not None ) and (self.cisa_representative_last_name != "" and self.cisa_representative_last_name is not None) + # Check if anything_else has any data. + # Then set the has_anything_else_text flag accordingly (so that it isn't + # "none", which indicates an incomplete form). # This ensures that if we have prefilled data, the form is prepopulated if self.anything_else is not None: self.has_anything_else_text = self.anything_else != "" - # This check is required to ensure that the form doesn't start out checked. + # Check for blank data and update has_anything_else_text accordingly (if it isn't None) if self.has_anything_else_text is not None: self.has_anything_else_text = self.anything_else != "" and self.anything_else is not None diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 363de213b..966c880d7 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -645,23 +645,29 @@ class DomainRequest(TimeStampedModel): """Some yes/no forms use a db field to track whether it was checked or not. We handle that here for def save(). """ + # Check if the firstname or lastname of cisa representative has any data. + # Then set the has_cisa_representative flag accordingly (so that it isn't + # "none", which indicates an incomplete form). # This ensures that if we have prefilled data, the form is prepopulated if self.cisa_representative_first_name is not None or self.cisa_representative_last_name is not None: self.has_cisa_representative = ( self.cisa_representative_first_name != "" and self.cisa_representative_last_name != "" ) - # This check is required to ensure that the form doesn't start out checked + # Check for blank data and update has_cisa_representative accordingly (if it isn't None) if self.has_cisa_representative is not None: self.has_cisa_representative = ( self.cisa_representative_first_name != "" and self.cisa_representative_first_name is not None ) and (self.cisa_representative_last_name != "" and self.cisa_representative_last_name is not None) + # Check if anything_else has any data. + # Then set the has_anything_else_text flag accordingly (so that it isn't + # "none", which indicates an incomplete form). # This ensures that if we have prefilled data, the form is prepopulated if self.anything_else is not None: self.has_anything_else_text = self.anything_else != "" - # This check is required to ensure that the form doesn't start out checked. + # Check for blank data and update has_anything_else_text accordingly (if it isn't None) if self.has_anything_else_text is not None: self.has_anything_else_text = self.anything_else != "" and self.anything_else is not None diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index 7352460ce..c8f81dcaa 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -217,11 +217,11 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): if current_url == self.EDIT_URL_NAME and "id" in kwargs: del self.storage self.storage["domain_request_id"] = kwargs["id"] - + # refresh step_history to ensure we don't erroneously unlock unfinished # steps just because we visited it self.storage["step_history"] = self.db_check_for_unlocking_steps() - + # if accessing this class directly, redirect to either to an acknowledgement # page or to the first step in the processes (if an edit rather than a new request); # subclasseswill NOT be redirected. The purpose of this is to allow code to @@ -348,12 +348,12 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): # The way this works is as follows: # Each step is assigned a true/false value to determine if it is # "unlocked" or not. This dictionary of values is looped through - # at the end of this function and any step with a "true" value is + # at the end of this function and any step with a "true" value is # added to a simple array that is returned at the end of this function. # This array is eventually passed to the frontend context (eg. domain_request_sidebar.html), # and is used to determine how steps appear in the side nav. # It is worth noting that any step assigned "false" here will be EXCLUDED - # from the list of "unlocked" steps. + # from the list of "unlocked" steps. history_dict = { "generic_org_type": self.domain_request.generic_org_type is not None, @@ -369,7 +369,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): or self.domain_request.zipcode is not None or self.domain_request.urbanization is not None ), - "about_your_organization": True, + "about_your_organization": self.domain_request.about_your_organization is not None, "senior_official": self.domain_request.senior_official is not None, "current_sites": ( self.domain_request.current_websites.exists() or self.domain_request.requested_domain is not None @@ -382,7 +382,11 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): or self.domain_request.no_other_contacts_rationale is not None ), "additional_details": ( - (self.domain_request.has_anything_else_text and self.domain_request.has_cisa_representative) + # Additional details is complete as long as "has anything else" and "has cisa rep" are not None + ( + self.domain_request.has_anything_else_text is not None + and self.domain_request.has_cisa_representative is not None + ) ), "requirements": self.domain_request.is_policy_acknowledged is not None, "review": self.domain_request.is_policy_acknowledged is not None, From dc3509c7d65f73eb4148788fe2dac7c410387ae5 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Mon, 12 Aug 2024 22:19:16 -0600 Subject: [PATCH 04/11] Fixing tests --- src/registrar/tests/test_views_request.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py index 0cee9d563..f2c28b772 100644 --- a/src/registrar/tests/test_views_request.py +++ b/src/registrar/tests/test_views_request.py @@ -1017,20 +1017,27 @@ class DomainRequestTests(TestWithUser, WebTest): type_page = intro_result.follow() session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + # fill out the organization type section then submit type_form = type_page.forms[0] type_form["generic_org_type-generic_org_type"] = "federal" self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) type_result = type_form.submit() - # follow first redirect + # follow first redirect to the next section self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) federal_page = type_result.follow() - # Now on federal type page, click back to the organization type + # we need to fill out the federal section so it stays unlocked + fed_branch_form = federal_page.forms[0] + fed_branch_form["organization_federal-federal_type"] = "executive" + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + fed_branch_form.submit() + + # Now click back to the organization type self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) new_page = federal_page.click(str(self.TITLES["generic_org_type"]), index=0) - # Should be a link to the organization_federal page + # Should be a link to the organization_federal page since it is now unlocked self.assertGreater( len(new_page.html.find_all("a", href="/request/organization_federal/")), 0, From 073ff94c3ba4214ba22dc449da0dacf438ac6300 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Wed, 14 Aug 2024 12:13:48 -0600 Subject: [PATCH 05/11] fixing tests - thanks for the help Rachid! --- src/registrar/views/domain_request.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index c8f81dcaa..b691549cd 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -218,10 +218,6 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): del self.storage self.storage["domain_request_id"] = kwargs["id"] - # refresh step_history to ensure we don't erroneously unlock unfinished - # steps just because we visited it - self.storage["step_history"] = self.db_check_for_unlocking_steps() - # if accessing this class directly, redirect to either to an acknowledgement # page or to the first step in the processes (if an edit rather than a new request); # subclasseswill NOT be redirected. The purpose of this is to allow code to @@ -236,6 +232,9 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): else: return self.goto(self.steps.first) + # refresh step_history to ensure we don't erroneously unlock unfinished + # steps just because we visited it + self.storage["step_history"] = self.db_check_for_unlocking_steps() context = self.get_context_data() self.steps.current = current_url context["forms"] = self.get_forms() From 9f9969ca72795953b41978280b696e1ee06ed35d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:39:40 -0600 Subject: [PATCH 06/11] Add jyoti to fixtures --- src/registrar/fixtures_users.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/registrar/fixtures_users.py b/src/registrar/fixtures_users.py index 7ce63d364..6cfd13573 100644 --- a/src/registrar/fixtures_users.py +++ b/src/registrar/fixtures_users.py @@ -22,6 +22,12 @@ class UserFixture: """ ADMINS = [ + { + "username": "43a7fa8d-0550-4494-a6fe-81500324d590", + "first_name": "Jyoti", + "last_name": "Bock", + "email": "jyotibock@truss.works" + }, { "username": "aad084c3-66cc-4632-80eb-41cdf5c5bcbf", "first_name": "Aditi", @@ -125,6 +131,12 @@ class UserFixture: ] STAFF = [ + { + "username": "a5906815-dd80-4c64-aebe-2da6a4c9d7a4", + "first_name": "Jyoti-Analyst", + "last_name": "Bock-Analyst", + "email": "jyotibock+1@truss.works" + }, { "username": "ffec5987-aa84-411b-a05a-a7ee5cbcde54", "first_name": "Aditi-Analyst", From 9d83e50ac69e4f37d75e52cb92cae9f0ddd2c007 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:45:46 -0600 Subject: [PATCH 07/11] Update fixtures_users.py --- src/registrar/fixtures_users.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/fixtures_users.py b/src/registrar/fixtures_users.py index 6cfd13573..0fc203248 100644 --- a/src/registrar/fixtures_users.py +++ b/src/registrar/fixtures_users.py @@ -26,7 +26,7 @@ class UserFixture: "username": "43a7fa8d-0550-4494-a6fe-81500324d590", "first_name": "Jyoti", "last_name": "Bock", - "email": "jyotibock@truss.works" + "email": "jyotibock@truss.works", }, { "username": "aad084c3-66cc-4632-80eb-41cdf5c5bcbf", @@ -135,7 +135,7 @@ class UserFixture: "username": "a5906815-dd80-4c64-aebe-2da6a4c9d7a4", "first_name": "Jyoti-Analyst", "last_name": "Bock-Analyst", - "email": "jyotibock+1@truss.works" + "email": "jyotibock+1@truss.works", }, { "username": "ffec5987-aa84-411b-a05a-a7ee5cbcde54", From f9c2a647d4cd6af3d1a1eabb2d3775ad5618d8b4 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:33:44 -0600 Subject: [PATCH 08/11] Fix tests --- src/registrar/tests/test_views_request.py | 28 ++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py index f2c28b772..6642b6471 100644 --- a/src/registrar/tests/test_views_request.py +++ b/src/registrar/tests/test_views_request.py @@ -2535,9 +2535,22 @@ class DomainRequestTests(TestWithUser, WebTest): self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) election_page = type_result.follow() - # Go back to SO page and test the dynamic text changed + # Navigate to the org page as that is the step right before senior_official + org_page = election_page.click(str(self.TITLES["organization_contact"]), index=0) + org_contact_form = org_page.forms[0] + org_contact_form["organization_contact-organization_name"] = "Testorg" + org_contact_form["organization_contact-address_line1"] = "address 1" + org_contact_form["organization_contact-address_line2"] = "address 2" + org_contact_form["organization_contact-city"] = "NYC" + org_contact_form["organization_contact-state_territory"] = "NY" + org_contact_form["organization_contact-zipcode"] = "10002" + org_contact_form["organization_contact-urbanization"] = "URB Royal Oaks" self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - so_page = election_page.click(str(self.TITLES["senior_official"]), index=0) + org_contact_result = org_contact_form.submit() + + # Navigate back to the so page + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + so_page = org_contact_result.follow() self.assertContains(so_page, "Domain requests from cities") @less_console_noise_decorator @@ -2635,9 +2648,15 @@ class DomainRequestTests(TestWithUser, WebTest): self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) election_page = type_result.follow() + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + current_websites = election_page.click(str(self.TITLES["current_sites"]), index=0) + current_sites_form = current_websites.forms[0] + current_sites_form["current_sites-0-website"] = "www.city.com" + current_sites_result = current_sites_form.submit().follow() + # Go back to dotgov domain page to test the dynamic text changed self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - dotgov_page = election_page.click(str(self.TITLES["dotgov_domain"]), index=0) + dotgov_page = current_sites_result.click(str(self.TITLES["dotgov_domain"]), index=0) self.assertContains(dotgov_page, "CityofEudoraKS.gov") self.assertNotContains(dotgov_page, "medicare.gov") @@ -2991,6 +3010,9 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest): """Test when all fields in the domain request are filled.""" domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.STARTED, user=self.user) + domain_request.anything_else = False + domain_request.has_anything_else_text = False + domain_request.save() response = self.app.get(f"/domain-request/{domain_request.id}/edit/") # django-webtest does not handle cookie-based sessions well because it keeps From 469a4bda879c5440ec11f587e42f5b02dcdc80b7 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 16 Aug 2024 15:44:37 -0600 Subject: [PATCH 09/11] Added domains and domain request section to suborgs --- src/registrar/admin.py | 23 ++++++++++++ .../django/admin/suborg_change_form.html | 36 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/registrar/templates/django/admin/suborg_change_form.html diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 423c0a01b..b3ce63601 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -9,6 +9,7 @@ from django.db.models.functions import Concat, Coalesce from django.http import HttpResponseRedirect from django.shortcuts import redirect from django_fsm import get_available_FIELD_transitions, FSMField +from registrar.models.domain_information import DomainInformation from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices from waffle.decorators import flag_is_active from django.contrib import admin, messages @@ -3142,12 +3143,34 @@ class DomainGroupAdmin(ListHeaderAdmin, ImportExportModelAdmin): class SuborganizationAdmin(ListHeaderAdmin, ImportExportModelAdmin): + list_display = ["name", "portfolio"] autocomplete_fields = [ "portfolio", ] search_fields = ["name"] + change_form_template = "django/admin/suborg_change_form.html" + def change_view(self, request, object_id, form_url="", extra_context=None): + """Add suborg's related domains and requests to context""" + obj = self.get_object(request, object_id) + + # ---- Domain Requests + # domain_requests = DomainRequest.objects.filter(sub_organization=obj).exclude( + # Q(status=DomainRequest.DomainRequestStatus.STARTED) | Q(status=DomainRequest.DomainRequestStatus.WITHDRAWN) + # ) + domain_requests = DomainRequest.objects.filter(sub_organization=obj) + sort_by = request.GET.get("sort_by", "requested_domain__name") + domain_requests = domain_requests.order_by(sort_by) + + # ---- Domains + domain_infos = DomainInformation.objects.filter(sub_organization=obj) + domain_ids = domain_infos.values_list("domain", flat=True) + domains = Domain.objects.filter(id__in=domain_ids).exclude(state=Domain.State.DELETED) + + extra_context = {"domain_requests": domain_requests, "domains": domains} + return super().change_view(request, object_id, form_url, extra_context) + admin.site.unregister(LogEntry) # Unregister the default registration diff --git a/src/registrar/templates/django/admin/suborg_change_form.html b/src/registrar/templates/django/admin/suborg_change_form.html new file mode 100644 index 000000000..005d67aec --- /dev/null +++ b/src/registrar/templates/django/admin/suborg_change_form.html @@ -0,0 +1,36 @@ +{% extends 'django/admin/email_clipboard_change_form.html' %} +{% load i18n static %} + +{% block after_related_objects %} +
+

Associated requests and domains

+
+
+

Domain requests

+ +
+
+

Domains

+ +
+
+
+{% endblock %} From b83cc5a980bea05559a52fc20447567053bdf820 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 16 Aug 2024 15:45:01 -0600 Subject: [PATCH 10/11] removed commented out code --- src/registrar/admin.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index b3ce63601..bb3c09ae9 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -3156,9 +3156,6 @@ class SuborganizationAdmin(ListHeaderAdmin, ImportExportModelAdmin): obj = self.get_object(request, object_id) # ---- Domain Requests - # domain_requests = DomainRequest.objects.filter(sub_organization=obj).exclude( - # Q(status=DomainRequest.DomainRequestStatus.STARTED) | Q(status=DomainRequest.DomainRequestStatus.WITHDRAWN) - # ) domain_requests = DomainRequest.objects.filter(sub_organization=obj) sort_by = request.GET.get("sort_by", "requested_domain__name") domain_requests = domain_requests.order_by(sort_by) From efc78361975ef22d90144f0ab3c7f007470641a5 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Fri, 16 Aug 2024 16:06:37 -0600 Subject: [PATCH 11/11] linted --- src/registrar/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index bb3c09ae9..3ad5e3ea0 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -3151,6 +3151,7 @@ class SuborganizationAdmin(ListHeaderAdmin, ImportExportModelAdmin): search_fields = ["name"] change_form_template = "django/admin/suborg_change_form.html" + def change_view(self, request, object_id, form_url="", extra_context=None): """Add suborg's related domains and requests to context""" obj = self.get_object(request, object_id)