Skip to content

Commit

Permalink
Merge pull request #2618 from cisagov/ms/2451-additional-domain-reque…
Browse files Browse the repository at this point in the history
…st-dates

Issue #2541 additional domain request dates [getgov-litterbox]
  • Loading branch information
Matt-Spence authored Aug 29, 2024
2 parents c19bc89 + fc17854 commit ec56f17
Show file tree
Hide file tree
Showing 24 changed files with 219 additions and 69 deletions.
22 changes: 22 additions & 0 deletions docs/operations/data_migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -816,3 +816,25 @@ Example: `cf ssh getgov-za`
| | Parameter | Description |
|:-:|:-------------------------- |:-----------------------------------------------------------------------------------|
| 1 | **federal_cio_csv_path** | Specifies where the federal CIO csv is |

## Populate Domain Request Dates
This section outlines how to run the populate_domain_request_dates script

### Running on sandboxes

#### Step 1: Login to CloudFoundry
```cf login -a api.fr.cloud.gov --sso```

#### Step 2: SSH into your environment
```cf ssh getgov-{space}```

Example: `cf ssh getgov-za`

#### Step 3: Create a shell instance
```/tmp/lifecycle/shell```

#### Step 4: Running the script
```./manage.py populate_domain_request_dates```

### Running locally
```docker-compose exec app ./manage.py populate_domain_request_dates```
6 changes: 4 additions & 2 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,9 @@ def queryset(self, request, queryset):
# Columns
list_display = [
"requested_domain",
"submission_date",
"first_submitted_date",
"last_submitted_date",
"last_status_update",
"status",
"generic_org_type",
"federal_type",
Expand Down Expand Up @@ -1901,7 +1903,7 @@ def get_fieldsets(self, request, obj=None):
# Table ordering
# NOTE: This impacts the select2 dropdowns (combobox)
# Currentl, there's only one for requests on DomainInfo
ordering = ["-submission_date", "requested_domain__name"]
ordering = ["-last_submitted_date", "requested_domain__name"]

change_form_template = "django/admin/domain_request_change_form.html"

Expand Down
4 changes: 2 additions & 2 deletions src/registrar/assets/js/get-gov.js
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,7 @@ document.addEventListener('DOMContentLoaded', function() {
const domainName = request.requested_domain ? request.requested_domain : `New domain request <br><span class="text-base font-body-xs">(${utcDateString(request.created_at)})</span>`;
const actionUrl = request.action_url;
const actionLabel = request.action_label;
const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString('en-US', options) : `<span class="text-base">Not submitted</span>`;
const submissionDate = request.last_submitted_date ? new Date(request.last_submitted_date).toLocaleDateString('en-US', options) : `<span class="text-base">Not submitted</span>`;

// Even if the request is not deletable, we may need this empty string for the td if the deletable column is displayed
let modalTrigger = '';
Expand Down Expand Up @@ -1699,7 +1699,7 @@ document.addEventListener('DOMContentLoaded', function() {
<th scope="row" role="rowheader" data-label="Domain name">
${domainName}
</th>
<td data-sort-value="${new Date(request.submission_date).getTime()}" data-label="Date submitted">
<td data-sort-value="${new Date(request.last_submitted_date).getTime()}" data-label="Date submitted">
${submissionDate}
</td>
<td data-label="Status">
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/fixtures_domain_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def _set_non_foreign_key_fields(cls, da: DomainRequest, app: dict):

# TODO for a future ticket: Allow for more than just "federal" here
da.generic_org_type = app["generic_org_type"] if "generic_org_type" in app else "federal"
da.submission_date = fake.date()
da.last_submitted_date = fake.date()
da.federal_type = (
app["federal_type"]
if "federal_type" in app
Expand Down
45 changes: 45 additions & 0 deletions src/registrar/management/commands/populate_domain_request_dates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import logging
from django.core.management import BaseCommand
from registrar.management.commands.utility.terminal_helper import PopulateScriptTemplate, TerminalColors
from registrar.models import DomainRequest
from auditlog.models import LogEntry

logger = logging.getLogger(__name__)


class Command(BaseCommand, PopulateScriptTemplate):
help = "Loops through each domain request object and populates the last_status_update and first_submitted_date"

def handle(self, **kwargs):
"""Loops through each DomainRequest object and populates
its last_status_update and first_submitted_date values"""
self.mass_update_records(DomainRequest, None, ["last_status_update", "first_submitted_date"])

def update_record(self, record: DomainRequest):
"""Defines how we update the first_submitted_date and last_status_update fields"""

# Retrieve and order audit log entries by timestamp in descending order
audit_log_entries = LogEntry.objects.filter(object_pk=record.pk).order_by("-timestamp")
# Loop through logs in descending order to find most recent status change
for log_entry in audit_log_entries:
if "status" in log_entry.changes_dict:
record.last_status_update = log_entry.timestamp.date()
break

# Loop through logs in ascending order to find first submission
for log_entry in audit_log_entries.reverse():
status = log_entry.changes_dict.get("status")
if status and status[1] == "submitted":
record.first_submitted_date = log_entry.timestamp.date()
break

logger.info(
f"""{TerminalColors.OKCYAN}Updating {record} =>
first submitted date: {record.first_submitted_date},
last status update: {record.last_status_update}{TerminalColors.ENDC}
"""
)

def should_skip_record(self, record) -> bool:
# make sure the record had some kind of history
return not LogEntry.objects.filter(object_pk=record.pk).exists()
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def mass_update_records(self, object_class, filter_conditions, fields_to_update,
You must define update_record before you can use this function.
"""

records = object_class.objects.filter(**filter_conditions)
records = object_class.objects.filter(**filter_conditions) if filter_conditions else object_class.objects.all()
readable_class_name = self.get_class_name(object_class)

# Code execution will stop here if the user prompts "N"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 4.2.10 on 2024-08-16 15:28

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("registrar", "0119_remove_user_portfolio_and_more"),
]

operations = [
migrations.RenameField(
model_name="domainrequest",
old_name="submission_date",
new_name="last_submitted_date",
),
migrations.AlterField(
model_name="domainrequest",
name="last_submitted_date",
field=models.DateField(
blank=True, default=None, help_text="Date last submitted", null=True, verbose_name="last submitted on"
),
),
migrations.AddField(
model_name="domainrequest",
name="first_submitted_date",
field=models.DateField(
blank=True,
default=None,
help_text="Date initially submitted",
null=True,
verbose_name="first submitted on",
),
),
migrations.AddField(
model_name="domainrequest",
name="last_status_update",
field=models.DateField(
blank=True,
default=None,
help_text="Date of the last status update",
null=True,
verbose_name="last updated on",
),
),
]
36 changes: 30 additions & 6 deletions src/registrar/models/domain_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,15 +563,32 @@ def get_action_needed_reason_label(cls, action_needed_reason: str):
help_text="Acknowledged .gov acceptable use policy",
)

# submission date records when domain request is submitted
submission_date = models.DateField(
# Records when the domain request was first submitted
first_submitted_date = models.DateField(
null=True,
blank=True,
default=None,
verbose_name="submitted at",
help_text="Date submitted",
verbose_name="first submitted on",
help_text="Date initially submitted",
)

# Records when domain request was last submitted
last_submitted_date = models.DateField(
null=True,
blank=True,
default=None,
verbose_name="last submitted on",
help_text="Date last submitted",
)

# Records when domain request status was last updated by an admin or analyst
last_status_update = models.DateField(
null=True,
blank=True,
default=None,
verbose_name="last updated on",
help_text="Date of the last status update",
)
notes = models.TextField(
null=True,
blank=True,
Expand Down Expand Up @@ -621,6 +638,9 @@ def save(self, *args, **kwargs):
self.sync_organization_type()
self.sync_yes_no_form_fields()

if self._cached_status != self.status:
self.last_status_update = timezone.now().date()

super().save(*args, **kwargs)

# Handle the action needed email.
Expand Down Expand Up @@ -803,8 +823,12 @@ def submit(self):
if not DraftDomain.string_could_be_domain(self.requested_domain.name):
raise ValueError("Requested domain is not a valid domain name.")

# Update submission_date to today
self.submission_date = timezone.now().date()
# if the domain has not been submitted before this must be the first time
if not self.first_submitted_date:
self.first_submitted_date = timezone.now().date()

# Update last_submitted_date to today
self.last_submitted_date = timezone.now().date()
self.save()

# Limit email notifications to transitions from Started and Withdrawn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Action needed

----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Action needed

----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Action needed

----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that you’ll need to complete before we continue reviewing your .gov domain request.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Action needed

----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
Your .gov domain request has been withdrawn and will not be reviewed by our team.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Withdrawn

----------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/templates/emails/status_change_approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
Congratulations! Your .gov domain request has been approved.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Approved

You can manage your approved domain on the .gov registrar <https://manage.get.gov>.
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/templates/emails/status_change_rejected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
Your .gov domain request has been rejected.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Rejected

----------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/templates/emails/submission_confirmation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We received your .gov domain request.

DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
STATUS: Submitted

----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ <h2 id="domain-requests-header" class="flex-6">Domain requests</h2>
<thead>
<tr>
<th data-sortable="requested_domain__name" scope="col" role="columnheader">Domain name</th>
<th data-sortable="submission_date" scope="col" role="columnheader">Date submitted</th>
<th data-sortable="last_submitted_date" scope="col" role="columnheader">Date submitted</th>
<th data-sortable="status" scope="col" role="columnheader">Status</th>
<th scope="col" role="columnheader"><span class="usa-sr-only">Action</span></th>
<!-- AJAX will conditionally add a th for delete actions -->
Expand Down
6 changes: 3 additions & 3 deletions src/registrar/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,13 +777,13 @@ def sharedSetUp(cls):
cls.domain_request_3.alternative_domains.add(website, website_2)
cls.domain_request_3.current_websites.add(website_3, website_4)
cls.domain_request_3.cisa_representative_email = "[email protected]"
cls.domain_request_3.submission_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_3.last_submitted_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_3.save()

cls.domain_request_4.submission_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_4.last_submitted_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_4.save()

cls.domain_request_6.submission_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_6.last_submitted_date = get_time_aware_date(datetime(2024, 4, 2))
cls.domain_request_6.save()

@classmethod
Expand Down
Loading

0 comments on commit ec56f17

Please sign in to comment.