Update migrations

This commit is contained in:
Erin Song 2024-08-29 11:35:00 -07:00
commit 1bfc2dfa79
No known key found for this signature in database
25 changed files with 220 additions and 70 deletions

View file

@ -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```

View file

@ -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"

View file

@ -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">

View file

@ -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

View file

@ -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()

View file

@ -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"

View file

@ -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",
),
),
]

View file

@ -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 = [

View file

@ -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

View file

@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that youll 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
----------------------------------------------------------------

View file

@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that youll 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
----------------------------------------------------------------

View file

@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that youll 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
----------------------------------------------------------------

View file

@ -4,7 +4,7 @@ Hi, {{ recipient.first_name }}.
We've identified an action that youll 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
----------------------------------------------------------------

View file

@ -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
----------------------------------------------------------------

View file

@ -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>.

View file

@ -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
----------------------------------------------------------------

View file

@ -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
----------------------------------------------------------------

View file

@ -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 -->

View file

@ -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

View file

@ -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",
]

View file

@ -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]

View file

@ -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

View file

@ -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",

View file

@ -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,

View file

@ -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