mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2024-12-13 10:21:05 +01:00
6c37d73d4e
This refactor removes duplicated logic for deciding whom the messages get sent to. It also normalizes behavior ensuring that all CCed addresses are sent to in all cases that CCed individuals should be notified.
177 lines
5.1 KiB
Python
177 lines
5.1 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 __future__ import print_function
|
|
|
|
from datetime import timedelta, date
|
|
import getopt
|
|
from optparse import make_option
|
|
import sys
|
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
from django.db.models import Q
|
|
from django.utils.translation import ugettext as _
|
|
|
|
try:
|
|
from django.utils import timezone
|
|
except ImportError:
|
|
from datetime import datetime as timezone
|
|
|
|
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
|
|
from helpdesk.lib import safe_template_context
|
|
|
|
|
|
class Command(BaseCommand):
|
|
|
|
def __init__(self):
|
|
BaseCommand.__init__(self)
|
|
|
|
self.option_list += (
|
|
make_option(
|
|
'--queues',
|
|
help='Queues to include (default: all). Use queue slugs'),
|
|
make_option(
|
|
'--verboseescalation',
|
|
action='store_true',
|
|
default=False,
|
|
help='Display a list of dates excluded'),
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
verbose = False
|
|
queue_slugs = None
|
|
queues = []
|
|
|
|
if options['verboseescalation']:
|
|
verbose = True
|
|
if options['queues']:
|
|
queue_slugs = options['queues']
|
|
|
|
if queue_slugs is not None:
|
|
queue_set = queue_slugs.split(',')
|
|
for queue in queue_set:
|
|
try:
|
|
Queue.objects.get(slug__exact=queue)
|
|
except Queue.DoesNotExist:
|
|
raise CommandError("Queue %s does not exist." % queue)
|
|
queues.append(queue)
|
|
|
|
escalate_tickets(queues=queues, verbose=verbose)
|
|
|
|
|
|
def escalate_tickets(queues, verbose):
|
|
""" Only include queues with escalation configured """
|
|
queryset = Queue.objects.filter(escalate_days__isnull=False).exclude(escalate_days=0)
|
|
if queues:
|
|
queryset = queryset.filter(slug__in=queues)
|
|
|
|
for q in queryset:
|
|
last = date.today() - timedelta(days=q.escalate_days)
|
|
today = date.today()
|
|
workdate = last
|
|
|
|
days = 0
|
|
|
|
while workdate < today:
|
|
if EscalationExclusion.objects.filter(date=workdate).count() == 0:
|
|
days += 1
|
|
workdate = workdate + timedelta(days=1)
|
|
|
|
req_last_escl_date = date.today() - timedelta(days=days)
|
|
|
|
if verbose:
|
|
print("Processing: %s" % q)
|
|
|
|
for t in q.ticket_set.filter(
|
|
Q(status=Ticket.OPEN_STATUS) |
|
|
Q(status=Ticket.REOPENED_STATUS)
|
|
).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)
|
|
):
|
|
|
|
t.last_escalation = timezone.now()
|
|
t.priority -= 1
|
|
t.save()
|
|
|
|
context = safe_template_context(t)
|
|
|
|
t.send(
|
|
{'submitter': ('escalated_submitter', context),
|
|
'ticket_cc': ('escalated_cc', context),
|
|
'assigned_to': ('escalated_owner', context)}
|
|
fail_silently=True,
|
|
)
|
|
|
|
if verbose:
|
|
print(" - Esclating %s from %s>%s" % (
|
|
t.ticket,
|
|
t.priority + 1,
|
|
t.priority
|
|
)
|
|
)
|
|
|
|
f = FollowUp(
|
|
ticket=t,
|
|
title='Ticket Escalated',
|
|
date=timezone.now(),
|
|
public=True,
|
|
comment=_('Ticket escalated after %s days' % q.escalate_days),
|
|
)
|
|
f.save()
|
|
|
|
tc = TicketChange(
|
|
followup=f,
|
|
field=_('Priority'),
|
|
old_value=t.priority + 1,
|
|
new_value=t.priority,
|
|
)
|
|
tc.save()
|
|
|
|
|
|
def usage():
|
|
print("Options:")
|
|
print(" --queues: Queues to include (default: all). Use queue slugs")
|
|
print(" --verboseescalation: Display a list of dates excluded")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
opts, args = getopt.getopt(sys.argv[1:], ['queues=', 'verboseescalation'])
|
|
except getopt.GetoptError:
|
|
usage()
|
|
sys.exit(2)
|
|
|
|
verbose = False
|
|
queue_slugs = None
|
|
queues = []
|
|
|
|
for o, a in opts:
|
|
if o == '--verboseescalation':
|
|
verbose = True
|
|
if o == '--queues':
|
|
queue_slugs = a
|
|
|
|
if queue_slugs is not None:
|
|
queue_set = queue_slugs.split(',')
|
|
for queue in queue_set:
|
|
try:
|
|
q = Queue.objects.get(slug__exact=queue)
|
|
except Queue.DoesNotExist:
|
|
print("Queue %s does not exist." % queue)
|
|
sys.exit(2)
|
|
queues.append(queue)
|
|
|
|
escalate_tickets(queues=queues, verbose=verbose)
|