#!/usr/bin/python """ django-helpdesk - A Django powered ticket tracker for small enterprise. (c) Copyright 2008 Jutda. All Rights Reserved. See LICENSE for details. scripts/escalate_tickets.py - Easy way to escalate tickets based on their age, designed to be run from Cron or similar. """ from datetime import date, timedelta from django.core.management.base import BaseCommand from django.db.models import Q from django.utils import timezone from django.utils.translation import gettext as _ from helpdesk.lib import safe_template_context from helpdesk.models import EscalationExclusion, Queue, Ticket class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument( "-q", "--queues", nargs="*", choices=list(Queue.objects.values_list("slug", flat=True)), help="Queues to include (default: all). Enter the queues slug as space separated list.", ) parser.add_argument( "-x", "--escalate-verbosely", action="store_true", default=False, help="Display escalated tickets", ) parser.add_argument( "-n", "--notify-only", action="store_true", default=False, help="Send email reminder but dont escalate tickets", ) def handle(self, *args, **options): verbose = options["escalate_verbosely"] notify_only = options["notify_only"] queue_slugs = options["queues"] # Only include queues with escalation configured queues = Queue.objects.filter(escalate_days__isnull=False).exclude( escalate_days=0 ) if queue_slugs is not None: queues = queues.filter(slug__in=queue_slugs) if verbose: self.stdout.write(f"Processing: {queues}") for queue in queues: last = date.today() - timedelta(days=queue.escalate_days) today = date.today() workdate = last days = 0 while workdate < today: if not EscalationExclusion.objects.filter(date=workdate).exists(): days += 1 workdate = workdate + timedelta(days=1) req_last_escl_date = timezone.now() - timedelta(days=days) for ticket in ( queue.ticket_set.filter(status__in=Ticket.OPEN_STATUSES) .exclude(priority=1) .filter(Q(on_hold__isnull=True) | Q(on_hold=False)) .filter( Q(last_escalation__lte=req_last_escl_date) | Q(last_escalation__isnull=True, created__lte=req_last_escl_date) ) ): ticket.last_escalation = timezone.now() ticket.priority -= 1 ticket.save() context = safe_template_context(ticket) ticket.send( { "submitter": ("escalated_submitter", context), "ticket_cc": ("escalated_cc", context), "assigned_to": ("escalated_owner", context), }, fail_silently=True, ) if verbose: self.stdout.write( f" - Esclating {ticket.ticket} from {ticket.priority + 1}>{ticket.priority}" ) if not notify_only: followup = ticket.followup_set.create( title=_("Ticket Escalated"), public=True, comment=_("Ticket escalated after %(nb)s days") % {"nb": queue.escalate_days}, ) followup.ticketchange_set.create( field=_("Priority"), old_value=ticket.priority + 1, new_value=ticket.priority, )