Skip to content

Commit

Permalink
Fix views for report schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
Rieven committed Sep 25, 2024
1 parent fde2ff3 commit f46ebb1
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 106 deletions.
52 changes: 43 additions & 9 deletions rocky/reports/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime, timezone
from typing import Any

from django import forms
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -32,29 +33,62 @@ def __init__(self, report_types: set[Report], *args, **kwargs):
self.fields["report_type"].choices = report_types_choices


class ReportScheduleForm(BaseRockyForm):
class ReportReferenceDateForm(BaseRockyForm):
choose_date = forms.ChoiceField(
label="",
required=False,
widget=forms.RadioSelect(attrs={"class": "submit-on-click"}),
choices=(("today", _("Today")), ("schedule", _("Different date"))),
initial="today",
)
start_date = forms.DateField(
label=_("Start date"),
widget=DateInput(format="%Y-%m-%d", attrs={"form": "generate_report"}),
label="",
widget=forms.HiddenInput(),
initial=lambda: datetime.now(tz=timezone.utc).date(),
required=False,
)

def clean(self) -> dict[str, Any]:
cleaned_data = super().clean()
if cleaned_data.get("choose_date") == "schedule":
self.fields["start_date"].widget = DateInput(format="%Y-%m-%d")
return cleaned_data


class ReportRecurrenceForm(BaseRockyForm):
choose_recurrence = forms.ChoiceField(
label="",
required=False,
widget=forms.RadioSelect(attrs={"class": "submit-on-click"}),
choices=(("once", _("No, just once")), ("repeat", _("Yes, repeat"))),
initial="once",
)
recurrence = forms.ChoiceField(
label=_("Recurrence"),
label="",
required=False,
widget=forms.Select(
attrs={"form": "generate_report"},
),
widget=forms.Select,
choices=[
("no_repeat", _("Does not repeat")),
("daily", _("Daily")),
("weekly", _("Weekly")),
("monthly", _("Monthly")),
("yearly", _("Yearly")),
],
)

def clean(self) -> dict[str, Any]:
cleaned_data = super().clean()
if cleaned_data.get("choose_recurrence") == "once":
self.fields["recurrence"].widget = forms.HiddenInput()
self.fields["recurrence"].choices = [("no_repeat", _("No Repeat"))]
return cleaned_data


