django-helpdesk/management/commands/escalate_tickets.py
Ross Poulton cea6394b70 Big bugfix release - addresses a number of issues introduced in recent Django
updates, and other bugs in the codebase. Many thanks to David Clymer and
Chris Etcp for reporting these bugs and then providing fixes.

Tickets closed:

#3: BUG E-Mail Script Incompatible with Python 2.5
#4: BUG Failure on empty attachments
#5: ENHANCEMENT Run scripts as command extensions [Backwards Compatible]
#7: BUG Cannot view tickets when not logged in
#8: BUG Overly broad error handling

Note that #5 is backwards-incompatible, as you need to change any CRON or 
scheduler entries for the 'get_email.py', 'escalate_tickets.py' or 
'create_escalation_exclusions.py' scripts. See the README file for the new 
commands.
2008-08-18 21:29:31 +00:00

154 lines
5.1 KiB
Python

#!/usr/bin/python
"""
Jutda 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 datetime, timedelta, date
import sys, getopt
from django.db.models import Q
from django.utils.translation import ugettext as _
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
from helpdesk.lib import send_templated_mail
from django.core.management.base import BaseCommand
from optparse import make_option
class Command(BaseCommand):
def __init__(self):
BaseCommand.__init__(self)
self.option_list += (
make_option(
'--queues', '-q',
help='Queues to include (default: all). Use queue slugs'),
make_option(
'--verbose', '-v',
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['verbose']:
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:
q = 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)):
t.last_escalation = datetime.now()
t.priority -= 1
t.save()
context = {
'ticket': t,
'queue': q,
}
if t.submitter_email:
send_templated_mail('escalated_submitter', context, recipients=t.submitter_email, sender=t.queue.from_address, fail_silently=True)
if t.queue.updated_ticket_cc:
send_templated_mail('escalated_cc', context, recipients=t.queue.updated_ticket_cc, sender=t.queue.from_address, fail_silently=True)
if t.assigned_to:
send_templated_mail('escalated_owner', context, recipients=t.assigned_to.email, sender=t.queue.from_address, 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=datetime.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, -q: Queues to include (default: all). Use queue slugs"
print " --verbose, -v: Display a list of dates excluded"
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], 'q:v', ['queues=', 'verbose'])
except getopt.GetoptError:
usage()
sys.exit(2)
verbose = False
queue_slugs = None
queues = []
for o, a in opts:
if o in ('-v', '--verbose'):
verbose = True
if o in ('-q', '--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)