diff --git a/app/notifications/validators.py b/app/notifications/validators.py index adbe27805f..00bd022e98 100644 --- a/app/notifications/validators.py +++ b/app/notifications/validators.py @@ -203,7 +203,7 @@ def check_email_annual_limit(service: Service, requested_emails=0): current_app.logger.info( f"Service {service.id} reached their annual email limit of {service.email_annual_limit} when sending {requested_emails} messages. Sending reached annual limit email." ) - # TODO Send reached limit email + send_annual_limit_reached_email(service, "email", current_fiscal_year + 1) # Will this send put annual usage within 80% of the limit? if is_near_annual_limit and not annual_limit_client.check_has_warning_been_sent(service.id, EMAIL_TYPE): @@ -211,7 +211,9 @@ def check_email_annual_limit(service: Service, requested_emails=0): current_app.logger.info( f"Service {service.id} reached 80% of their annual email limit of {service.email_annual_limit} messages. Sending annual limit usage warning email." ) - # TODO: Send warning email + send_near_annual_limit_warning_email( + service, "email", int(emails_sent_today + emails_sent_this_fiscal), current_fiscal_year + 1 + ) return @@ -255,7 +257,7 @@ def check_sms_annual_limit(service: Service, requested_sms=0): current_app.logger.info( f"Service {service.id} reached their annual SMS limit of {service.sms_annual_limit} messages. Sending reached annual limit email." ) - # TODO Send reached limit email + send_annual_limit_reached_email(service, "email", current_fiscal_year + 1) # Will this send put annual usage within 80% of the limit? if is_near_annual_limit and not annual_limit_client.check_has_warning_been_sent(service.id, EMAIL_TYPE): @@ -263,7 +265,9 @@ def check_sms_annual_limit(service: Service, requested_sms=0): current_app.logger.info( f"Service {service.id} reached 80% of their annual SMS limit of {service.sms_annual_limit} messages. Sending annual limit usage warning email." ) - # TODO: Send warning email + send_near_annual_limit_warning_email( + service, "email", int(sms_sent_today + sms_sent_this_fiscal), current_fiscal_year + 1 + ) return @@ -488,6 +492,76 @@ def send_email_limit_reached_email(service: Service): ) +def send_annual_limit_reached_email(service: Service, notification_type: NotificationType, fiscal_end: int): + send_notification_to_service_users( + service_id=service.id, + template_id=current_app.config["REACHED_ANNUAL_LIMIT_TEMPLATE_ID"], + personalisation={ + "message_type_en": notification_type, + "message_type_fr": "Courriel" if notification_type == EMAIL_TYPE else "SMS", + "fiscal_end": fiscal_end, + "hyperlink_to_page_en": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly", + "hyperlink_to_page_fr": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly?lang=fr", + }, + include_user_fields=["name"], + ) + + +def send_near_annual_limit_warning_email(service: Service, notification_type: NotificationType, count_en: int, fiscal_end: int): + count_fr = "{:,}".format(count_en).replace(",", " ") + if notification_type == EMAIL_TYPE: + message_limit_fr = "{:,}".format(service.email_annual_limit).replace(",", " ") + message_limit_en = service.email_annual_limit + message_type_fr = "Courriel" + remaining_en = service.email_annual_limit - count_en + remaining_fr = "{:,}".format(remaining_en).replace(",", " ") + else: + message_limit_fr = "{:,}".format(service.sms_annual_limit).replace(",", " ") + message_limit_en = service.sms_annual_limit + message_type_fr = "sms" + remaining_en = service.sms_annual_limit - count_en + remaining_fr = "{:,}".format(remaining_en).replace(",", " ") + + send_notification_to_service_users( + service_id=service.id, + template_id=current_app.config["NEAR_ANNUAL_LIMIT_TEMPLATE_ID"], + personalisation={ + "message_type": notification_type, + "fiscal_end": fiscal_end, + "service_name": service.name, + "count_en": count_en, + "count_fr": count_fr, + "message_limit_en": message_limit_en, + "message_limit_fr": message_limit_fr, + "message_type_en": notification_type, + "message_type_fr": message_type_fr, + "remaining_en": remaining_en, + "remaining_fr": remaining_fr, + "hyperlink_to_page_en": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly", + "hyperlink_to_page_fr": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly?lang=fr", + }, + include_user_fields=["name"], + ) + + +def send_annual_limit_updated_email(service: Service, notification_type: NotificationType, fiscal_end: int): + send_notification_to_service_users( + service_id=service.id, + template_id=current_app.config["ANNUAL_LIMIT_UPDATED_TEMPLATE_ID"], + personalisation={ + "message_type_en": notification_type, + "message_type_fr": "Courriel" if notification_type == EMAIL_TYPE else "SMS", + "message_limit_en": service.email_annual_limit if notification_type == EMAIL_TYPE else service.sms_annual_limit, + "message_limit_fr": "{:,}".format( + service.email_annual_limit if notification_type == EMAIL_TYPE else service.sms_annual_limit + ).replace(",", " "), + "hyperlink_to_page_en": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly", + "hyperlink_to_page_fr": f"{current_app.config['ADMIN_BASE_URL']}/services/{service.id}/monthly?lang=fr", + }, + include_user_fields=["name"], + ) + + def check_template_is_for_notification_type(notification_type: NotificationType, template_type: TemplateType): if notification_type != template_type: message = "{0} template is not suitable for {1} notification".format(template_type, notification_type) diff --git a/scripts/run_celery_delivery.sh b/scripts/run_celery_delivery.sh new file mode 100755 index 0000000000..d1ef747f77 --- /dev/null +++ b/scripts/run_celery_delivery.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +# Runs celery with only the delivery-receipts queue. + +echo "Start celery, concurrency: ${CELERY_CONCURRENCY-4}" + +celery -A run_celery.notify_celery worker --pidfile="/tmp/celery.pid" --loglevel=INFO --concurrency="${CELERY_CONCURRENCY-4}" -Q delivery-receipts diff --git a/tests/app/notifications/test_validators.py b/tests/app/notifications/test_validators.py index 955bcdaa89..c217e431aa 100644 --- a/tests/app/notifications/test_validators.py +++ b/tests/app/notifications/test_validators.py @@ -756,7 +756,7 @@ def test_check_email_annual_limit( mocker.patch( "app.annual_limit_client.check_has_warning_been_sent", return_value=has_sent_reached_limit_email ) # Email sent flag checks - + mocker.patch("app.notifications.validators.send_notification_to_service_users") is_near = (counts_from_redis + ft_count + notifications_requested) >= (annual_limit * 0.8) is_reached = (counts_from_redis + ft_count + notifications_requested) == annual_limit @@ -851,7 +851,7 @@ def test_check_sms_annual_limit( mocker.patch( "app.annual_limit_client.check_has_warning_been_sent", return_value=has_sent_reached_limit_email ) # Email sent flag checks - + mocker.patch("app.notifications.validators.send_notification_to_service_users") is_near = (counts_from_redis + ft_count + notifications_requested) >= (annual_limit * 0.8) is_reached = (counts_from_redis + ft_count + notifications_requested) == annual_limit