Merge branch 'main' into za/1901-allow-analysts-to-customize-action-needed-emails

This commit is contained in:
zandercymatics 2024-07-02 11:29:08 -06:00
commit 083ed6fb25
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
46 changed files with 575 additions and 563 deletions

View file

@ -15,7 +15,6 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from dateutil.relativedelta import relativedelta # type: ignore
from epplibwrapper.errors import ErrorCode, RegistryError
from registrar.models.user_domain_role import UserDomainRole
from waffle.admin import FlagAdmin
@ -449,7 +448,7 @@ class AdminSortFields:
sort_mapping = {
# == Contact == #
"other_contacts": (Contact, _name_sort),
"authorizing_official": (Contact, _name_sort),
"senior_official": (Contact, _name_sort),
"submitter": (Contact, _name_sort),
# == User == #
"creator": (User, _name_sort),
@ -1240,7 +1239,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
fieldsets = [
(None, {"fields": ["portfolio", "creator", "submitter", "domain_request", "notes"]}),
(".gov domain", {"fields": ["domain"]}),
("Contacts", {"fields": ["authorizing_official", "other_contacts", "no_other_contacts_rationale"]}),
("Contacts", {"fields": ["senior_official", "other_contacts", "no_other_contacts_rationale"]}),
("Background info", {"fields": ["anything_else"]}),
(
"Type of organization",
@ -1314,7 +1313,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
autocomplete_fields = [
"creator",
"domain_request",
"authorizing_official",
"senior_official",
"domain",
"submitter",
]
@ -1539,7 +1538,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
"Contacts",
{
"fields": [
"authorizing_official",
"senior_official",
"other_contacts",
"no_other_contacts_rationale",
"cisa_representative_first_name",
@ -1629,7 +1628,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
"requested_domain",
"submitter",
"creator",
"authorizing_official",
"senior_official",
"investigator",
]
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
@ -2063,7 +2062,7 @@ class DomainInformationInline(admin.StackedInline):
autocomplete_fields = [
"creator",
"domain_request",
"authorizing_official",
"senior_official",
"domain",
"submitter",
]
@ -2261,25 +2260,12 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
extra_context["state_help_message"] = Domain.State.get_admin_help_text(domain.state)
extra_context["domain_state"] = domain.get_state_display()
# Pass in what the an extended expiration date would be for the expiration date modal
self._set_expiration_date_context(domain, extra_context)
extra_context["curr_exp_date"] = (
domain.expiration_date if domain.expiration_date is not None else self._get_current_date()
)
return super().changeform_view(request, object_id, form_url, extra_context)
def _set_expiration_date_context(self, domain, extra_context):
"""Given a domain, calculate the an extended expiration date
from the current registry expiration date."""
years_to_extend_by = self._get_calculated_years_for_exp_date(domain)
try:
curr_exp_date = domain.registry_expiration_date
except KeyError:
# No expiration date was found. Return none.
extra_context["extended_expiration_date"] = None
else:
new_date = curr_exp_date + relativedelta(years=years_to_extend_by)
extra_context["extended_expiration_date"] = new_date
def response_change(self, request, obj):
# Create dictionary of action functions
ACTION_FUNCTIONS = {
@ -2307,11 +2293,9 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
self.message_user(request, "Object is not of type Domain.", messages.ERROR)
return None
years = self._get_calculated_years_for_exp_date(obj)
# Renew the domain.
try:
obj.renew_domain(length=years)
obj.renew_domain()
self.message_user(
request,
"Successfully extended the expiration date.",
@ -2336,37 +2320,6 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
return HttpResponseRedirect(".")
def _get_calculated_years_for_exp_date(self, obj, extension_period: int = 1):
"""Given the current date, an extension period, and a registry_expiration_date
on the domain object, calculate the number of years needed to extend the
current expiration date by the extension period.
"""
# Get the date we want to update to
desired_date = self._get_current_date() + relativedelta(years=extension_period)
# Grab the current expiration date
try:
exp_date = obj.registry_expiration_date
except KeyError:
# if no expiration date from registry, set it to today
logger.warning("current expiration date not set; setting to today")
exp_date = self._get_current_date()
# If the expiration date is super old (2020, for example), we need to
# "catch up" to the current year, so we add the difference.
# If both years match, then lets just proceed as normal.
calculated_exp_date = exp_date + relativedelta(years=extension_period)
year_difference = desired_date.year - exp_date.year
years = extension_period
if desired_date > calculated_exp_date:
# Max probably isn't needed here (no code flow), but it guards against negative and 0.
# In both of those cases, we just want to extend by the extension_period.
years = max(extension_period, year_difference)
return years
# Workaround for unit tests, as we cannot mock date directly.
# it is immutable. Rather than dealing with a convoluted workaround,
# lets wrap this in a function.