From 85e3d4abb46a0ef28cea03568d5a1761bd1bd43a Mon Sep 17 00:00:00 2001 From: Pasi Vuohijoki Date: Mon, 24 Jul 2023 10:48:54 +0300 Subject: [PATCH] Added email sending feature into direct reservation link create serializer --- locale/fi/LC_MESSAGES/django.po | 106 ++++++++++++++++-- plotsearch/enums.py | 8 +- plotsearch/serializers/plot_search.py | 61 ++++++++++ .../api/test_direct_reservation_links.py | 9 +- plotsearch/utils.py | 34 +++++- plotsearch/views/plot_search.py | 9 +- 6 files changed, 211 insertions(+), 16 deletions(-) diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index a5ac2b40..111d12fa 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-02-13 13:29+0200\n" +"POT-Creation-Date: 2023-07-27 16:00+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: \n" "Language: fi\n" @@ -384,6 +384,18 @@ msgctxt "Section type" msgid "Show if" msgstr "Näytä, jos" +msgctxt "Applicant type" +msgid "Person" +msgstr "Henkilö" + +msgctxt "Applicant type" +msgid "Company" +msgstr "" + +msgctxt "Applicant type" +msgid "Both" +msgstr "" + msgid "Time created" msgstr "Luotu" @@ -3440,6 +3452,18 @@ msgstr "" "Ilmoitusviestien vastaanottajat. Esimerkki: matti@example.com,maija@example." "com" +msgctxt "Area search lessor" +msgid "Area use and control" +msgstr "Aluekäyttö- ja valvonta" + +msgctxt "Area search lessor" +msgid "Culture and leisure" +msgstr "Kulttuuri ja vapaa-aika" + +msgctxt "Area search lessor" +msgid "Development of land assets" +msgstr "Maaomaisuudenkehittäminen ja tontit" + msgctxt "Search class" msgid "Plot search" msgstr "Tonttihaku tai -kilpailu" @@ -3448,6 +3472,26 @@ msgctxt "Search class" msgid "Other" msgstr "Muu kilpailu tai haku" +msgctxt "Search stage" +msgid "In preparation" +msgstr "Tarkastus" + +msgctxt "Search stage" +msgid "In action" +msgstr "Tarkastus" + +msgctxt "Search stage" +msgid "Processing" +msgstr "" + +msgctxt "Search stage" +msgid "Decision making" +msgstr "Päättäjä" + +msgctxt "Search stage" +msgid "Settled" +msgstr "" + msgctxt "Information state" msgid "Checked" msgstr "Tarkistettu" @@ -3492,6 +3536,42 @@ msgctxt "Information check name" msgid "Certificate of entry in the register of employers" msgstr "Todistus työnantajarekisteriin merkitsemisestä" +msgctxt "Decline reason" +msgid "Application revoked" +msgstr "" + +msgctxt "Decline reason" +msgid "Area not controlled by city" +msgstr "Alue ei ole kaupungin hallinnassa" + +msgctxt "Decline reason" +msgid "Area no available for lease" +msgstr "Tiedostoa ei löydy" + +msgctxt "Decline reason" +msgid "Other reason" +msgstr "Muu korvaus" + +msgctxt "Area search state" +msgid "Received" +msgstr "Saamislaji" + +msgctxt "Area search state" +msgid "In action" +msgstr "Tarkastus" + +msgctxt "Area search state" +msgid "Settled" +msgstr "" + +msgctxt "Area search state" +msgid "Revoked" +msgstr "" + +msgctxt "Area search state" +msgid "Declined" +msgstr "" + msgctxt "Model name" msgid "Plot search type" msgstr "Tonttihaun tyyppi" @@ -3547,13 +3627,11 @@ msgctxt "Model name" msgid "Area search intended uses" msgstr "Aluehaun käyttötarkoitukset" -msgctxt "Model name" -msgid "Area search sub intended use" -msgstr "Aluehaun alikäyttötarkoitus" +msgid "Time received" +msgstr "Arkistointiaika" -msgctxt "Model name" -msgid "Area search sub intended uses" -msgstr "Aluehaun alikäyttötarkoitukset" +msgid "Area search state" +msgstr "Vuokrauksen tila" msgid "The target has been removed from the system!" msgstr "Kohde on poistunut järjestelmästä!" @@ -3561,5 +3639,19 @@ msgstr "Kohde on poistunut järjestelmästä!" msgid "The target information has changed!" msgstr "Kohteen tiedot ovat muuttuneet!" +msgid "You have received a link for a direct reservation plot search" +msgstr "Olet vastaanottanut linkin suoravaraushakuun" + +#python-brace-format +msgid "" +"Hi {receiver}! Here is the link for the direct reservation plot search: " +"{url} \n" +"\n" +"{covering_note}" +msgstr "" +"Hei {receiver}! Tässä linkki suoravaraustonttihakuun: {url} \n" +"\n" +"{covering_note}" + msgid "Users permissions" msgstr "Käyttäjän oikeudet" diff --git a/plotsearch/enums.py b/plotsearch/enums.py index 06b4b3a7..66460b54 100644 --- a/plotsearch/enums.py +++ b/plotsearch/enums.py @@ -12,11 +12,9 @@ class AreaSearchLessor(str, Enum): MAKE = "make" class Labels: - AKV = pgettext_lazy("Area search lessor", "Aluekäyttö- ja valvonta") - KUVA = pgettext_lazy("Area search lessor", "Kulttuuri ja vapaa-aika") - MAKE = pgettext_lazy( - "Area search lessor", "Maaomaisuudenkehittäminen ja tontit" - ) + AKV = pgettext_lazy("Area search lessor", "Area use and control") + KUVA = pgettext_lazy("Area search lessor", "Culture and leisure") + MAKE = pgettext_lazy("Area search lessor", "Development of land assets") class SearchClass(str, Enum): diff --git a/plotsearch/serializers/plot_search.py b/plotsearch/serializers/plot_search.py index bc23638e..e332bd65 100755 --- a/plotsearch/serializers/plot_search.py +++ b/plotsearch/serializers/plot_search.py @@ -1,5 +1,6 @@ import requests from django.core.exceptions import BadRequest +from django.core.mail import send_mail from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from enumfields.drf import EnumSupportSerializerMixin @@ -45,9 +46,12 @@ ) from plotsearch.serializers.info_links import PlotSearchTargetInfoLinkSerializer from plotsearch.utils import ( + compose_direct_reservation_mail_body, + compose_direct_reservation_mail_subject, get_applicant, initialize_area_search_form, map_intended_use_to_lessor, + pop_default, ) from users.models import User from users.serializers import UserSerializer @@ -1013,6 +1017,15 @@ class DirectReservationLinkSerializer(serializers.ModelSerializer): targets = InstanceDictPrimaryKeyRelatedField( queryset=PlotSearchTarget.objects.all(), many=True ) + lang_choices = ("FI", "SE", "EN") + language = serializers.ChoiceField(lang_choices, allow_blank=True, required=False) + first_name = serializers.CharField(allow_blank=True, required=False) + last_name = serializers.CharField(allow_blank=True, required=False) + email = serializers.CharField(allow_blank=True, required=False) + company = serializers.CharField(allow_blank=True, required=False) + covering_note = serializers.CharField(allow_blank=True, required=False) + send_copy = serializers.BooleanField(required=False) + send_mail = serializers.BooleanField(required=False) class Meta: model = DirectReservationLink @@ -1020,7 +1033,55 @@ class Meta: "uuid", "url", "targets", + "language", + "first_name", + "last_name", + "email", + "company", + "covering_note", + "send_copy", + "send_mail", ) def get_url(self, obj): return obj.get_external_url() + + def create(self, validated_data): + + language = pop_default(validated_data, "language", "en") + first_name = pop_default(validated_data, "first_name", "") + last_name = pop_default(validated_data, "last_name", "") + email = pop_default(validated_data, "email", None) + company = pop_default(validated_data, "company", None) + covering_note = pop_default(validated_data, "covering_note", "") + send_copy = pop_default(validated_data, "send_copy", False) + send_email = pop_default(validated_data, "send_mail", False) + + instance = super().create(validated_data) + + if send_email and email: + receivers = [email] + + if send_copy: + user = None + request = self.context.get("request") + if request and hasattr(request, "user"): + user = request.user + receivers.append(user.email) + + send_mail( + compose_direct_reservation_mail_subject(language), + compose_direct_reservation_mail_body( + first_name, + last_name, + company, + instance.get_external_url(), + covering_note, + language, + ), + None, + receivers, + False, + ) + + return instance diff --git a/plotsearch/tests/api/test_direct_reservation_links.py b/plotsearch/tests/api/test_direct_reservation_links.py index 8be6218d..31ebc588 100644 --- a/plotsearch/tests/api/test_direct_reservation_links.py +++ b/plotsearch/tests/api/test_direct_reservation_links.py @@ -6,7 +6,6 @@ from plotsearch.models.plot_search import DirectReservationLink, Favourite -@pytest.mark.django_db def test_direct_reservation_link_create( django_db_setup, admin_client, @@ -30,6 +29,14 @@ def test_direct_reservation_link_create( data = { "targets": [target.id], + "language": "FI", + "first_name": "Pekka", + "last_name": "Testaaja", + "email": "pekkatestaaja@testimaili.org", + "company": "", + "covering_note": "Saateteksti", + "send_copy": False, + "send_mail": True, } url = reverse("directreservationlink-list") diff --git a/plotsearch/utils.py b/plotsearch/utils.py index 297cc536..121c9792 100644 --- a/plotsearch/utils.py +++ b/plotsearch/utils.py @@ -1,9 +1,11 @@ +from django.utils.translation import override +from django.utils.translation import ugettext_lazy as _ + from forms.models import Choice, Field, Form, Section from plotsearch.enums import AreaSearchLessor def map_intended_use_to_lessor(intended_use): - if intended_use is None: return None @@ -752,3 +754,33 @@ def get_applicant(answer, reservation_recipients): reservation_recipients.append( " ".join([front_name.value, last_name.value]) ) + + +def compose_direct_reservation_mail_subject(language): + with override(language): + subject = _("You have received a link for a direct reservation plot search") + return subject + + +def compose_direct_reservation_mail_body( + first_name, last_name, company, url, covering_note, language +): + with override(language): + receiver = ( + company + if company + else "{first_name} {last_name}".format( + first_name=first_name, last_name=last_name + ) + ) + body = _( + "Hi {receiver}! Here is the link for the direct reservation plot search: {url} \n\n{covering_note}" + ).format(receiver=receiver, url=url, covering_note=covering_note,) + return body + + +def pop_default(validated_data, index, default_value): + try: + return validated_data.pop(index) + except IndexError: + return default_value diff --git a/plotsearch/views/plot_search.py b/plotsearch/views/plot_search.py index 48c42033..42ef2bf2 100755 --- a/plotsearch/views/plot_search.py +++ b/plotsearch/views/plot_search.py @@ -294,9 +294,14 @@ def get(self, request, *args, **kwargs): Favourite.objects.filter(user=request.user).delete() direct_reservation_link = DirectReservationLink.objects.get(uuid=kwargs["uuid"]) favourite = Favourite.objects.create(user=request.user) + targets = [] for plot_search_target in direct_reservation_link.targets.all(): - FavouriteTarget.objects.create( + target, created = FavouriteTarget.objects.get_or_create( favourite=favourite, plot_search_target=plot_search_target ) + if created: + targets.append(target) + for target in targets: + target.refresh_from_db() - return Response(status=200) + return Response(FavouriteSerializer(favourite).data, status=200)