-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [#4930] Implement the actual export
Export submission statistics based on the timeline logs. Note: if the timeline logs are pruned, this affects the exports. It's up to the users to periodically create these exports and save them somewhere if they periodically prune log records. Note 2: filtering on forms only works on new log records, as existing log records don't have the form ID stored in the structured data. Submissions that were deleted for which existing log records are present will display 'unknown' for some columns because the relevant information has been deleted. Only from 3.0 onwards are we snapshotting the data required for the exports.
- Loading branch information
1 parent
e0ff975
commit 33b6e2e
Showing
4 changed files
with
132 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from datetime import date, datetime, time | ||
|
||
from django.contrib.contenttypes.models import ContentType | ||
from django.db import models | ||
from django.utils.timezone import make_aware | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from tablib import Dataset | ||
|
||
from openforms.logging import logevent | ||
from openforms.logging.models import TimelineLogProxy | ||
from openforms.submissions.models import Submission | ||
|
||
from .models import Form | ||
|
||
|
||
def export_registration_statistics( | ||
start_date: date, | ||
end_date: date, | ||
limit_to_forms: models.QuerySet[Form] | None = None, | ||
) -> Dataset: | ||
dataset = Dataset( | ||
headers=( | ||
_("Public reference"), | ||
_("Form name (public)"), | ||
_("Form name (internal)"), | ||
_("Submitted on"), | ||
_("Registered on"), | ||
), | ||
title=_("Successfully registered submissions between {start} and {end}").format( | ||
start=start_date.isoformat(), | ||
end=end_date.isoformat(), | ||
), | ||
) | ||
|
||
_start_date = make_aware(datetime.combine(start_date, time.min)) | ||
_end_date = make_aware(datetime.combine(end_date, time.max)) | ||
|
||
log_records = TimelineLogProxy.objects.filter( | ||
content_type=ContentType.objects.get_for_model(Submission), | ||
timestamp__gte=_start_date, | ||
timestamp__lt=_end_date, | ||
# see openforms.logging.logevent for the data structure of the extra_data | ||
# JSONField | ||
extra_data__log_event=logevent.REGISTRATION_SUCCESS_EVENT, | ||
).order_by("timestamp") | ||
|
||
if limit_to_forms: | ||
form_ids = list(limit_to_forms.values_list("pk", flat=True)) | ||
log_records = log_records.filter(extra_data__form_id__in=form_ids) | ||
|
||
for record in log_records.iterator(): | ||
extra_data = record.extra_data | ||
# GFKs will be broken when the submissions are pruned, so prefer extracting | ||
# information from the extra_data snapshot | ||
submission: Submission | None = record.content_object | ||
dataset.append( | ||
( | ||
# public reference | ||
extra_data.get( | ||
"public_reference", | ||
( | ||
submission.public_registration_reference | ||
if submission | ||
else "-unknown-" | ||
), | ||
), | ||
# public form name | ||
extra_data.get( | ||
"form_name", submission.form.name if submission else "-unknown-" | ||
), | ||
# internal form name | ||
extra_data.get( | ||
"internal_form_name", | ||
submission.form.internal_name if submission else "-unknown-", | ||
), | ||
# when the user submitted the form | ||
extra_data.get( | ||
"submitted_on", | ||
submission.completed_on.isoformat() if submission else None, | ||
), | ||
# when the registration succeeeded - this must be close to when it was logged | ||
record.timestamp.isoformat(), | ||
) | ||
) | ||
|
||
return dataset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters