diff --git a/src/dispatch/case/messaging.py b/src/dispatch/case/messaging.py new file mode 100644 index 000000000000..80d8499af764 --- /dev/null +++ b/src/dispatch/case/messaging.py @@ -0,0 +1,87 @@ +""" +.. module: dispatch.case.messaging + :platform: Unix + :copyright: (c) 2019 by Netflix Inc., see AUTHORS for more + :license: Apache, see LICENSE for more details. +""" +import logging + +from dispatch.database.core import SessionLocal +from dispatch.case.models import Case +from dispatch.messaging.strings import ( + CASE_CLOSE_REMINDER, + CASE_TRIAGE_REMINDER, + MessageType, +) +from dispatch.plugin import service as plugin_service + + +log = logging.getLogger(__name__) + + +def send_case_close_reminder(case: Case, db_session: SessionLocal): + """ + Sends a direct message to the assignee reminding them to close the case if possible. + """ + message_text = "Case Close Reminder" + message_template = CASE_CLOSE_REMINDER + + plugin = plugin_service.get_active_instance( + db_session=db_session, project_id=case.project.id, plugin_type="conversation" + ) + if not plugin: + log.warning("Case close reminder message not sent. No conversation plugin enabled.") + return + + items = [ + { + "name": case.name, + "ticket_weblink": case.ticket.weblink, + "title": case.title, + "status": case.status, + } + ] + + plugin.instance.send_direct( + case.assignee.individual.email, + message_text, + message_template, + MessageType.case_status_reminder, + items=items, + ) + + log.debug(f"Case close reminder sent to {case.assignee.individual.email}.") + + +def send_case_triage_reminder(case: Case, db_session: SessionLocal): + """ + Sends a direct message to the assignee reminding them to triage the case if possible. + """ + message_text = "Case Triage Reminder" + message_template = CASE_TRIAGE_REMINDER + + plugin = plugin_service.get_active_instance( + db_session=db_session, project_id=case.project.id, plugin_type="conversation" + ) + if not plugin: + log.warning("Case triage reminder message not sent. No conversation plugin enabled.") + return + + items = [ + { + "name": case.name, + "ticket_weblink": case.ticket.weblink, + "title": case.title, + "status": case.status, + } + ] + + plugin.instance.send_direct( + case.assignee.individual.email, + message_text, + message_template, + MessageType.case_status_reminder, + items=items, + ) + + log.debug(f"Case close reminder sent to {case.assignee.individual.email}.") diff --git a/src/dispatch/case/scheduled.py b/src/dispatch/case/scheduled.py new file mode 100644 index 000000000000..fa386bcf085e --- /dev/null +++ b/src/dispatch/case/scheduled.py @@ -0,0 +1,47 @@ +from datetime import datetime, date +from schedule import every + +from dispatch.database.core import SessionLocal +from dispatch.decorators import scheduled_project_task, timer +from dispatch.project.models import Project +from dispatch.scheduler import scheduler + +from .enums import CaseStatus +from .messaging import send_case_close_reminder, send_case_triage_reminder +from .service import ( + get_all_by_status, +) + + +@scheduler.add(every(1).day.at("18:00"), name="case-close-reminder") +@timer +@scheduled_project_task +def case_close_reminder(db_session: SessionLocal, project: Project): + """Sends a reminder to the case assignee to close out their case.""" + cases = get_all_by_status( + db_session=db_session, project_id=project.id, status=CaseStatus.triage + ) + + for case in cases: + span = datetime.utcnow() - case.triage_at + q, r = divmod(span.days, 7) + if q >= 1 and date.today().isoweekday() == 1: + # we only send the reminder for cases that have been triaging + # longer than a week and only on Mondays + send_case_close_reminder(case, db_session) + + +@scheduler.add(every(1).day.at("18:00"), name="case-triage-reminder") +@timer +@scheduled_project_task +def case_triage_reminder(db_session: SessionLocal, project: Project): + """Sends a reminder to the case assignee to triage their case.""" + cases = get_all_by_status(db_session=db_session, project_id=project.id, status=CaseStatus.new) + + # if we want more specific SLA reminders, we would need to add additional data model + for case in cases: + span = datetime.utcnow() - case.created + q, r = divmod(span.days, 1) + if q >= 1: + # we only send one reminder per case per day + send_case_triage_reminder(case, db_session)