From f46ebb1d5a34511f6336df0ce29fb0be0f80fce6 Mon Sep 17 00:00:00 2001 From: Rieven Date: Wed, 25 Sep 2024 17:16:17 +0200 Subject: [PATCH] Fix views for report schedule --- rocky/reports/forms.py | 52 ++++++-- .../partials/export_report_settings.html | 112 +++++++----------- .../templates/partials/report_names_form.html | 52 ++++++++ .../partials/report_names_header.html | 11 ++ rocky/reports/views/base.py | 50 +++++++- .../partials/form/field_input_radio.html | 7 +- rocky/rocky/views/scheduler.py | 65 +++++++--- 7 files changed, 243 insertions(+), 106 deletions(-) create mode 100644 rocky/reports/templates/partials/report_names_form.html create mode 100644 rocky/reports/templates/partials/report_names_header.html diff --git a/rocky/reports/forms.py b/rocky/reports/forms.py index 3b5137b792b..c1b2df7d506 100644 --- a/rocky/reports/forms.py +++ b/rocky/reports/forms.py @@ -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 _ @@ -32,22 +33,41 @@ 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")), @@ -55,6 +75,20 @@ class ReportScheduleForm(BaseRockyForm): ], ) + 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( @@ -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}" ) diff --git a/rocky/reports/templates/partials/export_report_settings.html b/rocky/reports/templates/partials/export_report_settings.html index cdb9a2a60d8..efa2006f5c4 100644 --- a/rocky/reports/templates/partials/export_report_settings.html +++ b/rocky/reports/templates/partials/export_report_settings.html @@ -7,81 +7,56 @@
{% if selected_oois and selected_report_types %} - {% if report_schedule_form %} -

{% translate "Report schedule" %}

-

- {% 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 %} -

-
- {% include "partials/form/fieldset.html" with fields=report_schedule_form fieldset_parent_class="column-2" %} - -
- {% endif %} -

{% translate "Report name" %}

- {% include "partials/return_button.html" with btn_text="Change selection" %} - +

{% translate "Report schedule" %}

{% 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 Python - strftime code in the report name. + The date you select will be the reference date for the data set for your report. {% endblocktranslate %}

+ {% include "partials/return_button.html" with btn_text="Change selection" %} + +
+ {% csrf_token %} + {% include "forms/report_form_fields.html" %} + +

{% translate "Reference date" %}

+ {% include "partials/form/fieldset.html" with fields=report_reference_date_form %} + +

{% translate "Recurrence" %}

+ {% include "partials/form/fieldset.html" with fields=report_recurrence_form %} + +
+ {% if show_listed_report_names %} + {% include "partials/report_names_header.html" %} + + {% endif %} + {% if is_scheduled_report %} + {% include "partials/report_names_header.html" %} + + {% endif %}
- - - - - - - - - - {% for report_name in reports %} - {% with report_id=report_name|slugify %} - - - - - - - {% endwith %} - {% endfor %} - -
{% translate "Report names:" %}
- {% translate "Name" %} {% translate "(Required)" %} - {% translate "Add reference date" %}
-
- -
-
- - - -
{% csrf_token %} - + {% 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" %} - + {% endif %} + + {% endif %}
{% else %} {% include "partials/return_button.html" with btn_text="Go back" %} @@ -92,5 +67,6 @@

{% translate "Report name" %}

{% block html_at_end_body %} {% compress js %} + {% endcompress %} {% endblock html_at_end_body %} diff --git a/rocky/reports/templates/partials/report_names_form.html b/rocky/reports/templates/partials/report_names_form.html new file mode 100644 index 00000000000..28d91084845 --- /dev/null +++ b/rocky/reports/templates/partials/report_names_form.html @@ -0,0 +1,52 @@ +{% load i18n %} +{% load static %} +{% load report_extra %} +{% load ooi_extra %} +{% load compress %} + + + + + + + + + + + {% for report_name in reports %} + {% with report_id=report_name|slugify %} + + + + + + + {% endwith %} + {% endfor %} + +
{% translate "Report names:" %}
+ {% translate "Name" %} {% translate "(Required)" %} + {% translate "Add reference date" %}
+
+ +
+
+ + + +
+{% csrf_token %} diff --git a/rocky/reports/templates/partials/report_names_header.html b/rocky/reports/templates/partials/report_names_header.html new file mode 100644 index 00000000000..9ff50c925fc --- /dev/null +++ b/rocky/reports/templates/partials/report_names_header.html @@ -0,0 +1,11 @@ +{% load i18n %} +{% load static %} + +

{% translate "Report name" %}

+

+ {% 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 Python + strftime code in the report name. + {% endblocktranslate %} +

diff --git a/rocky/reports/views/base.py b/rocky/reports/views/base.py index ea40d3f6e01..f7969c6865e 100644 --- a/rocky/reports/views/base.py +++ b/rocky/reports/views/base.py @@ -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 @@ -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 @@ -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(), @@ -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 @@ -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) @@ -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]: diff --git a/rocky/rocky/templates/partials/form/field_input_radio.html b/rocky/rocky/templates/partials/form/field_input_radio.html index 6e796eddfeb..cf001180389 100644 --- a/rocky/rocky/templates/partials/form/field_input_radio.html +++ b/rocky/rocky/templates/partials/form/field_input_radio.html @@ -7,12 +7,7 @@ {% endif %} {% for choice in field %}
- +