Exemplo n.º 1
0
    def resend_application_confirmation(self, request, queryset):
        resent_count = 0
        for application in queryset:
            context = {
                "subject": NotificationType.BERTH_APPLICATION_CREATED.label,
                **application.get_notification_context(),
            }
            try:
                send_notification(
                    application.email,
                    NotificationType.BERTH_APPLICATION_CREATED.value,
                    context,
                    application.language,
                )
                resent_count += 1
            except (OSError, AnymailError):
                logger.error(
                    "Failed to resend confirmation for berth application {}".format(
                        application.id
                    )
                )

        self.message_user(
            request,
            _("Resent confirmation for %d berth application(s)") % resent_count,
            messages.SUCCESS,
        )
Exemplo n.º 2
0
    def handle(self, *args, **options):
        email = options["email"]
        notification_type = options["notification_type"]
        custom_context = options["context"]

        if notification_data := get_notification_data(notification_type):
            notification_type = notification_data["notification_type"]
            default_context = notification_data["context"]

            notification = {
                "email": email,
                "language": "en",
                "context": {
                    **default_context,
                    **custom_context
                },
                "notification_type": notification_type,
            }

            try:
                send_notification(**notification)

                self.stdout.write(self.style.SUCCESS("Notification sent"))
                self.stdout.write(json.dumps(notification, indent=2))
            except Exception as e:
                self.stdout.write(
                    self.style.ERROR(f"Error while sending notification: {e}"))
Exemplo n.º 3
0
    def mutate_and_get_payload(cls, root, info, **input):
        youth_data = input.get("approval_data")
        token = input.get("approval_token")

        youth_profile = YouthProfile.objects.get(approval_token=token)

        for field, value in youth_data.items():
            setattr(youth_profile, field, value)

        try:
            email = youth_profile.profile.get_primary_email()
        except Email.DoesNotExist:
            raise ProfileHasNoPrimaryEmailError(
                "Cannot send email confirmation, youth profile has no primary email address."
            )

        youth_profile.approved_time = timezone.now()
        youth_profile.approval_token = ""  # invalidate
        youth_profile.save()
        send_notification(
            email=email.email,
            notification_type=NotificationType.YOUTH_PROFILE_CONFIRMED.value,
            context={"youth_profile": youth_profile},
            language=youth_profile.profile.language
            if youth_profile.profile else "fi",
        )
        return ApproveYouthProfileMutation(youth_profile=youth_profile)
Exemplo n.º 4
0
    def resend_application_confirmation(self, request, queryset):
        resent_count = 0
        for application in queryset:
            try:
                notification_type = (
                    NotificationType.UNMARKED_WINTER_STORAGE_APPLICATION_CREATED
                    if application.area_type == ApplicationAreaType.UNMARKED
                    else NotificationType.WINTER_STORAGE_APPLICATION_CREATED
                )
                context = {
                    "subject": notification_type.label,
                    **application.get_notification_context(),
                }
                send_notification(
                    application.email,
                    notification_type.value,
                    context,
                    application.language,
                )
                resent_count += 1
            except (OSError, AnymailError):
                logger.error(
                    "Failed to resend confirmation for winter storage application {}".format(
                        application.id
                    )
                )

        self.message_user(
            request,
            _("Resent confirmation for %d winter storage application(s)")
            % resent_count,
            messages.SUCCESS,
        )
Exemplo n.º 5
0
 def make_approvable(self):
     self.approval_token = uuid.uuid4()
     send_notification(
         email=self.approver_email,
         notification_type=NotificationType.
         YOUTH_PROFILE_CONFIRMATION_NEEDED.value,
         context={"youth_profile": self},
         language=self.language_at_home.value,
     )
     self.approval_notification_timestamp = timezone.now()
Exemplo n.º 6
0
def index(request):
    animal = Animal(name="Rox the Fox")
    context = {
        "animal": animal,
        "foo": "bar",
    }

    attachment = "test.txt", "foo bar", "text/plain"

    send_notification("*****@*****.**", "event_created", context, "en", [attachment])
    return HttpResponse("Hello, world. You're at the polls index.")
    def mutate_and_get_payload(cls, root, info, **input):
        youth_data = input.get("approval_data")
        token = input.get("approval_token")
        if not token:
            raise GraphQLError("Approval token cannot be empty.")
        youth_profile = YouthProfile.objects.get(approval_token=token)
        if (not youth_profile.profile_access_token
                or youth_profile.profile_access_token_expiration <
                timezone.now()):
            raise TokenExpiredError(
                "Profile access token is expired or not set.")

        profile_api = ProfileAPI()
        profile_data = profile_api.fetch_profile_with_temporary_access_token(
            youth_profile.profile_access_token)
        if not profile_data["email"]:
            raise ProfileHasNoPrimaryEmailError(
                "Cannot send email confirmation, youth profile has no primary email address."
            )

        contact_persons_to_create = youth_data.pop(
            "add_additional_contact_persons", [])
        contact_persons_to_update = youth_data.pop(
            "update_additional_contact_persons", [])
        contact_persons_to_delete = youth_data.pop(
            "remove_additional_contact_persons", [])

        for field, value in youth_data.items():
            setattr(youth_profile, field, value)

        # Additional contact persons
        create_or_update_contact_persons(youth_profile,
                                         contact_persons_to_create)
        create_or_update_contact_persons(youth_profile,
                                         contact_persons_to_update)
        delete_contact_persons(youth_profile, contact_persons_to_delete)

        youth_profile.set_approved()
        youth_profile.save()

        send_notification(
            email=profile_data["email"],
            notification_type=NotificationType.YOUTH_PROFILE_CONFIRMED.value,
            context={
                "youth_profile":
                youth_profile,
                "youth_name":
                profile_data["first_name"],
                "youth_membership_ui_base_url":
                settings.EMAIL_TEMPLATE_YOUTH_MEMBERSHIP_UI_BASE_URL,
            },
            language=profile_data["language"],
        )
        return ApproveYouthProfileMutation(youth_profile=youth_profile)
Exemplo n.º 8
0
 def make_approvable(self, youth_name: str):
     self.approval_token = uuid.uuid4()
     send_notification(
         email=self.approver_email,
         notification_type=NotificationType.YOUTH_PROFILE_CONFIRMATION_NEEDED.value,
         context={
             "youth_profile": self,
             "youth_name": youth_name,
             "youth_membership_ui_base_url": settings.EMAIL_TEMPLATE_YOUTH_MEMBERSHIP_UI_BASE_URL,
         },
         language=self.language_at_home.value,
     )
     self.approval_notification_timestamp = timezone.now()
Exemplo n.º 9
0
def test_translated_from_email(notification_template, settings, language):
    context = {
        "extra_var": "foo",
        "subject_var": "bar",
        "body_html_var": "html_baz",
        "body_text_var": "text_baz",
    }
    settings.ILMOITIN_TRANSLATED_FROM_EMAIL = {"fi": "Yrjö <*****@*****.**>"}

    send_notification("*****@*****.**", "event_created", context, language)

    assert len(mail.outbox) == 1
    message = mail.outbox[0]
    assert message.from_email == settings.ILMOITIN_TRANSLATED_FROM_EMAIL.get(
        language, settings.DEFAULT_FROM_EMAIL
    )
Exemplo n.º 10
0
 def email_admins(self, exited_with_errors: bool = False):
     logger.debug("Emailing admins")
     context = {
         "subject":
         LeaseNotificationType.AUTOMATIC_INVOICING_EMAIL_ADMINS.label,
         "exited_with_errors": exited_with_errors,
         "successful_orders": len(self.successful_orders),
         "failed_orders": self.number_of_failed_orders,
     }
     admins = (get_user_model().objects.filter(groups=Group.objects.get(
         name=self.ADMIN_EMAIL_NOTIFICATION_GROUP_NAME)).exclude(
             email="").exclude(email__icontains="@example.com"))
     for admin in admins:
         send_notification(
             admin.email,
             LeaseNotificationType.AUTOMATIC_INVOICING_EMAIL_ADMINS,
             context,
         )
Exemplo n.º 11
0
def application_notification_handler(sender, application, **kwargs):
    notification_type = NotificationType.BERTH_APPLICATION_CREATED
    if sender == MARKED_WS_SENDER:
        notification_type = NotificationType.WINTER_STORAGE_APPLICATION_CREATED
    elif sender == UNMARKED_WS_SENDER:
        notification_type = NotificationType.UNMARKED_WINTER_STORAGE_APPLICATION_CREATED
    elif sender == REJECT_BERTH_SENDER:
        notification_type = NotificationType.BERTH_APPLICATION_REJECTED

    context = {
        "subject": notification_type.label,
        **application.get_notification_context(),
    }
    try:
        send_notification(
            application.email, notification_type.value, context, application.language,
        )
    except (OSError, AnymailError) as e:
        capture_exception(e)
Exemplo n.º 12
0
def test_notification_delayed_sending(notification_template):
    context = {
        "extra_var": "foo",
        "subject_var": "bar",
        "body_html_var": "html_baz",
        "body_text_var": "text_baz",
    }
    # Override settings to use django-mailer email backend
    settings.EMAIL_BACKEND = "mailer.backend.DbBackend"
    settings.MAILER_EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
    settings.ILMOITIN_QUEUE_NOTIFICATIONS = True

    send_notification("*****@*****.**", "event_created", context, "fi")
    assert len(mail.outbox) == 0
    assert Message.objects.count() == 1
    # Now actually send emails
    Message.objects.retry_deferred()
    send_all()
    assert Message.objects.count() == 0
    assert len(mail.outbox) == 1
Exemplo n.º 13
0
def test_notification_sending(notification_template):
    context = {
        "extra_var": "foo",
        "subject_var": "bar",
        "body_html_var": "html_baz",
        "body_text_var": "text_baz",
    }
    send_notification("*****@*****.**", "event_created", context, "fi")

    assert len(mail.outbox) == 1
    message = mail.outbox[0]
    subject = message.subject
    body_html = next(a[0] for a in message.alternatives if a[1] == "text/html")
    body_text = message.body

    assert message.to == ["*****@*****.**"]
    assert message.from_email == settings.DEFAULT_FROM_EMAIL
    assert subject == "testiotsikko, muuttujan arvo: bar!"
    assert body_html == "<b>testihötömölöruumis</b>, muuttujan arvo: html_baz!"
    assert body_text == "testitekstiruumis, muuttujan arvo: text_baz!"
Exemplo n.º 14
0
def send_berth_switch_offer(
    offer,
    due_date: date,
) -> None:
    if due_date:
        offer.due_date = due_date
        offer.save()

    # Update offer and application status
    offer.set_status(OfferStatus.OFFERED)

    from .notifications import NotificationType

    language = (offer.application.language
                if offer.application else settings.LANGUAGE_CODE)

    email = offer.customer_email or offer.application.email

    if not is_valid_email(email):
        raise ValidationError(_("Missing customer email"))

    notification_type = NotificationType.BERTH_SWITCH_OFFER_APPROVED

    context = {
        "subject": get_email_subject(notification_type),
        "offer": offer,
        "accept_url": get_offer_customer_url(offer, language, True),
        "cancel_url": get_offer_customer_url(offer, language, False),
        "due_date": format_date(offer.due_date, locale=language),
    }

    send_notification(email, notification_type.value, context, language)

    if offer.customer_phone:
        sms_service = SMSNotificationService()
        sms_service.send(
            NotificationType.SMS_BERTH_SWITCH_NOTICE,
            context,
            offer.customer_phone,
            language=language,
        )
Exemplo n.º 15
0
def send_refund_notice(order):
    from .notifications import NotificationType

    language = (order.lease.application.language if order.lease
                and order.lease.application else settings.LANGUAGE_CODE)
    notification_type = NotificationType.ORDER_REFUNDED

    context = get_context(order,
                          notification_type,
                          has_services=False,
                          payment_url=None,
                          cancel_url=None)

    email = order.customer_email

    if not email:
        if order.lease and order.lease.application:
            email = order.lease.application.email
        else:
            raise VenepaikkaGraphQLError(_("No email was found"))

    send_notification(email, notification_type.value, context, language)
Exemplo n.º 16
0
def relationship_saved_handler(sender, instance, created, **kwargs):
    confirmed = instance.confirmation_degree != RepresentativeConfirmationDegree.NONE

    # Only notify person whose confirmation is needed
    if created and not confirmed:
        try:
            send_notification(
                instance.representative.email,
                NotificationType.RELATIONSHIP_CONFIRMATION_NEEDED.value,
                instance.get_notification_context(),
                instance.representative.language,
            )
        except (OSError, AnymailError) as e:
            capture_exception(e)

    # Notify both parties involved
    elif confirmed:
        try:
            send_notification(
                instance.representative.email,
                NotificationType.RELATIONSHIP_CONFIRMED.value,
                instance.get_notification_context(),
                instance.representative.language,
            )
        except (OSError, AnymailError) as e:
            capture_exception(e)

        try:
            send_notification(
                instance.representee.email,
                NotificationType.RELATIONSHIP_CONFIRMED.value,
                instance.get_notification_context(),
                instance.representee.language,
            )
        except (OSError, AnymailError) as e:
            capture_exception(e)
