diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index babc955aa..101534034 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -11,6 +11,7 @@ from registrar.models.federal_agency import FederalAgency from registrar.models.utility.generic_helper import CreateOrUpdateOrganizationTypeHelper from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes from registrar.utility.constants import BranchChoices +from auditlog.models import LogEntry from .utility.time_stamped_model import TimeStampedModel from ..utility.email import send_templated_email, EmailSendingError @@ -576,11 +577,25 @@ class DomainRequest(TimeStampedModel): verbose_name="last updated on", help_text="Date of the last status update", ) + notes = models.TextField( null=True, blank=True, ) + def get_first_status_set_date(self, status): + """Returns the date when the domain request was first set to the given status.""" + log_entry = ( + LogEntry.objects.filter(content_type__model="domainrequest", object_pk=self.pk, changes__status__1=status) + .order_by("-timestamp") + .first() + ) + return log_entry.timestamp.date() if log_entry else None + + def get_first_status_started_date(self): + """Returns the date when the domain request was put into the status "started" for the first time""" + return self.get_first_status_set_date(DomainRequest.DomainRequestStatus.STARTED) + @classmethod def get_statuses_that_send_emails(cls): """Returns a list of statuses that send an email to the user""" @@ -1138,6 +1153,11 @@ class DomainRequest(TimeStampedModel): data[field.name] = field.value_from_object(self) return data + def get_formatted_cisa_rep_name(self): + """Returns the cisa representatives name in Western order.""" + names = [n for n in [self.cisa_representative_first_name, self.cisa_representative_last_name] if n] + return " ".join(names) if names else "Unknown" + def _is_federal_complete(self): # Federal -> "Federal government branch" page can't be empty + Federal Agency selection can't be None return not (self.federal_type is None or self.federal_agency is None) diff --git a/src/registrar/models/utility/generic_helper.py b/src/registrar/models/utility/generic_helper.py index 8c44a3bdd..3cafe87c4 100644 --- a/src/registrar/models/utility/generic_helper.py +++ b/src/registrar/models/utility/generic_helper.py @@ -3,6 +3,7 @@ import time import logging from urllib.parse import urlparse, urlunparse, urlencode +from django.urls import resolve, Resolver404 logger = logging.getLogger(__name__) @@ -315,3 +316,21 @@ def convert_queryset_to_dict(queryset, is_model=True, key="id"): request_dict = {value[key]: value for value in queryset} return request_dict + + +def get_url_name(path): + """ + Given a URL path, returns the corresponding URL name defined in urls.py. + + Args: + path (str): The URL path to resolve. + + Returns: + str or None: The URL name if it exists, otherwise None. + """ + try: + match = resolve(path) + return match.url_name + except Resolver404: + logger.error(f"No matching URL name found for path: {path}") + return None diff --git a/src/registrar/templates/domain_request_status.html b/src/registrar/templates/domain_request_status.html index 944371a6a..8bc083835 100644 --- a/src/registrar/templates/domain_request_status.html +++ b/src/registrar/templates/domain_request_status.html @@ -8,33 +8,30 @@ {% block content %}
- {% comment %} - TODO: Uncomment in #2596 {% if portfolio %} {% url 'domain-requests' as url %} - +

Domain request for {{ DomainRequest.requested_domain.name }}

Status: - {% if DomainRequest.status == 'approved' %} Approved - {% elif DomainRequest.status == 'in review' %} In review - {% elif DomainRequest.status == 'rejected' %} Rejected - {% elif DomainRequest.status == 'submitted' %} Submitted - {% elif DomainRequest.status == 'ineligible' %} Ineligible - {% else %}ERROR Please contact technical support/dev - {% endif %} + {{ DomainRequest.get_status_display|default:"ERROR Please contact technical support/dev" }}


-

Last updated: {{DomainRequest.updated_at|date:"F j, Y"}}

- + + {% with statuses=DomainRequest.DomainRequestStatus last_submitted=DomainRequest.last_submitted_date|date:"F j, Y" first_submitted=DomainRequest.first_submitted_date|date:"F j, Y" last_status_update=DomainRequest.last_status_update|date:"F j, Y" %} + {% comment %} + These are intentionally seperated this way. + There is some code repetition, but it gives us more flexibility rather than a dense reduction. + Leave it this way until we've solidified our requirements. + {% endcomment %} + {% if DomainRequest.status == statuses.STARTED %} + {% with first_started_date=DomainRequest.get_first_status_started_date|date:"F j, Y" %} +

+ {% comment %} + A newly created domain request will not have a value for last_status update. + This is because the status never really updated. + However, if this somehow goes back to started we can default to displaying that new date. + {% endcomment %} + Started on: {{last_status_update|default:first_started_date}} +

+ {% endwith %} + {% elif DomainRequest.status == statuses.SUBMITTED %} +

+ Submitted on: {{last_submitted|default:first_submitted }} +

+

+ Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

+ {% elif DomainRequest.status == statuses.ACTION_NEEDED %} +

+ Submitted on: {{last_submitted|default:first_submitted }} +

+

+ Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

+ {% elif DomainRequest.status == statuses.REJECTED %} +

+ Submitted on: {{last_submitted|default:first_submitted }} +

+

+ Rejected on: {{last_status_update}} +

+ {% elif DomainRequest.status == statuses.WITHDRAWN %} +

+ Submitted on: {{last_submitted|default:first_submitted }} +

+

+ Withdrawn on: {{last_status_update}} +

+ {% else %} + {% comment %} Shown for in_review, approved, ineligible {% endcomment %} +

+ Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

+ {% endif %} + {% if DomainRequest.status != 'rejected' %}

{% include "includes/domain_request.html" %}

Withdraw request

{% endif %} + {% endwith %}
@@ -141,8 +184,8 @@ {% if DomainRequest %}

CISA Regional Representative