mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2025-03-06 03:02:02 +01:00
text to assist with future translation efforts. I've no doubt missed a few. Also we don't have a "Change Language" view in here, unsure if this should be a helpdesk function or a function of the parent project. * Updated svn:ignore to ignore .pyc files * Added new function to replace cursor.dictfetchall() which is available in psycopg1 but not psycopg2. New function should work across other database systems, but is untested.
115 lines
3.9 KiB
Python
115 lines
3.9 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
|
|
|
|
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': queue,
|
|
}
|
|
|
|
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:
|
|
print "Queue %s does not exist." % queue
|
|
sys.exit(2)
|
|
queues.append(queue)
|
|
|
|
escalate_tickets(queues=queues, verbose=verbose)
|