Merge remote-tracking branch 'origin/main' into ms/2451-additional-domain-request-dates

This commit is contained in:
Matthew Spence 2024-08-21 12:25:59 -05:00
commit eac757a6a6
No known key found for this signature in database
23 changed files with 626 additions and 96 deletions

View file

@ -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
@ -424,3 +430,10 @@ class DomainInformation(TimeStampedModel):
def _get_many_to_many_fields():
"""Returns a set of each field.name that has the many to many relation"""
return {field.name for field in DomainInformation._meta.many_to_many} # type: ignore
def get_state_display_of_domain(self):
"""Returns the state display of the underlying domain record"""
if self.domain:
return self.domain.get_state_display()
else:
return None

View file

@ -665,23 +665,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

View file

@ -2,6 +2,7 @@ from django.db import models
from registrar.models.domain_request import DomainRequest
from registrar.models.federal_agency import FederalAgency
from registrar.utility.constants import BranchChoices
from .utility.time_stamped_model import TimeStampedModel
@ -12,6 +13,10 @@ class Portfolio(TimeStampedModel):
manageable groups.
"""
# Addresses the UnorderedObjectListWarning
class Meta:
ordering = ["organization_name"]
# use the short names in Django admin
OrganizationChoices = DomainRequest.OrganizationChoices
StateTerritoryChoices = DomainRequest.StateTerritoryChoices
@ -21,11 +26,25 @@ class Portfolio(TimeStampedModel):
creator = models.ForeignKey(
"registrar.User",
on_delete=models.PROTECT,
help_text="Associated user",
verbose_name="Portfolio creator",
related_name="created_portfolios",
unique=False,
)
organization_name = models.CharField(
null=True,
blank=True,
verbose_name="Portfolio organization",
)
organization_type = models.CharField(
max_length=255,
choices=OrganizationChoices.choices,
null=True,
blank=True,
help_text="Type of organization",
)
notes = models.TextField(
null=True,
blank=True,
@ -42,25 +61,11 @@ class Portfolio(TimeStampedModel):
senior_official = models.ForeignKey(
"registrar.SeniorOfficial",
on_delete=models.PROTECT,
help_text="Associated senior official",
unique=False,
null=True,
blank=True,
)
organization_type = models.CharField(
max_length=255,
choices=OrganizationChoices.choices,
null=True,
blank=True,
help_text="Type of organization",
)
organization_name = models.CharField(
null=True,
blank=True,
)
address_line1 = models.CharField(
null=True,
blank=True,
@ -109,7 +114,7 @@ class Portfolio(TimeStampedModel):
)
def __str__(self) -> str:
return f"{self.organization_name}"
return str(self.organization_name)
def save(self, *args, **kwargs):
"""Save override for custom properties"""
@ -119,3 +124,35 @@ class Portfolio(TimeStampedModel):
self.urbanization = None
super().save(*args, **kwargs)
@property
def portfolio_type(self):
"""
Returns a combination of organization_type / federal_type, seperated by ' - '.
If no federal_type is found, we just return the org type.
"""
org_type_label = self.OrganizationChoices.get_org_label(self.organization_type)
agency_type_label = BranchChoices.get_branch_label(self.federal_type)
if self.organization_type == self.OrganizationChoices.FEDERAL and agency_type_label:
return " - ".join([org_type_label, agency_type_label])
else:
return org_type_label
@property
def federal_type(self):
"""Returns the federal_type value on the underlying federal_agency field"""
return self.federal_agency.federal_type if self.federal_agency else None
# == Getters for domains == #
def get_domains(self):
"""Returns all DomainInformations associated with this portfolio"""
return self.information_portfolio.all()
def get_domain_requests(self):
"""Returns all DomainRequests associated with this portfolio"""
return self.DomainRequest_portfolio.all()
# == Getters for suborganization == #
def get_suborganizations(self):
"""Returns all suborganizations associated with this portfolio"""
return self.portfolio_suborganizations.all()

View file

@ -16,6 +16,7 @@ class Suborganization(TimeStampedModel):
portfolio = models.ForeignKey(
"registrar.Portfolio",
on_delete=models.PROTECT,
related_name="portfolio_suborganizations",
)
def __str__(self) -> str: