mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-17 18:09:25 +02:00
Update migrations
This commit is contained in:
commit
1bfc2dfa79
25 changed files with 220 additions and 70 deletions
|
@ -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```
|
||||
|
|
|
@ -1691,7 +1691,9 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
# Columns
|
||||
list_display = [
|
||||
"requested_domain",
|
||||
"submission_date",
|
||||
"first_submitted_date",
|
||||
"last_submitted_date",
|
||||
"last_status_update",
|
||||
"status",
|
||||
"generic_org_type",
|
||||
"federal_type",
|
||||
|
@ -1889,7 +1891,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
# 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"
|
||||
|
||||
|
|
|
@ -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 = '';
|
||||
|
@ -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">
|
||||
|
|
|
@ -94,7 +94,7 @@ class DomainRequestFixture:
|
|||
|
||||
# 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
|
||||
|
|
|
@ -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()
|
|
@ -86,7 +86,7 @@ class PopulateScriptTemplate(ABC):
|
|||
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"
|
||||
|
|
|
@ -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",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -8,7 +8,7 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("registrar", "0119_remove_user_portfolio_and_more"),
|
||||
("registrar", "0120_add_domainrequest_submission_dates"),
|
||||
]
|
||||
|
||||
operations = [
|
|
@ -550,15 +550,32 @@ class DomainRequest(TimeStampedModel):
|
|||
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,
|
||||
|
@ -608,6 +625,9 @@ class DomainRequest(TimeStampedModel):
|
|||
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.
|
||||
|
@ -787,8 +807,12 @@ class DomainRequest(TimeStampedModel):
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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>.
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<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 -->
|
||||
|
|
|
@ -775,13 +775,13 @@ class MockDb(TestCase):
|
|||
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 = "test@igorville.com"
|
||||
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
|
||||
|
|
|
@ -448,7 +448,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
# Assert that our sort works correctly
|
||||
self.test_helper.assert_table_sorted(
|
||||
"11",
|
||||
"13",
|
||||
(
|
||||
"creator__first_name",
|
||||
"creator__last_name",
|
||||
|
@ -457,7 +457,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
# Assert that sorting in reverse works correctly
|
||||
self.test_helper.assert_table_sorted(
|
||||
"-11",
|
||||
"-13",
|
||||
(
|
||||
"-creator__first_name",
|
||||
"-creator__last_name",
|
||||
|
@ -480,7 +480,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
# Assert that our sort works correctly
|
||||
self.test_helper.assert_table_sorted(
|
||||
"12",
|
||||
"14",
|
||||
(
|
||||
"investigator__first_name",
|
||||
"investigator__last_name",
|
||||
|
@ -489,7 +489,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
# Assert that sorting in reverse works correctly
|
||||
self.test_helper.assert_table_sorted(
|
||||
"-12",
|
||||
"-14",
|
||||
(
|
||||
"-investigator__first_name",
|
||||
"-investigator__last_name",
|
||||
|
@ -502,7 +502,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
@less_console_noise_decorator
|
||||
def test_default_sorting_in_domain_requests_list(self):
|
||||
"""
|
||||
Make sure the default sortin in on the domain requests list page is reverse submission_date
|
||||
Make sure the default sortin in on the domain requests list page is reverse last_submitted_date
|
||||
then alphabetical requested_domain
|
||||
"""
|
||||
|
||||
|
@ -512,12 +512,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
for name in ["ccc.gov", "bbb.gov", "eee.gov", "aaa.gov", "zzz.gov", "ddd.gov"]
|
||||
]
|
||||
|
||||
domain_requests[0].submission_date = timezone.make_aware(datetime(2024, 10, 16))
|
||||
domain_requests[1].submission_date = timezone.make_aware(datetime(2001, 10, 16))
|
||||
domain_requests[2].submission_date = timezone.make_aware(datetime(1980, 10, 16))
|
||||
domain_requests[3].submission_date = timezone.make_aware(datetime(1998, 10, 16))
|
||||
domain_requests[4].submission_date = timezone.make_aware(datetime(2013, 10, 16))
|
||||
domain_requests[5].submission_date = timezone.make_aware(datetime(1980, 10, 16))
|
||||
domain_requests[0].last_submitted_date = timezone.make_aware(datetime(2024, 10, 16))
|
||||
domain_requests[1].last_submitted_date = timezone.make_aware(datetime(2001, 10, 16))
|
||||
domain_requests[2].last_submitted_date = timezone.make_aware(datetime(1980, 10, 16))
|
||||
domain_requests[3].last_submitted_date = timezone.make_aware(datetime(1998, 10, 16))
|
||||
domain_requests[4].last_submitted_date = timezone.make_aware(datetime(2013, 10, 16))
|
||||
domain_requests[5].last_submitted_date = timezone.make_aware(datetime(1980, 10, 16))
|
||||
|
||||
# Save the modified domain requests to update their attributes in the database
|
||||
for domain_request in domain_requests:
|
||||
|
@ -1649,7 +1649,9 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"cisa_representative_last_name",
|
||||
"has_cisa_representative",
|
||||
"is_policy_acknowledged",
|
||||
"submission_date",
|
||||
"first_submitted_date",
|
||||
"last_submitted_date",
|
||||
"last_status_update",
|
||||
"notes",
|
||||
"alternative_domains",
|
||||
]
|
||||
|
|
|
@ -768,7 +768,7 @@ class HelperFunctions(MockDbForSharedTests):
|
|||
with less_console_noise():
|
||||
filter_condition = {
|
||||
"status": DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
"submission_date__lte": self.end_date,
|
||||
"last_submitted_date__lte": self.end_date,
|
||||
}
|
||||
submitted_requests_sliced_at_end_date = DomainRequestExport.get_sliced_requests(filter_condition)
|
||||
expected_content = [3, 2, 0, 0, 0, 0, 1, 0, 0, 1]
|
||||
|
|
|
@ -25,91 +25,91 @@ class GetRequestsJsonTest(TestWithUser, WebTest):
|
|||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=lamb_chops,
|
||||
submission_date="2024-01-01",
|
||||
last_submitted_date="2024-01-01",
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
created_at="2024-01-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=short_ribs,
|
||||
submission_date="2024-02-01",
|
||||
last_submitted_date="2024-02-01",
|
||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||
created_at="2024-02-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=beef_chuck,
|
||||
submission_date="2024-03-01",
|
||||
last_submitted_date="2024-03-01",
|
||||
status=DomainRequest.DomainRequestStatus.REJECTED,
|
||||
created_at="2024-03-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=stew_beef,
|
||||
submission_date="2024-04-01",
|
||||
last_submitted_date="2024-04-01",
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
created_at="2024-04-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-05-01",
|
||||
last_submitted_date="2024-05-01",
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
created_at="2024-05-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-06-01",
|
||||
last_submitted_date="2024-06-01",
|
||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||
created_at="2024-06-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-07-01",
|
||||
last_submitted_date="2024-07-01",
|
||||
status=DomainRequest.DomainRequestStatus.REJECTED,
|
||||
created_at="2024-07-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-08-01",
|
||||
last_submitted_date="2024-08-01",
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
created_at="2024-08-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-09-01",
|
||||
last_submitted_date="2024-09-01",
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
created_at="2024-09-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-10-01",
|
||||
last_submitted_date="2024-10-01",
|
||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||
created_at="2024-10-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-11-01",
|
||||
last_submitted_date="2024-11-01",
|
||||
status=DomainRequest.DomainRequestStatus.REJECTED,
|
||||
created_at="2024-11-01",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-11-02",
|
||||
last_submitted_date="2024-11-02",
|
||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||
created_at="2024-11-02",
|
||||
),
|
||||
DomainRequest.objects.create(
|
||||
creator=cls.user,
|
||||
requested_domain=None,
|
||||
submission_date="2024-12-01",
|
||||
last_submitted_date="2024-12-01",
|
||||
status=DomainRequest.DomainRequestStatus.APPROVED,
|
||||
created_at="2024-12-01",
|
||||
),
|
||||
|
@ -138,7 +138,7 @@ class GetRequestsJsonTest(TestWithUser, WebTest):
|
|||
|
||||
# Extract fields from response
|
||||
requested_domains = [request["requested_domain"] for request in data["domain_requests"]]
|
||||
submission_dates = [request["submission_date"] for request in data["domain_requests"]]
|
||||
last_submitted_dates = [request["last_submitted_date"] for request in data["domain_requests"]]
|
||||
statuses = [request["status"] for request in data["domain_requests"]]
|
||||
created_ats = [request["created_at"] for request in data["domain_requests"]]
|
||||
ids = [request["id"] for request in data["domain_requests"]]
|
||||
|
@ -154,7 +154,7 @@ class GetRequestsJsonTest(TestWithUser, WebTest):
|
|||
self.domain_requests[i].requested_domain.name if self.domain_requests[i].requested_domain else None,
|
||||
requested_domains[i],
|
||||
)
|
||||
self.assertEqual(self.domain_requests[i].submission_date, submission_dates[i])
|
||||
self.assertEqual(self.domain_requests[i].last_submitted_date, last_submitted_dates[i])
|
||||
self.assertEqual(self.domain_requests[i].get_status_display(), statuses[i])
|
||||
self.assertEqual(
|
||||
parse_datetime(self.domain_requests[i].created_at.isoformat()), parse_datetime(created_ats[i])
|
||||
|
@ -287,26 +287,30 @@ class GetRequestsJsonTest(TestWithUser, WebTest):
|
|||
|
||||
def test_sorting(self):
|
||||
"""test that sorting works properly on the result set"""
|
||||
response = self.app.get(reverse("get_domain_requests_json"), {"sort_by": "submission_date", "order": "desc"})
|
||||
response = self.app.get(
|
||||
reverse("get_domain_requests_json"), {"sort_by": "last_submitted_date", "order": "desc"}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.json
|
||||
|
||||
# Check if sorted by submission_date in descending order
|
||||
submission_dates = [req["submission_date"] for req in data["domain_requests"]]
|
||||
self.assertEqual(submission_dates, sorted(submission_dates, reverse=True))
|
||||
# Check if sorted by last_submitted_date in descending order
|
||||
last_submitted_dates = [req["last_submitted_date"] for req in data["domain_requests"]]
|
||||
self.assertEqual(last_submitted_dates, sorted(last_submitted_dates, reverse=True))
|
||||
|
||||
response = self.app.get(reverse("get_domain_requests_json"), {"sort_by": "submission_date", "order": "asc"})
|
||||
response = self.app.get(reverse("get_domain_requests_json"), {"sort_by": "last_submitted_date", "order": "asc"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.json
|
||||
|
||||
# Check if sorted by submission_date in ascending order
|
||||
submission_dates = [req["submission_date"] for req in data["domain_requests"]]
|
||||
self.assertEqual(submission_dates, sorted(submission_dates))
|
||||
# Check if sorted by last_submitted_date in ascending order
|
||||
last_submitted_dates = [req["last_submitted_date"] for req in data["domain_requests"]]
|
||||
self.assertEqual(last_submitted_dates, sorted(last_submitted_dates))
|
||||
|
||||
def test_filter_approved_excluded(self):
|
||||
"""test that approved requests are excluded from result set."""
|
||||
# sort in reverse chronological order of submission date, since most recent request is approved
|
||||
response = self.app.get(reverse("get_domain_requests_json"), {"sort_by": "submission_date", "order": "desc"})
|
||||
response = self.app.get(
|
||||
reverse("get_domain_requests_json"), {"sort_by": "last_submitted_date", "order": "desc"}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.json
|
||||
|
||||
|
|
|
@ -1235,7 +1235,9 @@ class DomainRequestExport(BaseExport):
|
|||
"State/territory": model.get("state_territory"),
|
||||
"Request purpose": model.get("purpose"),
|
||||
"CISA regional representative": model.get("cisa_representative_email"),
|
||||
"Submitted at": model.get("submission_date"),
|
||||
"Last submitted date": model.get("last_submitted_date"),
|
||||
"First submitted date": model.get("first_submitted_date"),
|
||||
"Last status update": model.get("last_status_update"),
|
||||
}
|
||||
|
||||
row = [FIELDS.get(column, "") for column in columns]
|
||||
|
@ -1279,8 +1281,8 @@ class DomainRequestGrowth(DomainRequestExport):
|
|||
end_date_formatted = format_end_date(end_date)
|
||||
return Q(
|
||||
status=DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
submission_date__lte=end_date_formatted,
|
||||
submission_date__gte=start_date_formatted,
|
||||
last_submitted_date__lte=end_date_formatted,
|
||||
last_submitted_date__gte=start_date_formatted,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -1304,7 +1306,9 @@ class DomainRequestDataFull(DomainRequestExport):
|
|||
"""
|
||||
return [
|
||||
"Domain request",
|
||||
"Submitted at",
|
||||
"Last submitted date",
|
||||
"First submitted date",
|
||||
"Last status update",
|
||||
"Status",
|
||||
"Domain type",
|
||||
"Federal type",
|
||||
|
|
|
@ -46,7 +46,7 @@ def get_domain_requests_json(request):
|
|||
domain_requests_data = [
|
||||
{
|
||||
"requested_domain": domain_request.requested_domain.name if domain_request.requested_domain else None,
|
||||
"submission_date": domain_request.submission_date,
|
||||
"last_submitted_date": domain_request.last_submitted_date,
|
||||
"status": domain_request.get_status_display(),
|
||||
"created_at": format(domain_request.created_at, "c"), # Serialize to ISO 8601
|
||||
"id": domain_request.id,
|
||||
|
|
|
@ -26,7 +26,7 @@ class AnalyticsView(View):
|
|||
created_at__gt=thirty_days_ago, status=models.DomainRequest.DomainRequestStatus.APPROVED
|
||||
)
|
||||
avg_approval_time = last_30_days_approved_applications.annotate(
|
||||
approval_time=F("approved_domain__created_at") - F("submission_date")
|
||||
approval_time=F("approved_domain__created_at") - F("last_submitted_date")
|
||||
).aggregate(Avg("approval_time"))["approval_time__avg"]
|
||||
# Format the timedelta to display only days
|
||||
if avg_approval_time is not None:
|
||||
|
@ -104,11 +104,11 @@ class AnalyticsView(View):
|
|||
|
||||
filter_submitted_requests_start_date = {
|
||||
"status": models.DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
"submission_date__lte": start_date_formatted,
|
||||
"last_submitted_date__lte": start_date_formatted,
|
||||
}
|
||||
filter_submitted_requests_end_date = {
|
||||
"status": models.DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
"submission_date__lte": end_date_formatted,
|
||||
"last_submitted_date__lte": end_date_formatted,
|
||||
}
|
||||
submitted_requests_sliced_at_start_date = csv_export.DomainRequestExport.get_sliced_requests(
|
||||
filter_submitted_requests_start_date
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue