diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 111d12fa..f35b9f51 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: MVJ 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-27 16:00+0300\n" +"POT-Creation-Date: 2023-09-14 14:56+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: \n" "Language: fi\n" @@ -3639,10 +3639,26 @@ msgstr "Kohde on poistunut järjestelmästä!" msgid "The target information has changed!" msgstr "Kohteen tiedot ovat muuttuneet!" +msgid "Area search information" +msgstr "Aluehaun tiedot" + +msgid "Description area" +msgstr "Tarkempi kuvaus alueesta" + +msgid "Description intended use" +msgstr "Tarkempi kuvaus käyttötarkoituksesta" + +msgid "Received date" +msgstr "Vastaanotettu" + +msgid "Time stamp" +msgstr "Aikaleima" + msgid "You have received a link for a direct reservation plot search" msgstr "Olet vastaanottanut linkin suoravaraushakuun" -#python-brace-format +# python-brace-format +#, python-brace-format msgid "" "Hi {receiver}! Here is the link for the direct reservation plot search: " "{url} \n" diff --git a/mvj/urls.py b/mvj/urls.py index 363976e7..9c17eaf1 100755 --- a/mvj/urls.py +++ b/mvj/urls.py @@ -109,12 +109,12 @@ from leasing.viewsets.vat import VatViewSet from plotsearch.views.plot_search import ( AreaSearchAttachmentViewset, + AreaSearchGeneratePDF, AreaSearchViewSet, DirectReservationLinkViewSet, DirectReservationToFavourite, FAQViewSet, FavouriteViewSet, - GeneratePDF, InformationCheckViewSet, ) from plotsearch.views.plot_search import IntendedUseViewSet as IntendedUsePSViewSet @@ -124,6 +124,7 @@ PlotSearchTargetViewSet, PlotSearchTypeViewSet, PlotSearchViewSet, + TargetStatusGeneratePDF, ) from users.views import UsersPermissions from users.viewsets import UserViewSet @@ -252,7 +253,12 @@ router.register("job_run_log_entry", JobRunLogEntryViewSet) additional_api_paths = [ - path("target_status_pdf/", GeneratePDF.as_view(), name="target_status-pdf"), + path( + "target_status_pdf/", + TargetStatusGeneratePDF.as_view(), + name="target_status-pdf", + ), + path("area_search_pdf/", AreaSearchGeneratePDF.as_view(), name="area-search-pdf"), path("auditlog/", AuditLogView.as_view(), name="auditlog"), path("contact_exists/", ContactExistsView.as_view(), name="contact-exists"), path( diff --git a/plotsearch/templates/area_search/detail.html b/plotsearch/templates/area_search/detail.html new file mode 100644 index 00000000..558625cc --- /dev/null +++ b/plotsearch/templates/area_search/detail.html @@ -0,0 +1,100 @@ +{% load static %} +{% load i18n %} +{% load entry_filter %} + + + + + + + Title + + + + + +
+
+

{{ object.identifier }}

+
+
+

{% trans "Area search information" %}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans "Lessor" %}{{ object.lessor.value }}
{% trans "Description area" %}{{ object.description_area }}
{% trans "Address" %}{{ object.address }}
{% trans "District" %}{{ object.district }}
{% trans "Intended use" %}{{ object.intended_use }}
{% trans "Description intended use" %}{{ object.description_intended_use }}
{% trans "Start date" %}{{ object.start_date|date:"G:i j.n.Y" }}
{% trans "End date" %}{{ object.end_date|date:"G:i j.n.Y" }}
{% trans "Received date" %}{{ object.received_date|date:"G:i j.n.Y" }}
+
+
 
+ {% for section in object.form.sections.all|filter_only_parent %} + {% if section.applicant_type|slugify == applicant_type|slugify or section.applicant_type|slugify == "Both"|slugify %} + {% include "mixins/section.html" with section=section answer=object.answer %} + {% endif %} + {% endfor %} + {% if show_information_check %} +
+

{% trans "Area search information" %}

+ + + + + + + + + + {% for note in object.area_search_status.status_notes.all %} + + + + + + + + + + + + + {% endfor %} +
{% trans "Lessor" %}{{ object.area_search_status.decline_reason.value }}
{% trans "Description area" %}{{ object.area_search_status.preparer_note }}
{% trans "Note" %}{{ note.note }}
{% trans "Preparer" %}{{ note.preparer }}
{% trans "Time stamp" %}{{ note.time_stamp|date:"G:i j.n.Y" }}
+
 
+
+ {% endif %} +
+ + + diff --git a/plotsearch/templates/mixins/section.html b/plotsearch/templates/mixins/section.html index af1c1ecd..8941936e 100644 --- a/plotsearch/templates/mixins/section.html +++ b/plotsearch/templates/mixins/section.html @@ -1,29 +1,45 @@ -{% for subsection in section.subsections.all %} - {% include "mixins/section.html" with section=subsection %} -{% endfor %} +{% load entry_filter %} +{% load form_visible %} + +{% if section.fields.all and section.visible == True %} +
+

{{ section }}

+ + {% for field in section.fields.all %} + {% if field.enabled == True %} + + + {% for entry in field.entry_set.all|filter_answer:answer %} + + {% endfor %} + + {% endif %} -{% if section.fields.all %} -
-

{{ section }}

-
+ {{ field }} + + {% if field.type.identifier == "checkbox" or field.type.identifier == "radiobutton" or field.type.identifier == "radiobuttoninline" %} + {% fetch_choice_value entry.value entry.field.id %} + {% if not entry.value %} + - + {% endif %} + + {% else %} + {{ entry.value }} + {% if not entry.value %} + - + {% endif %} + {% endif %} + {% empty %} + - +
- {% for field in section.fields.all %} - - - - - {% endfor %} -
- {{field}} - - {% for entry in field.entry_set.all %} - {{ entry.value }} - {% if not entry.value%} - - - {% endif %} - {% empty %} - - - {% endfor %} -
+ {% endfor %} + +
 
- {% endif %} + +{% for subsection in section.subsections.all %} + {% if subsection.applicant_type|slugify == applicant_type|slugify or subsection.applicant_type|slugify == "Both"|slugify %} + {% include "mixins/section.html" with section=subsection %} + {% endif %} +{% endfor %} diff --git a/plotsearch/templates/target_status/detail.html b/plotsearch/templates/target_status/detail.html index a1e0dda7..460ae2c7 100644 --- a/plotsearch/templates/target_status/detail.html +++ b/plotsearch/templates/target_status/detail.html @@ -1,4 +1,7 @@ {% load static %} +{% load form_visible %} +{% load entry_filter %} + @@ -15,10 +18,10 @@

{{ object.application_identifier }}

 
- {% for section in object.plot_search_target.plot_search.form.sections.all %} - {% include "mixins/section.html" with section=section %} + {% for section in object.plot_search_target.plot_search.form.sections.all|filter_only_parent %} + {% include "mixins/section.html" with section=section answer=object.answer %} {% endfor %} - \ No newline at end of file + diff --git a/plotsearch/templatetags/__init__.py b/plotsearch/templatetags/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plotsearch/templatetags/entry_filter.py b/plotsearch/templatetags/entry_filter.py new file mode 100755 index 00000000..6865db69 --- /dev/null +++ b/plotsearch/templatetags/entry_filter.py @@ -0,0 +1,13 @@ +from django import template + +register = template.Library() + + +@register.filter +def filter_answer(qs, answer): + return qs.filter(entry_section__answer=answer) + + +@register.filter +def filter_only_parent(qs): + return qs.filter(parent__isnull=True) diff --git a/plotsearch/templatetags/form_visible.py b/plotsearch/templatetags/form_visible.py new file mode 100644 index 00000000..2261a691 --- /dev/null +++ b/plotsearch/templatetags/form_visible.py @@ -0,0 +1,32 @@ +import ast + +from django import template + +from forms.models import Choice + +register = template.Library() + + +@register.filter +def visible_section(section, value): + return section.filter(visible=value) + + +@register.filter +def visible_field(field, value): + return field.filter(enabled=value) + + +@register.simple_tag +def fetch_choice_value(value, field_id): + if value == "" or value == "[]": + return "-" + choice_value = ast.literal_eval(value) + choices = Choice.objects.filter(field=field_id) + if isinstance(choice_value, list): + choices = choices.filter(value__in=choice_value) + else: + choices = choices.filter(value=choice_value) + if not choices.exists(): + return "-" + return " ".join([choice.text for choice in choices]) diff --git a/plotsearch/utils.py b/plotsearch/utils.py index 121c9792..f4e094fe 100644 --- a/plotsearch/utils.py +++ b/plotsearch/utils.py @@ -1,6 +1,7 @@ from django.utils.translation import override from django.utils.translation import ugettext_lazy as _ +from forms.enums import ApplicantType from forms.models import Choice, Field, Form, Section from plotsearch.enums import AreaSearchLessor @@ -784,3 +785,26 @@ def pop_default(validated_data, index, default_value): return validated_data.pop(index) except IndexError: return default_value + + +def get_applicant_type(answer): + applicant_sections = answer.entry_sections.filter( + entries__field__identifier="hakija", + entries__field__section__identifier="hakijan-tiedot", + ) + applicant_type = ( + applicant_sections[0] + .entries.get( + field__identifier="hakija", field__section__identifier="hakijan-tiedot" + ) + .value + ) + + applicant_type_enum = ApplicantType.BOTH + + if applicant_type == "0": + applicant_type_enum = ApplicantType.PERSON + if applicant_type == "1": + applicant_type_enum = ApplicantType.COMPANY + + return applicant_type_enum diff --git a/plotsearch/views/plot_search.py b/plotsearch/views/plot_search.py index b13b3968..e5442a04 100755 --- a/plotsearch/views/plot_search.py +++ b/plotsearch/views/plot_search.py @@ -66,6 +66,7 @@ PlotSearchTypeSerializer, PlotSearchUpdateSerializer, ) +from plotsearch.utils import get_applicant_type class PlotSearchSubtypeViewSet( @@ -259,7 +260,7 @@ class DirectReservationLinkViewSet(viewsets.ModelViewSet): permission_classes = (MvjDjangoModelPermissions,) -class GeneratePDF(PdfMixin, FilterView): +class TargetStatusGeneratePDF(PdfMixin, FilterView): template_name = "target_status/detail.html" model = TargetStatus filterset_class = TargetStatusExportFilterSet @@ -291,6 +292,61 @@ def render_to_response( return response +class AreaSearchGeneratePDF(PdfMixin, FilterView): + template_name = "area_search/detail.html" + model = AreaSearch + filterset_class = AreaSearchFilterSet + + def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: + context = super().get_context_data(**kwargs) + show_information_check = self.request.GET.get("show_information_check", False) + + context.update({"show_information_check": show_information_check}) + + return context + + def render_to_response( + self, context: Dict[str, Any], **response_kwargs: Any + ) -> http.HttpResponse: + response_kwargs.setdefault("content_type", self.content_type) + response = HttpResponse(content_type="application/zip") + with zipfile.PyZipFile(response, mode="w") as zip_file: + for object in self.object_list: + context.update( + object=object, applicant_type=get_applicant_type(object.answer) + ) + pdf_response = self.response_class( + request=self.request, + template=self.get_template_names(), + context=context, + using=self.template_engine, + **response_kwargs, + ) + zip_file.writestr( + ZipInfo("{}.pdf".format(object.identifier)), + pdf_response.render().content, + ) + + response[ + "Content-Disposition" + ] = f'attachment; filename={"{}.zip".format(self.object_list[0].lessor)}' + + return response + + +""" +# For PDF debugging purposes +class DebugAreaSearchPDF(generic.DetailView): + model = AreaSearch + template_name = "area_search/detail.html" + + def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: + context = super().get_context_data(**kwargs) + context.update(applicant_type=get_applicant_type(context["areasearch"].answer)) + return context +""" + + class DirectReservationToFavourite(APIView): permission_classes = (IsAuthenticated,)