mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2025-06-10 11:46:43 +02:00
115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
#!/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,
|
|
)
|