class ReportScheduleForm(ReportReferenceDateForm, ReportRecurrenceForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget = forms.HiddenInput()


class CustomReportScheduleForm(BaseRockyForm):
start_date = forms.DateField(
Expand Down Expand Up @@ -104,7 +138,7 @@ class CustomReportScheduleForm(BaseRockyForm):

class ParentReportNameForm(BaseRockyForm):
parent_report_name = forms.CharField(
label=_("Report name format"), required=True, initial="{report type} for {ooi}"
label=_("Report name format"), required=False, initial="{report type} for {ooi}"
)


Expand Down
112 changes: 44 additions & 68 deletions rocky/reports/templates/partials/export_report_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,81 +7,56 @@
<section>
<div>
{% if selected_oois and selected_report_types %}
{% if report_schedule_form %}
<h2>{% translate "Report schedule" %}</h2>
<p>
{% blocktranslate trimmed %}
The date you select will be the reference date for the data set for your report.
Please allow for up to 24 hours for your report to be ready.
{% endblocktranslate %}
</p>
<form class="inline">
{% include "partials/form/fieldset.html" with fields=report_schedule_form fieldset_parent_class="column-2" %}

</form>
{% endif %}
<h2>{% translate "Report name" %}</h2>
{% include "partials/return_button.html" with btn_text="Change selection" %}

<h2>{% translate "Report schedule" %}</h2>
<p>
{% blocktranslate trimmed %}
Give your report a custom name and optionally add the reports' reference date
to the name. To do so you can select a standard option or use a <a href="https://strftime.org/" target="_blank">Python
strftime code</a> in the report name.
The date you select will be the reference date for the data set for your report.
{% endblocktranslate %}
</p>
{% include "partials/return_button.html" with btn_text="Change selection" %}

<form class="inline" method="post" action="{{ current }}">
{% csrf_token %}
{% include "forms/report_form_fields.html" %}

<h3>{% translate "Reference date" %}</h3>
{% include "partials/form/fieldset.html" with fields=report_reference_date_form %}

<h3>{% translate "Recurrence" %}</h3>
{% include "partials/form/fieldset.html" with fields=report_recurrence_form %}

</form>
{% if show_listed_report_names %}
{% include "partials/report_names_header.html" %}

{% endif %}
{% if is_scheduled_report %}
{% include "partials/report_names_header.html" %}

{% endif %}
<form id="generate_report" class="inline" method="post" action="{{ next }}">
<table id="report-name-table">
<caption class="visually-hidden">{% translate "Report names:" %}</caption>
<thead>
<tr>
<th scope="col" colspan="2">
{% translate "Name" %} <span class="nota-bene" aria-hidden>{% translate "(Required)" %}</span>
</th>
<th scope="col">{% translate "Add reference date" %}</th>
</tr>
</thead>
<tbody>
{% for report_name in reports %}
{% with report_id=report_name|slugify %}
<input type="hidden" name="old_report_name" value="{{ report_name }}" />
<tr>
<td>
<div>
<input id="{{ report_id }}"
class="name-input"
name="report_name"
type="text"
value="{{ report_name }}"
required
minlength="3" />
</div>
</td>
<td>
<button type="button"
class="icon ti-arrow-back-up action-button reset-button hidden"
aria-label="{% translate "Reset" %}"></button>
</td>
<td>
<select class="reference-date" name="reference_date">
<option value="">{% translate "No reference date" %}</option>
<option value="%b %d %Y, %H:%M">{% translate "Day" %} ({{ created_at|date:"N jS Y, H:i" }})</option>
<option value="week">{% translate "Week" %} ({% translate "Week" %} {{ created_at|date:"W, Y" }})</option>
<option value="%b, %Y">{% translate "Month" %} ({{ created_at|date:"N, Y" }})</option>
<option value="%Y">{% translate "Year" %} ({{ created_at|date:"Y" }})</option>
</select>
</td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
{% csrf_token %}
<button type="submit" form="generate_report">
{% include "forms/report_form_fields.html" %}
{% include "forms/report_form_fields.html" %}
{% include "partials/form/fieldset.html" with fields=report_schedule_form %}

{% if show_listed_report_names %}
{% include "partials/report_names_form.html" %}

<button type="submit" form="generate_report">
{% translate "Generate report" %}<span class="icon ti-chevron-right" aria-hidden="true"></span>
</button>
{% endif %}
{% if is_scheduled_report %}
{% include "partials/form/fieldset.html" with fields=report_parent_name_form %}

{% if reports|length > 1 %}
{% include "partials/form/fieldset.html" with fields=report_child_name_form %}

{% translate "Generate report" %}<span class="icon ti-chevron-right" aria-hidden="true"></span>
</button>
{% endif %}
<button type="submit" form="generate_report">
{% translate "Generate report" %}<span class="icon ti-chevron-right" aria-hidden="true"></span>
</button>
{% endif %}
</form>
{% else %}
{% include "partials/return_button.html" with btn_text="Go back" %}
Expand All @@ -92,5 +67,6 @@ <h2>{% translate "Report name" %}</h2>
{% block html_at_end_body %}
{% compress js %}
<script src="{% static "js/renameReports.js" %}" nonce="{{ request.csp_nonce }}" type="module"></script>
<script src="{% static "js/autoSubmit.js" %}" nonce="{{ request.csp_nonce }}" type="module"></script>
{% endcompress %}
{% endblock html_at_end_body %}
52 changes: 52 additions & 0 deletions rocky/reports/templates/partials/report_names_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{% load i18n %}
{% load static %}
{% load report_extra %}
{% load ooi_extra %}
{% load compress %}

<table id="report-name-table">
<caption class="visually-hidden">{% translate "Report names:" %}</caption>
<thead>
<tr>
<th scope="col" colspan="2">
{% translate "Name" %} <span class="nota-bene" aria-hidden>{% translate "(Required)" %}</span>
</th>
<th scope="col">{% translate "Add reference date" %}</th>
</tr>
</thead>
<tbody>
{% for report_name in reports %}
{% with report_id=report_name|slugify %}
<input type="hidden" name="old_report_name" value="{{ report_name }}" />
<tr>
<td>
<div>
<input id="{{ report_id }}"
class="name-input"
name="report_name"
type="text"
value="{{ report_name }}"
required
minlength="3" />
</div>
</td>
<td>
<button type="button"
class="icon ti-arrow-back-up action-button reset-button hidden"
aria-label="{% translate "Reset" %}"></button>
</td>
<td>
<select class="reference-date" name="reference_date">
<option value="">{% translate "No reference date" %}</option>
<option value="%b %d %Y, %H:%M">{% translate "Day" %} ({{ created_at|date:"N jS Y, H:i" }})</option>
<option value="week">{% translate "Week" %} ({% translate "Week" %} {{ created_at|date:"W, Y" }})</option>
<option value="%b, %Y">{% translate "Month" %} ({{ created_at|date:"N, Y" }})</option>
<option value="%Y">{% translate "Year" %} ({{ created_at|date:"Y" }})</option>
</select>
</td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
{% csrf_token %}
11 changes: 11 additions & 0 deletions rocky/reports/templates/partials/report_names_header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% load i18n %}
{% load static %}

<h2>{% translate "Report name" %}</h2>
<p>
{% blocktranslate trimmed %}
Give your report a custom name and optionally add the reports' reference date
to the name. To do so you can select a standard option or use a <a href="https://strftime.org/" target="_blank">Python
strftime code</a> in the report name.
{% endblocktranslate %}
</p>
50 changes: 44 additions & 6 deletions rocky/reports/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from account.mixins import OrganizationView
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import SuspiciousOperation
from django.forms import Form
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import redirect
Expand Down Expand Up @@ -116,6 +115,7 @@ def get_context_data(self, **kwargs):
context["breadcrumbs"] = self.get_breadcrumbs()
context["next"] = self.get_next()
context["previous"] = self.get_previous()
context["current"] = self.get_current()
return context


Expand Down Expand Up @@ -239,6 +239,20 @@ def get_plugin_data_for_saving(self) -> list[dict]:

return plugin_data

def show_report_names(self) -> bool:
date_choice = self.request.POST.get("choose_date", "today")
recurrence_choice = self.request.POST.get("choose_recurrence", "once")

return date_choice == "today" and recurrence_choice == "once"

def is_scheduled_report(self) -> bool:
date_choice = self.request.POST.get("choose_date", "schedule")
recurrence_choice = self.request.POST.get("choose_recurrence", "repeat")

return (recurrence_choice in ["once", "repeat"] and date_choice == "schedule") or (
date_choice == "today" and recurrence_choice == "repeat"
)

def save_report_raw(self, data: dict) -> str:
report_data_raw_id = self.bytes_client.upload_raw(
raw=ReportDataDict(data).model_dump_json().encode(),
Expand Down Expand Up @@ -493,11 +507,17 @@ def get_context_data(self, **kwargs):
class ReportFinalSettingsView(BaseReportView, ReportBreadcrumbs, SchedulerView, TemplateView):
report_type: type[BaseReport] | None = None
task_type = "report"
is_a_scheduled_report = False
show_listes_report_names = False

def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
if not self.get_report_type_ids():
messages.error(request, self.NONE_REPORT_TYPE_SELECTION_MESSAGE)
return PostRedirect(self.get_previous())

self.is_a_scheduled_report = self.is_scheduled_report()
self.show_listes_report_names = self.show_report_names()

return super().get(request, *args, **kwargs)

@staticmethod
Expand Down Expand Up @@ -541,20 +561,31 @@ def get_report_names(self) -> dict[str, str] | list[str]:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["reports"] = self.get_report_names()

context["report_reference_date_form"] = self.get_report_reference_date_form()
context["report_recurrence_form"] = self.get_report_recurrence_form()

context["report_parent_name_form"] = self.get_report_parent_name_form()
context["report_child_name_form"] = self.get_report_child_name_form()

context["show_listed_report_names"] = self.show_listes_report_names
context["is_scheduled_report"] = self.is_a_scheduled_report

context["report_schedule_form"] = self.get_report_schedule_form()

context["created_at"] = datetime.now()
return context


class SaveReportView(BaseReportView):
class SaveReportView(BaseReportView, ReportBreadcrumbs, SchedulerView):
task_type = "report"

def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
old_report_names = request.POST.getlist("old_report_name")
report_names = request.POST.getlist("report_name")
report_names = request.POST.getlist("report_name", [])
reference_dates = request.POST.getlist("reference_date")

if "" in report_names:
raise SuspiciousOperation(_("Empty name should not be possible."))
else:
if self.show_report_names() and report_names:
final_report_names = list(zip(old_report_names, self.finalise_report_names(report_names, reference_dates)))
report_ooi = self.save_report(final_report_names)

Expand All @@ -563,6 +594,13 @@ def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
+ "?"
+ urlencode({"report_id": report_ooi.reference})
)
elif self.is_scheduled_report():
self.schedule_report()

return redirect(reverse("report_history", kwargs={"organization_code": self.organization.code}))

messages.error(request, _("Empty name should not be possible."))
return PostRedirect(self.get_previous())

@staticmethod
def finalise_report_names(report_names: list[str], reference_dates: list[str]) -> list[str]:
Expand Down
Loading

0 comments on commit f46ebb1

Please sign in to comment.