Skip to content

Commit

Permalink
add celery notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
depsiatwal committed Feb 12, 2024
1 parent ffa40fe commit dd8db7e
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 7 deletions.
77 changes: 75 additions & 2 deletions api/cases/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from pytz import timezone as tz

from api.cases.enums import CaseTypeSubTypeEnum
from api.cases.models import Case, CaseAssignmentSLA, CaseQueue, DepartmentSLA
from api.cases.models import EcjuQuery
from api.cases.models import Case, CaseAssignmentSLA, CaseQueue, DepartmentSLA, EcjuQuery
from api.common.dates import is_weekend, is_bank_holiday
from api.staticdata.statuses.enums import CaseStatusEnum
from api.staticdata.statuses.models import CaseStatus
from api.cases.notify import notify_exporter_ecju_query_chaser


# DST safe version of midnight
SLA_UPDATE_CUTOFF_TIME = time(18, 0, 0)
Expand Down Expand Up @@ -156,3 +157,75 @@ def update_cases_sla():

logger.info("SLA Update Not Performed. Non-working day")
return False


WORKING_DAYS_ECJU_QUERY_CHASER_REMINDER = 15
WORKING_DAYS_APPLICATION = 20


@shared_task(
autoretry_for=(Exception,),
max_retries=MAX_ATTEMPTS,
retry_backoff=RETRY_BACKOFF,
)
def schedule_all_ecju_query_chaser_emails():
"""
Sends an ECJU 15 working days reminder
Runs as a background task daily at a given time.
Doesn't run on non-working days (bank-holidays & weekends)
"""
logger.info("Sending all ECJU query chaser emails started")

try:
ecju_query_reminders = []
ecju_queries = EcjuQuery.objects.filter(
Q(is_query_closed=False) & Q(chaser_email_sent_on__isnull=True) & Q(case__status__is_terminal=False)
)

for ecju_query in ecju_queries:
if (
ecju_query.open_working_days >= WORKING_DAYS_ECJU_QUERY_CHASER_REMINDER
and ecju_query.open_working_days <= WORKING_DAYS_APPLICATION
):
ecju_query_reminders.append(ecju_query.id)

for ecju_query_id in ecju_query_reminders:
# Now lets loop round and send the notifications
send_ecju_query_chaser_email.delay(ecju_query_id)

logger.info("Sending all ECJU query chaser emails started finished")

except Exception as e: # noqa
logger.error(e)
raise e


@shared_task(
autoretry_for=(Exception,),
max_retries=MAX_ATTEMPTS,
retry_backoff=RETRY_BACKOFF,
)
def send_ecju_query_chaser_email(ecju_query_id):
"""
Sends an ecju query chaser email based on a case
Call back is to mark the relevent queries as chaser sent
"""
logger.info("Sending ECJU Query chaser emails for ecju_query_id %s started", ecju_query_id)
try:
notify_exporter_ecju_query_chaser(ecju_query_id, callback=mark_ecju_queries_as_sent.si(ecju_query_id))
logger.info("Sending ECJU Query chaser email for ecju_query_id %s finished", ecju_query_id)
except Exception as e: # noqa
logger.error(e)
raise e


@shared_task
def mark_ecju_queries_as_sent(ecju_query_id):
"""
Used as a call back method to set chaser_email_sent once a chaser email has been sent
"""
logger.info("Mark ECJU queries with chaser_email_sent as true for ecju_query_ids (%s) ", ecju_query_id)
ecju_query = EcjuQuery.objects.get(chaser_email_sent_on__isnull=True, id=ecju_query_id)
ecju_query.chaser_email_sent_on = timezone.datetime.now()
# Save base so we don't impact any over fields
ecju_query.save_base()
18 changes: 18 additions & 0 deletions api/cases/migrations/0063_ecjuquery_chaser_email_sent_on.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.23 on 2024-02-07 16:05

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('cases', '0062_alter_ecjuquery_response'),
]

operations = [
migrations.AddField(
model_name='ecjuquery',
name='chaser_email_sent_on',
field=models.DateTimeField(blank=True, null=True),
),
]
3 changes: 2 additions & 1 deletion api/cases/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ class EcjuQuery(TimestampableModel):
query_type = models.CharField(
choices=ECJUQueryType.choices, max_length=50, default=ECJUQueryType.ECJU, null=False, blank=False
)
chaser_email_sent_on = models.DateTimeField(blank=True, null=True)

@queryable_property
def is_query_closed(self):
Expand All @@ -636,7 +637,7 @@ def is_manually_closed(self):
# This method allows the above propery to be used in filtering objects. Similar to db fields.
@is_query_closed.filter(lookups=("exact",))
def is_query_closed(self, lookup, value):
return ~Q(responded_at__isnull=value)
return ~Q(responded_by_user__isnull=value)

@property
def open_working_days(self):
Expand Down
25 changes: 24 additions & 1 deletion api/cases/notify.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from django.db.models import F

from api.core.helpers import get_exporter_frontend_url
from api.cases.models import Case
from api.cases.models import Case, EcjuQuery
from gov_notify.enums import TemplateType
from gov_notify.payloads import (
ExporterECJUQuery,
ExporterECJUQueryChaser,
ExporterLicenceIssued,
ExporterLicenceRefused,
ExporterNoLicenceRequired,
Expand Down Expand Up @@ -104,11 +105,33 @@ def notify_exporter_ecju_query(case_pk):
)


def notify_exporter_ecju_query_chaser(ecju_query_id, callback):
APPLICATION_WORKING_DAYS = 20
ecju_query = EcjuQuery.objects.get(id=ecju_query_id)

exporter_frontend_ecju_queries_url = get_exporter_frontend_url(f"/applications/{ecju_query.case_id}/ecju-queries/")

_notify_exporter_ecju_query_chaser(
ecju_query.case.submitted_by.email,
{
"case_reference": ecju_query.case.reference_code,
"exporter_frontend_ecju_queries_url": exporter_frontend_ecju_queries_url,
"remaining_days": APPLICATION_WORKING_DAYS - ecju_query.open_working_days,
},
callback,
)


def _notify_exporter_ecju_query(email, data):
payload = ExporterECJUQuery(**data)
send_email(email, TemplateType.EXPORTER_ECJU_QUERY, payload)


def _notify_exporter_ecju_query_chaser(email, data, callback):
payload = ExporterECJUQueryChaser(**data)
send_email(email, TemplateType.EXPORTER_ECJU_QUERY_CHASER, payload, callback)


def _notify_exporter_no_licence_required(email, data):
payload = ExporterNoLicenceRequired(**data)
send_email(email, TemplateType.EXPORTER_NO_LICENCE_REQUIRED, payload)
Expand Down
Loading

0 comments on commit dd8db7e

Please sign in to comment.