Exemplo n.º 17
0
def terminate_lease(
    lease: Union[BerthLease, WinterStorageLease],
    end_date: date = None,
    profile_token: str = None,
    send_notice: bool = True,
) -> Union[BerthLease, WinterStorageLease]:
    from .models import BerthLease
    from .notifications import NotificationType

    if lease.status not in TERMINABLE_STATUSES:
        raise ValidationError(
            _(
                f"Only leases in paid, error or offered status can be terminated, current status is {lease.status}"
            )
        )

    for order in lease.orders.all():
        if order.status in OrderStatus.get_waiting_statuses():
            order.set_status(OrderStatus.CANCELLED, _("Lease was terminated"))

    lease.status = LeaseStatus.TERMINATED

    if isinstance(lease, BerthLease):
        default_date = calculate_berth_lease_start_date()
    else:  # WinterStorageLease
        default_date = calculate_winter_storage_lease_start_date()
    lease.end_date = end_date or default_date

    lease.save()

    if send_notice:
        language = (
            lease.application.language
            if lease.application
            else settings.LANGUAGES[0][0]
        )

        email = None

        if profile_token:
            profile_service = ProfileService(profile_token=profile_token)
            profile = profile_service.get_profile(lease.customer.id)
            email = profile.email

        if not email and lease.application:
            email = lease.application.email

        if not email:
            raise ValidationError(
                _("The lease has no email and no profile token was provided")
            )

        if not is_valid_email(email):
            raise ValidationError(_("Missing customer email"))

        notification_type = (
            NotificationType.BERTH_LEASE_TERMINATED_LEASE_NOTICE
            if isinstance(lease, BerthLease)
            else NotificationType.WINTER_STORAGE_LEASE_TERMINATED_LEASE_NOTICE
        )

        send_notification(
            email,
            notification_type,
            {
                "subject": notification_type.label,
                "cancelled_at": format_date(today(), locale=language),
                "lease": lease,
            },
            language=language,
        )

    return lease
Exemplo n.º 18
0
    notification_type = NotificationType.ORDER_CANCELLED
    if rejected_at := getattr(order, "rejected_at", None):
        rejected_at = format_date(rejected_at, locale=language)
    context = {
        "order": order,
        "rejected_at": rejected_at,
        "subject": get_email_subject(notification_type),
    }
    email = order.customer_email
    if not email:
        if order.lease and order.lease.application:
            email = order.lease.application.email
        else:
            raise VenepaikkaGraphQLError(_("No email was found"))

    send_notification(email, notification_type.value, context, language)


def send_refund_notice(order):
    from .notifications import NotificationType

    language = (order.lease.application.language if order.lease
                and order.lease.application else settings.LANGUAGE_CODE)
    notification_type = NotificationType.ORDER_REFUNDED

    context = get_context(order,
                          notification_type,
                          has_services=False,
                          payment_url=None,
                          cancel_url=None)
Exemplo n.º 19
0
def send_payment_notification(
    order: Order,
    request: HttpRequest,
    email: str = None,
    phone_number: str = None,
    has_services: bool = True,
    has_payment_urls: bool = True,
):
    from payments.providers import get_payment_provider

    from .notifications import NotificationType

    order_email = email or order.customer_email
    order_phone = phone_number or order.customer_phone

    if not is_valid_email(order_email):
        raise ValidationError(_("Missing customer email"))

    language = get_notification_language(order)

    payment_url = None
    cancel_url = None

    if has_payment_urls:
        payment_url = get_payment_provider(
            request,
            ui_return_url=settings.VENE_UI_RETURN_URL).get_payment_email_url(
                order, lang=language)

        cancel_url = get_payment_provider(
            request, ui_return_url=settings.VENE_UI_RETURN_URL
        ).get_cancellation_email_url(order, lang=language)

    notification_type = get_order_notification_type(order)
    context = get_context(order, notification_type, has_services, payment_url,
                          cancel_url)
    send_notification(order_email, notification_type.value, context, language)

    if order_phone and notification_type not in (
            NotificationType.ORDER_CANCELLED,
            NotificationType.ORDER_REFUNDED,
    ):
        if hasattr(order, "product") and order.product:
            product_name = order.product.name
        else:
            product_name = ", ".join([
                str(ProductServiceType(order_line.product.service).label)
                for order_line in order.order_lines.all()
            ])

        sms_context = {
            "product_name": product_name,
            "due_date": format_date(order.due_date, locale=language),
            "payment_url": payment_url,
        }
        sms_service = SMSNotificationService()
        sms_service.send(
            NotificationType.SMS_INVOICE_NOTICE,
            sms_context,
            order_phone,
            language=language,
        )