diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 8e918e442..5ae3457c3 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -51,7 +51,7 @@ from django.utils.html import escape from django.contrib.auth.forms import UserChangeForm, UsernameField from django.contrib.admin.views.main import IGNORED_PARAMS from django_admin_multiple_choice_list_filter.list_filters import MultipleChoiceListFilter -from import_export import resources, fields +from import_export import resources from import_export.admin import ImportExportModelAdmin from django.core.exceptions import ObjectDoesNotExist from django.contrib.admin.widgets import FilteredSelectMultiple @@ -1489,11 +1489,9 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin): for domain_info in DomainInformation.objects.all(): converted_generic_org = domain_info.converted_generic_org_type # Actual value converted_generic_org_display = domain_info.converted_generic_org_type_display # Display value - + if converted_generic_org: - converted_generic_orgs.add( - (converted_generic_org, converted_generic_org_display) # Value, Display - ) + converted_generic_orgs.add((converted_generic_org, converted_generic_org_display)) # Value, Display # Sort the set by display value return sorted(converted_generic_orgs, key=lambda x: x[1]) # x[1] is the display value @@ -1502,9 +1500,9 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin): def queryset(self, request, queryset): if self.value(): # Check if a generic org is selected in the filter return queryset.filter( - Q(portfolio__organization_type=self.value()) | - Q(portfolio__isnull=True, generic_org_type=self.value()) - ) + Q(portfolio__organization_type=self.value()) + | Q(portfolio__isnull=True, generic_org_type=self.value()) + ) return queryset resource_classes = [DomainInformationResource] @@ -1666,7 +1664,6 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin): # objects rather than Contact objects. use_sort = db_field.name != "senior_official" return super().formfield_for_foreignkey(db_field, request, use_admin_sort_fields=use_sort, **kwargs) - class DomainRequestResource(FsmModelResource): @@ -1711,11 +1708,9 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): for domain_request in DomainRequest.objects.all(): converted_generic_org = domain_request.converted_generic_org_type # Actual value converted_generic_org_display = domain_request.converted_generic_org_type_display # Display value - + if converted_generic_org: - converted_generic_orgs.add( - (converted_generic_org, converted_generic_org_display) # Value, Display - ) + converted_generic_orgs.add((converted_generic_org, converted_generic_org_display)) # Value, Display # Sort the set by display value return sorted(converted_generic_orgs, key=lambda x: x[1]) # x[1] is the display value @@ -1724,9 +1719,9 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): def queryset(self, request, queryset): if self.value(): # Check if a generic org is selected in the filter return queryset.filter( - Q(portfolio__organization_type=self.value()) | - Q(portfolio__isnull=True, generic_org_type=self.value()) - ) + Q(portfolio__organization_type=self.value()) + | Q(portfolio__isnull=True, generic_org_type=self.value()) + ) return queryset class FederalTypeFilter(admin.SimpleListFilter): @@ -1744,7 +1739,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): for domain_request in DomainRequest.objects.all(): converted_federal_type = domain_request.converted_federal_type # Actual value converted_federal_type_display = domain_request.converted_federal_type_display # Display value - + if converted_federal_type: converted_federal_types.add( (converted_federal_type, converted_federal_type_display) # Value, Display @@ -1757,9 +1752,9 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): def queryset(self, request, queryset): if self.value(): # Check if a federal type is selected in the filter return queryset.filter( - Q(portfolio__federal_agency__federal_type=self.value()) | - Q(portfolio__isnull=True, federal_type=self.value()) - ) + Q(portfolio__federal_agency__federal_type=self.value()) + | Q(portfolio__isnull=True, federal_type=self.value()) + ) return queryset class InvestigatorFilter(admin.SimpleListFilter): @@ -2761,27 +2756,22 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin): for domain_info in DomainInformation.objects.all(): converted_generic_org = domain_info.converted_generic_org_type # Actual value converted_generic_org_display = domain_info.converted_generic_org_type_display # Display value - + if converted_generic_org: - converted_generic_orgs.add( - (converted_generic_org, converted_generic_org_display) # Value, Display - ) + converted_generic_orgs.add((converted_generic_org, converted_generic_org_display)) # Value, Display # Sort the set by display value return sorted(converted_generic_orgs, key=lambda x: x[1]) # x[1] is the display value - # Filter queryset def queryset(self, request, queryset): if self.value(): # Check if a generic org is selected in the filter return queryset.filter( - Q(domain_info__portfolio__organization_type=self.value()) | - Q(domain_info__portfolio__isnull=True, domain_info__generic_org_type=self.value()) - ) - + Q(domain_info__portfolio__organization_type=self.value()) + | Q(domain_info__portfolio__isnull=True, domain_info__generic_org_type=self.value()) + ) + return queryset - - class FederalTypeFilter(admin.SimpleListFilter): """Custom Federal Type filter that accomodates portfolio feature. @@ -2798,7 +2788,7 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin): for domain_info in DomainInformation.objects.all(): converted_federal_type = domain_info.converted_federal_type # Actual value converted_federal_type_display = domain_info.converted_federal_type_display # Display value - + if converted_federal_type: converted_federal_types.add( (converted_federal_type, converted_federal_type_display) # Value, Display @@ -2811,56 +2801,56 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin): def queryset(self, request, queryset): if self.value(): # Check if a federal type is selected in the filter return queryset.filter( - Q(domain_info__portfolio__federal_agency__federal_type=self.value()) | - Q(domain_info__portfolio__isnull=True, domain_info__federal_agency__federal_type=self.value()) - ) + Q(domain_info__portfolio__federal_agency__federal_type=self.value()) + | Q(domain_info__portfolio__isnull=True, domain_info__federal_agency__federal_type=self.value()) + ) return queryset def get_annotated_queryset(self, queryset): return queryset.annotate( - converted_generic_org_type=Case( - # When portfolio is present, use its value instead - When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__organization_type")), - # Otherwise, return the natively assigned value - default=F("domain_info__generic_org_type"), + converted_generic_org_type=Case( + # When portfolio is present, use its value instead + When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__organization_type")), + # Otherwise, return the natively assigned value + default=F("domain_info__generic_org_type"), + ), + converted_federal_agency=Case( + # When portfolio is present, use its value instead + When( + Q(domain_info__portfolio__isnull=False) & Q(domain_info__portfolio__federal_agency__isnull=False), + then=F("domain_info__portfolio__federal_agency__agency"), ), - converted_federal_agency=Case( - # When portfolio is present, use its value instead - When( - Q(domain_info__portfolio__isnull=False) & Q(domain_info__portfolio__federal_agency__isnull=False), - then=F("domain_info__portfolio__federal_agency__agency") - ), - # Otherwise, return the natively assigned value - default=F("domain_info__federal_agency__agency"), + # Otherwise, return the natively assigned value + default=F("domain_info__federal_agency__agency"), + ), + converted_federal_type=Case( + # When portfolio is present, use its value instead + When( + Q(domain_info__portfolio__isnull=False) & Q(domain_info__portfolio__federal_agency__isnull=False), + then=F("domain_info__portfolio__federal_agency__federal_type"), ), - converted_federal_type=Case( - # When portfolio is present, use its value instead - When( - Q(domain_info__portfolio__isnull=False) & Q(domain_info__portfolio__federal_agency__isnull=False), - then=F("domain_info__portfolio__federal_agency__federal_type") - ), - # Otherwise, return the natively assigned value - default=F("domain_info__federal_agency__federal_type"), - ), - converted_organization_name=Case( - # When portfolio is present, use its value instead - When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__organization_name")), - # Otherwise, return the natively assigned value - default=F("domain_info__organization_name"), - ), - converted_city=Case( - # When portfolio is present, use its value instead - When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__city")), - # Otherwise, return the natively assigned value - default=F("domain_info__city"), - ), - converted_state_territory=Case( - # When portfolio is present, use its value instead - When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__state_territory")), - # Otherwise, return the natively assigned value - default=F("domain_info__state_territory"), - ), - ) + # Otherwise, return the natively assigned value + default=F("domain_info__federal_agency__federal_type"), + ), + converted_organization_name=Case( + # When portfolio is present, use its value instead + When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__organization_name")), + # Otherwise, return the natively assigned value + default=F("domain_info__organization_name"), + ), + converted_city=Case( + # When portfolio is present, use its value instead + When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__city")), + # Otherwise, return the natively assigned value + default=F("domain_info__city"), + ), + converted_state_territory=Case( + # When portfolio is present, use its value instead + When(domain_info__portfolio__isnull=False, then=F("domain_info__portfolio__state_territory")), + # Otherwise, return the natively assigned value + default=F("domain_info__state_territory"), + ), + ) # Filters list_filter = [GenericOrgFilter, FederalTypeFilter, ElectionOfficeFilter, "state"] diff --git a/src/registrar/models/domain_information.py b/src/registrar/models/domain_information.py index 3fb7e3e8d..378d59137 100644 --- a/src/registrar/models/domain_information.py +++ b/src/registrar/models/domain_information.py @@ -426,7 +426,6 @@ class DomainInformation(TimeStampedModel): else: return None - # ----- Portfolio Properties ----- @property @@ -434,7 +433,7 @@ class DomainInformation(TimeStampedModel): if self.portfolio: return self.portfolio.organization_name return self.organization_name - + @property def converted_generic_org_type(self): if self.portfolio: @@ -495,16 +494,15 @@ class DomainInformation(TimeStampedModel): return self.portfolio.display_urbanization return self.display_urbanization - # ----- Portfolio Properties (display values)----- @property def converted_generic_org_type_display(self): if self.portfolio: return self.portfolio.get_organization_type_display() return self.get_generic_org_type_display() - + @property def converted_federal_type_display(self): if self.portfolio: return self.portfolio.federal_agency.get_federal_type_display() - return self.get_federal_type_display() \ No newline at end of file + return self.get_federal_type_display() diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 780bd8719..3fa889a3b 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -1479,16 +1479,15 @@ class DomainRequest(TimeStampedModel): return self.portfolio.senior_official return self.senior_official - # ----- Portfolio Properties (display values)----- @property def converted_generic_org_type_display(self): if self.portfolio: return self.portfolio.get_organization_type_display() return self.get_generic_org_type_display() - + @property def converted_federal_type_display(self): if self.portfolio: return self.portfolio.federal_agency.get_federal_type_display() - return self.get_federal_type_display() \ No newline at end of file + return self.get_federal_type_display() diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index 055cd39f7..e1f4f5a27 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -563,7 +563,9 @@ class MockDb(TestCase): cls.federal_agency_1, _ = FederalAgency.objects.get_or_create(agency="World War I Centennial Commission") cls.federal_agency_2, _ = FederalAgency.objects.get_or_create(agency="Armed Forces Retirement Home") - cls.federal_agency_3, _ = FederalAgency.objects.get_or_create(agency="Portfolio 1 Federal Agency",federal_type="executive") + cls.federal_agency_3, _ = FederalAgency.objects.get_or_create( + agency="Portfolio 1 Federal Agency", federal_type="executive" + ) cls.portfolio_1, _ = Portfolio.objects.get_or_create( creator=cls.custom_superuser, federal_agency=cls.federal_agency_3, organization_type="federal" diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index 305340a2a..888abe302 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -53,12 +53,6 @@ from datetime import datetime from django.contrib.admin.models import LogEntry, ADDITION from django.contrib.contenttypes.models import ContentType -# ---Logger -import logging -from venv import logger -from registrar.management.commands.utility.terminal_helper import TerminalColors, TerminalHelper -logger = logging.getLogger(__name__) - class CsvReportsTest(MockDbForSharedTests): """Tests to determine if we are uploading our reports correctly.""" @@ -257,20 +251,25 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib): # We expect READY domains, # sorted alphabetially by domain name expected_content = ( - "Domain name,Status,First ready on,Expiration date,Domain type,Agency,Organization name,City,State,SO,SO email," + "Domain name,Status,First ready on,Expiration date,Domain type,Agency," + "Organization name,City,State,SO,SO email," "Security contact email,Domain managers,Invited domain managers\n" - "adomain2.gov,Dns needed,(blank),(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank)," + "adomain2.gov,Dns needed,(blank),(blank),Federal - Executive," + "Portfolio 1 Federal Agency,,,, ,,(blank)," "meoward@rocks.com,squeaker@rocks.com\n" - "defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank)," + "defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive," + "Portfolio 1 Federal Agency,,,, ,,(blank)," '"big_lebowski@dude.co, info@example.com, meoward@rocks.com",woofwardthethird@rocks.com\n' - "cdomain11.gov,Ready,2024-04-02,(blank),Federal - Executive,World War I Centennial Commission,,,, ,,(blank)," + "cdomain11.gov,Ready,2024-04-02,(blank),Federal - Executive," + "World War I Centennial Commission,,,, ,,(blank)," "meoward@rocks.com,\n" "adomain10.gov,Ready,2024-04-03,(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),," "squeaker@rocks.com\n" "bdomain4.gov,Unknown,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" "bdomain5.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" "bdomain6.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" - "ddomain3.gov,On hold,(blank),2023-11-15,Federal,Armed Forces Retirement Home,,,, ,,security@mail.gov,,\n" + "ddomain3.gov,On hold,(blank),2023-11-15,Federal," + "Armed Forces Retirement Home,,,, ,,security@mail.gov,,\n" "sdomain8.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" "xdomain7.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" "zdomain9.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n" @@ -786,10 +785,13 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib): "Purpose of the site,There is more,Testy Tester testy2@town.com,,city.com,\n" "city3.gov,Submitted,Federal,Executive,Portfolio 1 Federal Agency,,N/A,,,2,,,,0,1," '"cheeseville.gov, city1.gov, igorville.gov",,,,,Purpose of the site,CISA-first-name CISA-last-name | ' - 'There is more,"Meow Tester24 te2@town.com, Testy1232 Tester24 te2@town.com, Testy Tester testy2@town.com",' - "test@igorville.com,\"city.com, https://www.example2.com, https://www.example.com\",\n" - "city4.gov,Submitted,City,Executive,,Testorg,Yes,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com," - "Chief Tester,Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester testy2@town.com," + 'There is more,"Meow Tester24 te2@town.com, Testy1232 Tester24 te2@town.com, ' + 'Testy Tester testy2@town.com",' + 'test@igorville.com,"city.com, https://www.example2.com, https://www.example.com",\n' + "city4.gov,Submitted,City,Executive,,Testorg,Yes,,NY,2,,,,0,1,city1.gov,Testy," + "Tester,testy@town.com," + "Chief Tester,Purpose of the site,CISA-first-name CISA-last-name | There is more," + "Testy Tester testy2@town.com," "cisaRep@igorville.gov,city.com,\n" "city6.gov,Submitted,Federal,Executive,Portfolio 1 Federal Agency,,N/A,,,2,,,,0,1,city1.gov,,,,," "Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester testy2@town.com," diff --git a/src/registrar/utility/csv_export.py b/src/registrar/utility/csv_export.py index ed314812e..2758375b1 100644 --- a/src/registrar/utility/csv_export.py +++ b/src/registrar/utility/csv_export.py @@ -231,7 +231,7 @@ class BaseExport(ABC): # Return rows that for easier parsing and testing return rows - + @classmethod def get_annotated_queryset(cls, **kwargs): """Returns an annotated queryset based off of all query conditions.""" @@ -546,7 +546,8 @@ class DomainExport(BaseExport): # When portfolio is present, use its value instead When( Q(portfolio__isnull=False) & Q(portfolio__federal_agency__isnull=False), - then=F("portfolio__federal_agency__agency")), + then=F("portfolio__federal_agency__agency"), + ), # Otherwise, return the natively assigned value default=F("federal_agency__agency"), output_field=CharField(), @@ -769,20 +770,16 @@ class DomainExport(BaseExport): """Returns a list of Domain Requests that has been filtered by the given organization value.""" annotated_queryset = domain_infos_to_filter.annotate( - converted_generic_org_type=Case( - # Recreate the logic of the converted_generic_org_type property - # here in annotations - When( - portfolio__isnull=False, - then=F("portfolio__organization_type") - ), - default=F("generic_org_type"), - output_field=CharField(), - ) + converted_generic_org_type=Case( + # Recreate the logic of the converted_generic_org_type property + # here in annotations + When(portfolio__isnull=False, then=F("portfolio__organization_type")), + default=F("generic_org_type"), + output_field=CharField(), ) + ) return annotated_queryset.filter(converted_generic_org_type=org_to_filter_by) - @classmethod def get_sliced_domains(cls, filter_condition): """Get filtered domains counts sliced by org type and election office. @@ -1614,19 +1611,16 @@ class DomainRequestExport(BaseExport): def get_filtered_domain_requests_by_org(domain_requests_to_filter, org_to_filter_by): """Returns a list of Domain Requests that has been filtered by the given organization value""" annotated_queryset = domain_requests_to_filter.annotate( - converted_generic_org_type=Case( - # Recreate the logic of the converted_generic_org_type property - # here in annotations - When( - portfolio__isnull=False, - then=F("portfolio__organization_type") - ), - default=F("generic_org_type"), - output_field=CharField(), - ) + converted_generic_org_type=Case( + # Recreate the logic of the converted_generic_org_type property + # here in annotations + When(portfolio__isnull=False, then=F("portfolio__organization_type")), + default=F("generic_org_type"), + output_field=CharField(), ) + ) return annotated_queryset.filter(converted_generic_org_type=org_to_filter_by) - + # return domain_requests_to_filter.filter( # # Filter based on the generic org value returned by converted_generic_org_type # id__in=[ @@ -1636,9 +1630,6 @@ class DomainRequestExport(BaseExport): # and domainRequest.converted_generic_org_type == org_to_filter_by # ] # ) - - - @classmethod def get_computed_fields(cls, delimiter=", ", **kwargs): @@ -1661,21 +1652,10 @@ class DomainRequestExport(BaseExport): # When portfolio is present, use its value instead When( Q(portfolio__isnull=False) & Q(portfolio__federal_agency__isnull=False), - then=F("portfolio__federal_agency__agency") - ), - # Otherwise, return the natively assigned value - default=F("federal_agency__agency"), - output_field=CharField(), - ), - "converted_federal_type": Case( - # When portfolio is present, use its value instead - # NOTE: this is an @Property funciton in portfolio. - When( - Q(portfolio__isnull=False) & Q(portfolio__federal_agency__isnull=False), - then=F("portfolio__federal_agency__federal_type"), + then=F("portfolio__federal_agency__agency"), ), # Otherwise, return the natively assigned value - default=F("federal_type"), + default=F("federal_agency__agency"), output_field=CharField(), ), "converted_federal_type": Case( diff --git a/src/registrar/views/portfolios.py b/src/registrar/views/portfolios.py index 429934dcf..880472509 100644 --- a/src/registrar/views/portfolios.py +++ b/src/registrar/views/portfolios.py @@ -625,4 +625,4 @@ class NewMemberView(PortfolioMembersPermissionView, FormMixin): else: if permission_exists: messages.warning(self.request, "User is already a member of this portfolio.") - return redirect(self.get_success_url()) \ No newline at end of file + return redirect(self.get_success_url())