mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2024-12-13 02:10:49 +01:00
* Added i18n hooks, eg _() and {% trans %} tags around all helpdesk-generated
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.
This commit is contained in:
parent
ad05df8dda
commit
dfb821336e
2
api.py
2
api.py
@ -11,7 +11,7 @@ The API documentation can be accessed by visiting http://helpdesk/api/help/
|
|||||||
through templates/helpdesk/api_help.html.
|
through templates/helpdesk/api_help.html.
|
||||||
"""
|
"""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import simplejson
|
from django.utils import simplejson
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
31
feeds.py
31
feeds.py
@ -2,6 +2,7 @@ from django.contrib.auth.models import User
|
|||||||
from django.contrib.syndication.feeds import Feed
|
from django.contrib.syndication.feeds import Feed
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from models import Ticket, FollowUp, Queue
|
from models import Ticket, FollowUp, Queue
|
||||||
|
|
||||||
@ -22,21 +23,21 @@ class OpenTicketsByUser(Feed):
|
|||||||
|
|
||||||
def title(self, obj):
|
def title(self, obj):
|
||||||
if obj['queue']:
|
if obj['queue']:
|
||||||
return "Helpdesk: Open Tickets in queue %s for %s" % (obj['queue'].title, obj['user'].username)
|
return _("Helpdesk: Open Tickets in queue %(queue)s for %(username)s") % {'queue': obj['queue'].title, 'username': obj['user'].username}
|
||||||
else:
|
else:
|
||||||
return "Helpdesk: Open Tickets for %s" % obj['user'].username
|
return _("Helpdesk: Open Tickets for %(username)s") % {'username': obj['user'].username}
|
||||||
|
|
||||||
def description(self, obj):
|
def description(self, obj):
|
||||||
if obj['queue']:
|
if obj['queue']:
|
||||||
return "Open and Reopened Tickets in queue %s for %s" % (obj['queue'].title, obj['user'].username)
|
return _("Open and Reopened Tickets in queue %(queue)s for %(username)s") % {'queue': obj['queue'].title, 'username': obj['user'].username}
|
||||||
else:
|
else:
|
||||||
return "Open and Reopened Tickets for %s" % obj['user'].username
|
return _("Open and Reopened Tickets for %(username)s") % {'username': obj['user'].username}
|
||||||
|
|
||||||
def link(self, obj):
|
def link(self, obj):
|
||||||
if obj['queue']:
|
if obj['queue']:
|
||||||
return '%s?assigned_to=%s&queue=%s' % (reverse('helpdesk_list'), obj['user'].id, obj['queue'].id)
|
return u'%s?assigned_to=%s&queue=%s' % (reverse('helpdesk_list'), obj['user'].id, obj['queue'].id)
|
||||||
else:
|
else:
|
||||||
return '%s?assigned_to=%s' % (reverse('helpdesk_list'), obj['user'].id)
|
return u'%s?assigned_to=%s' % (reverse('helpdesk_list'), obj['user'].id)
|
||||||
|
|
||||||
def items(self, obj):
|
def items(self, obj):
|
||||||
if obj['queue']:
|
if obj['queue']:
|
||||||
@ -51,15 +52,15 @@ class OpenTicketsByUser(Feed):
|
|||||||
if item.assigned_to:
|
if item.assigned_to:
|
||||||
return item.assigned_to.username
|
return item.assigned_to.username
|
||||||
else:
|
else:
|
||||||
return "Unassigned"
|
return _('Unassigned')
|
||||||
|
|
||||||
|
|
||||||
class UnassignedTickets(Feed):
|
class UnassignedTickets(Feed):
|
||||||
title_template = 'helpdesk/rss/ticket_title.html'
|
title_template = 'helpdesk/rss/ticket_title.html'
|
||||||
description_template = 'helpdesk/rss/ticket_description.html'
|
description_template = 'helpdesk/rss/ticket_description.html'
|
||||||
|
|
||||||
title = "Helpdesk: Unassigned Tickets"
|
title = _('Helpdesk: Unassigned Tickets')
|
||||||
description = "Unassigned Open and Reopened tickets"
|
description = _('Unassigned Open and Reopened tickets')
|
||||||
link = ''#%s?assigned_to=' % reverse('helpdesk_list')
|
link = ''#%s?assigned_to=' % reverse('helpdesk_list')
|
||||||
|
|
||||||
def items(self, obj):
|
def items(self, obj):
|
||||||
@ -73,15 +74,15 @@ class UnassignedTickets(Feed):
|
|||||||
if item.assigned_to:
|
if item.assigned_to:
|
||||||
return item.assigned_to.username
|
return item.assigned_to.username
|
||||||
else:
|
else:
|
||||||
return "Unassigned"
|
return _('Unassigned')
|
||||||
|
|
||||||
|
|
||||||
class RecentFollowUps(Feed):
|
class RecentFollowUps(Feed):
|
||||||
title_template = 'helpdesk/rss/recent_activity_title.html'
|
title_template = 'helpdesk/rss/recent_activity_title.html'
|
||||||
description_template = 'helpdesk/rss/recent_activity_description.html'
|
description_template = 'helpdesk/rss/recent_activity_description.html'
|
||||||
|
|
||||||
title = "Helpdesk: Recent Followups"
|
title = _('Helpdesk: Recent Followups')
|
||||||
description = "Recent FollowUps, such as e-mail replies, comments, attachments and resolutions"
|
description = _('Recent FollowUps, such as e-mail replies, comments, attachments and resolutions')
|
||||||
link = '/tickets/' # reverse('helpdesk_list')
|
link = '/tickets/' # reverse('helpdesk_list')
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@ -98,10 +99,10 @@ class OpenTicketsByQueue(Feed):
|
|||||||
return Queue.objects.get(slug__exact=bits[0])
|
return Queue.objects.get(slug__exact=bits[0])
|
||||||
|
|
||||||
def title(self, obj):
|
def title(self, obj):
|
||||||
return "Helpdesk: Open Tickets in queue %s" % obj.title
|
return _('Helpdesk: Open Tickets in queue %(queue)s') % {'queue': obj.title}
|
||||||
|
|
||||||
def description(self, obj):
|
def description(self, obj):
|
||||||
return "Open and Reopened Tickets in queue %s" % obj.title
|
return _('Open and Reopened Tickets in queue %(queue)s') % {'queue': obj.title}
|
||||||
|
|
||||||
def link(self, obj):
|
def link(self, obj):
|
||||||
return '%s?queue=%s' % (reverse('helpdesk_list'), obj.id)
|
return '%s?queue=%s' % (reverse('helpdesk_list'), obj.id)
|
||||||
@ -116,7 +117,7 @@ class OpenTicketsByQueue(Feed):
|
|||||||
if item.assigned_to:
|
if item.assigned_to:
|
||||||
return item.assigned_to.username
|
return item.assigned_to.username
|
||||||
else:
|
else:
|
||||||
return "Unassigned"
|
return _('Unassigned')
|
||||||
|
|
||||||
|
|
||||||
feed_setup = {
|
feed_setup = {
|
||||||
|
41
forms.py
41
forms.py
@ -11,30 +11,31 @@ from django import newforms as forms
|
|||||||
from helpdesk.models import Ticket, Queue, FollowUp
|
from helpdesk.models import Ticket, Queue, FollowUp
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
class TicketForm(forms.Form):
|
class TicketForm(forms.Form):
|
||||||
queue = forms.ChoiceField(label=u'Queue', required=True, choices=())
|
queue = forms.ChoiceField(label=_('Queue'), required=True, choices=())
|
||||||
|
|
||||||
title = forms.CharField(max_length=100, required=True,
|
title = forms.CharField(max_length=100, required=True,
|
||||||
widget=forms.TextInput(),
|
widget=forms.TextInput(),
|
||||||
label=u'Summary of the problem')
|
label=_('Summary of the problem'))
|
||||||
|
|
||||||
submitter_email = forms.EmailField(required=False,
|
submitter_email = forms.EmailField(required=False,
|
||||||
label=u'Submitter E-Mail Address',
|
label=_('Submitter E-Mail Address'),
|
||||||
help_text=u'This e-mail address will receive copies of all public updates to this ticket.')
|
help_text=_('This e-mail address will receive copies of all public updates to this ticket.'))
|
||||||
|
|
||||||
body = forms.CharField(widget=forms.Textarea(),
|
body = forms.CharField(widget=forms.Textarea(),
|
||||||
label=u'Description of Issue', required=True)
|
label=_('Description of Issue'), required=True)
|
||||||
|
|
||||||
assigned_to = forms.ChoiceField(choices=(), required=False,
|
assigned_to = forms.ChoiceField(choices=(), required=False,
|
||||||
label=u'Case owner',
|
label=_('Case owner'),
|
||||||
help_text=u'If you select an owner other than yourself, they\'ll be e-mailed details of this ticket immediately.')
|
help_text=_('If you select an owner other than yourself, they\'ll be e-mailed details of this ticket immediately.'))
|
||||||
|
|
||||||
priority = forms.ChoiceField(choices=Ticket.PRIORITY_CHOICES,
|
priority = forms.ChoiceField(choices=Ticket.PRIORITY_CHOICES,
|
||||||
required=False,
|
required=False,
|
||||||
initial='3',
|
initial='3',
|
||||||
label=u'Priority',
|
label=_('Priority'),
|
||||||
help_text=u'Please select a priority carefully. If unsure, leave it as \'3\'.')
|
help_text=_('Please select a priority carefully. If unsure, leave it as \'3\'.'))
|
||||||
|
|
||||||
def save(self, user):
|
def save(self, user):
|
||||||
"""
|
"""
|
||||||
@ -61,14 +62,14 @@ class TicketForm(forms.Form):
|
|||||||
t.save()
|
t.save()
|
||||||
|
|
||||||
f = FollowUp( ticket = t,
|
f = FollowUp( ticket = t,
|
||||||
title = 'Ticket Opened',
|
title = _('Ticket Opened'),
|
||||||
date = datetime.now(),
|
date = datetime.now(),
|
||||||
public = True,
|
public = True,
|
||||||
comment = self.cleaned_data['body'],
|
comment = self.cleaned_data['body'],
|
||||||
user = user,
|
user = user,
|
||||||
)
|
)
|
||||||
if self.cleaned_data['assigned_to']:
|
if self.cleaned_data['assigned_to']:
|
||||||
f.title = 'Ticket Opened & Assigned to %s' % t.get_assigned_to
|
f.title = _('Ticket Opened & Assigned to %(name)s') % {'name': t.get_assigned_to}
|
||||||
|
|
||||||
f.save()
|
f.save()
|
||||||
|
|
||||||
@ -94,25 +95,25 @@ class TicketForm(forms.Form):
|
|||||||
return t
|
return t
|
||||||
|
|
||||||
class PublicTicketForm(forms.Form):
|
class PublicTicketForm(forms.Form):
|
||||||
queue = forms.ChoiceField(label=u'Queue', required=True, choices=())
|
queue = forms.ChoiceField(label=_('Queue'), required=True, choices=())
|
||||||
|
|
||||||
title = forms.CharField(max_length=100, required=True,
|
title = forms.CharField(max_length=100, required=True,
|
||||||
widget=forms.TextInput(),
|
widget=forms.TextInput(),
|
||||||
label=u'Summary of your query')
|
label=_('Summary of your query'))
|
||||||
|
|
||||||
submitter_email = forms.EmailField(required=True,
|
submitter_email = forms.EmailField(required=True,
|
||||||
label=u'Your E-Mail Address',
|
label=_('Your E-Mail Address'),
|
||||||
help_text=u'We will e-mail you when your ticket is updated.')
|
help_text=_('We will e-mail you when your ticket is updated.'))
|
||||||
|
|
||||||
body = forms.CharField(widget=forms.Textarea(),
|
body = forms.CharField(widget=forms.Textarea(),
|
||||||
label=u'Description of your issue', required=True,
|
label=_('Description of your issue'), required=True,
|
||||||
help_text=u'Please be as descriptive as possible, including any details we may need to address your query.')
|
help_text=_('Please be as descriptive as possible, including any details we may need to address your query.'))
|
||||||
|
|
||||||
priority = forms.ChoiceField(choices=Ticket.PRIORITY_CHOICES,
|
priority = forms.ChoiceField(choices=Ticket.PRIORITY_CHOICES,
|
||||||
required=True,
|
required=True,
|
||||||
initial='3',
|
initial='3',
|
||||||
label=u'Urgency',
|
label=_('Urgency'),
|
||||||
help_text=u'Please select a priority carefully.')
|
help_text=_('Please select a priority carefully.'))
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
@ -133,7 +134,7 @@ class PublicTicketForm(forms.Form):
|
|||||||
t.save()
|
t.save()
|
||||||
|
|
||||||
f = FollowUp( ticket = t,
|
f = FollowUp( ticket = t,
|
||||||
title = 'Ticket Opened Via Web',
|
title = _('Ticket Opened Via Web'),
|
||||||
date = datetime.now(),
|
date = datetime.now(),
|
||||||
public = True,
|
public = True,
|
||||||
comment = self.cleaned_data['body'],
|
comment = self.cleaned_data['body'],
|
||||||
|
17
lib.py
17
lib.py
@ -184,3 +184,20 @@ def bar_chart(data):
|
|||||||
chart_url += '&chxl=0:|%s|1:|0|%s' % ('|'.join(column_headings), max) # Axis Label Text
|
chart_url += '&chxl=0:|%s|1:|0|%s' % ('|'.join(column_headings), max) # Axis Label Text
|
||||||
|
|
||||||
return chart_url
|
return chart_url
|
||||||
|
|
||||||
|
def query_to_dict(results, descriptions):
|
||||||
|
""" Replacement method for cursor.dictfetchall() as that method no longer
|
||||||
|
exists in psycopg2, and I'm guessing in other backends too.
|
||||||
|
|
||||||
|
Converts the results of a raw SQL query into a list of dictionaries, suitable
|
||||||
|
for use in templates etc. """
|
||||||
|
output = []
|
||||||
|
for data in results:
|
||||||
|
row = {}
|
||||||
|
i = 0
|
||||||
|
for column in descriptions:
|
||||||
|
row[column[0]] = data[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
output.append(row)
|
||||||
|
return output
|
||||||
|
139
models.py
139
models.py
@ -13,6 +13,7 @@ from django.contrib.auth.models import User
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.dispatch import dispatcher
|
from django.dispatch import dispatcher
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
class Queue(models.Model):
|
class Queue(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -25,28 +26,28 @@ class Queue(models.Model):
|
|||||||
TODO: Add e-mail inboxes (either using piped e-mail or IMAP/POP3) so we
|
TODO: Add e-mail inboxes (either using piped e-mail or IMAP/POP3) so we
|
||||||
can automatically get tickets via e-mail.
|
can automatically get tickets via e-mail.
|
||||||
"""
|
"""
|
||||||
title = models.CharField(max_length=100)
|
title = models.CharField(_('Title'), max_length=100)
|
||||||
slug = models.SlugField(help_text='This slug is used when building ticket ID\'s. Once set, try not to change it or e-mailing may get messy.')
|
slug = models.SlugField(_('Slug'), help_text=_('This slug is used when building ticket ID\'s. Once set, try not to change it or e-mailing may get messy.'))
|
||||||
email_address = models.EmailField(blank=True, null=True, help_text='All outgoing e-mails for this queue will use this e-mail address. If you use IMAP or POP3, this shoul be the e-mail address for that mailbox.')
|
email_address = models.EmailField(_('E-Mail Address'), blank=True, null=True, help_text=_('All outgoing e-mails for this queue will use this e-mail address. If you use IMAP or POP3, this should be the e-mail address for that mailbox.'))
|
||||||
escalate_days = models.IntegerField(blank=True, null=True, help_text='For tickets which are not held, how often do you wish to increase their priority? Set to 0 for no escalation.')
|
escalate_days = models.IntegerField(_('Escalation Days'), blank=True, null=True, help_text=_('For tickets which are not held, how often do you wish to increase their priority? Set to 0 for no escalation.'))
|
||||||
|
|
||||||
def _from_address(self):
|
def _from_address(self):
|
||||||
if not self.email_address:
|
if not self.email_address:
|
||||||
return 'NO QUEUE EMAIL ADDRESS DEFINED <%s>' % settings.DEFAULT_FROM_EMAIL
|
return u'NO QUEUE EMAIL ADDRESS DEFINED <%s>' % settings.DEFAULT_FROM_EMAIL
|
||||||
else:
|
else:
|
||||||
return '%s <%s>' % (self.title, self.email_address)
|
return u'%s <%s>' % (self.title, self.email_address)
|
||||||
from_address = property(_from_address)
|
from_address = property(_from_address)
|
||||||
|
|
||||||
new_ticket_cc = models.EmailField(blank=True, null=True, help_text='If an e-mail address is entered here, then it will receive notification of all new tickets created for this queue')
|
new_ticket_cc = models.EmailField(_('New Ticket CC Address'), blank=True, null=True, help_text=_('If an e-mail address is entered here, then it will receive notification of all new tickets created for this queue'))
|
||||||
updated_ticket_cc = models.EmailField(blank=True, null=True, help_text='If an e-mail address is entered here, then it will receive notification of all activity (new tickets, closed tickets, updates, reassignments, etc) for this queue')
|
updated_ticket_cc = models.EmailField(_('Updated Ticket CC Address'), blank=True, null=True, help_text=_('If an e-mail address is entered here, then it will receive notification of all activity (new tickets, closed tickets, updates, reassignments, etc) for this queue'))
|
||||||
|
|
||||||
email_box_type = models.CharField(max_length=5, choices=(('pop3', 'POP 3'),('imap', 'IMAP')), blank=True, null=True, help_text='E-Mail Server Type - Both POP3 and IMAP are supported. Select your email server type here.')
|
email_box_type = models.CharField(_('E-Mail Box Type'), max_length=5, choices=(('pop3', _('POP 3')),('imap', _('IMAP'))), blank=True, null=True, help_text=_('E-Mail server type for creating tickets automatically from a mailbox - both POP3 and IMAP are supported.'))
|
||||||
email_box_host = models.CharField(max_length=200, blank=True, null=True, help_text='Your e-mail server address - either the domain name or IP address. May be "localhost".')
|
email_box_host = models.CharField(_('E-Mail Hostname'), max_length=200, blank=True, null=True, help_text=_('Your e-mail server address - either the domain name or IP address. May be "localhost".'))
|
||||||
email_box_port = models.IntegerField(blank=True, null=True, help_text='Port number to use for accessing e-mail. Default for POP3 is "110", and for IMAP is "143". This may differ on some servers.')
|
email_box_port = models.IntegerField(_('E-Mail Port'), blank=True, null=True, help_text=_('Port number to use for accessing e-mail. Default for POP3 is "110", and for IMAP is "143". This may differ on some servers. Leave it blank to use the defaults.'))
|
||||||
email_box_user = models.CharField(max_length=200, blank=True, null=True, help_text='Username for accessing this mailbox.')
|
email_box_user = models.CharField(_('E-Mail Username'), max_length=200, blank=True, null=True, help_text=_('Username for accessing this mailbox.'))
|
||||||
email_box_pass = models.CharField(max_length=200, blank=True, null=True, help_text='Password for the above username')
|
email_box_pass = models.CharField(_('E-Mail Password'), max_length=200, blank=True, null=True, help_text=_('Password for the above username'))
|
||||||
email_box_imap_folder = models.CharField(max_length=100, blank=True, null=True, help_text='If using IMAP, what folder do you wish to fetch messages from? This allows you to use one IMAP account for multiple queues, by filtering messages on your IMAP server into separate folders. Default: INBOX.')
|
email_box_imap_folder = models.CharField(_('IMAP Folder'), max_length=100, blank=True, null=True, help_text=_('If using IMAP, what folder do you wish to fetch messages from? This allows you to use one IMAP account for multiple queues, by filtering messages on your IMAP server into separate folders. Default: INBOX.'))
|
||||||
email_box_interval = models.IntegerField(help_text='How often do you wish to check this mailbox? (in Minutes)', blank=True, null=True, default='5')
|
email_box_interval = models.IntegerField(_('E-Mail Check Interval'), help_text=_('How often do you wish to check this mailbox? (in Minutes)'), blank=True, null=True, default='5')
|
||||||
email_box_last_check = models.DateTimeField(blank=True, null=True, editable=False) # Updated by the auto-pop3-and-imap-checker
|
email_box_last_check = models.DateTimeField(blank=True, null=True, editable=False) # Updated by the auto-pop3-and-imap-checker
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
@ -87,34 +88,34 @@ class Ticket(models.Model):
|
|||||||
CLOSED_STATUS = 4
|
CLOSED_STATUS = 4
|
||||||
|
|
||||||
STATUS_CHOICES = (
|
STATUS_CHOICES = (
|
||||||
(OPEN_STATUS, 'Open'),
|
(OPEN_STATUS, _('Open')),
|
||||||
(REOPENED_STATUS, 'Reopened'),
|
(REOPENED_STATUS, _('Reopened')),
|
||||||
(RESOLVED_STATUS, 'Resolved'),
|
(RESOLVED_STATUS, _('Resolved')),
|
||||||
(CLOSED_STATUS, 'Closed'),
|
(CLOSED_STATUS, _('Closed')),
|
||||||
)
|
)
|
||||||
|
|
||||||
PRIORITY_CHOICES = (
|
PRIORITY_CHOICES = (
|
||||||
(1, '1. Critical'),
|
(1, _('1. Critical')),
|
||||||
(2, '2. High'),
|
(2, _('2. High')),
|
||||||
(3, '3. Normal'),
|
(3, _('3. Normal')),
|
||||||
(4, '4. Low'),
|
(4, _('4. Low')),
|
||||||
(5, '5. Very Low'),
|
(5, _('5. Very Low')),
|
||||||
)
|
)
|
||||||
|
|
||||||
title = models.CharField(max_length=200)
|
title = models.CharField(_('Title'), max_length=200)
|
||||||
queue = models.ForeignKey(Queue)
|
queue = models.ForeignKey(Queue)
|
||||||
created = models.DateTimeField(blank=True)
|
created = models.DateTimeField(_('Created'), blank=True)
|
||||||
modified = models.DateTimeField(blank=True)
|
modified = models.DateTimeField(_('Modified'), blank=True)
|
||||||
submitter_email = models.EmailField(blank=True, null=True, help_text='The submitter will receive an email for all public follow-ups left for this task.')
|
submitter_email = models.EmailField(_('Submitter E-Mail'), blank=True, null=True, help_text=_('The submitter will receive an email for all public follow-ups left for this task.'))
|
||||||
assigned_to = models.ForeignKey(User, related_name='assigned_to', blank=True, null=True)
|
assigned_to = models.ForeignKey(User, related_name='assigned_to', blank=True, null=True)
|
||||||
status = models.IntegerField(choices=STATUS_CHOICES, default=OPEN_STATUS)
|
status = models.IntegerField(_('Status'), choices=STATUS_CHOICES, default=OPEN_STATUS)
|
||||||
|
|
||||||
on_hold = models.BooleanField(blank=True, null=True)
|
on_hold = models.BooleanField(_('On Hold'), blank=True, null=True)
|
||||||
|
|
||||||
description = models.TextField(blank=True, null=True)
|
description = models.TextField(_('Description'), blank=True, null=True)
|
||||||
resolution = models.TextField(blank=True, null=True)
|
resolution = models.TextField(_('Resolution'), blank=True, null=True)
|
||||||
|
|
||||||
priority = models.IntegerField(choices=PRIORITY_CHOICES, default=3, blank=3)
|
priority = models.IntegerField(_('Priority'), choices=PRIORITY_CHOICES, default=3, blank=3)
|
||||||
|
|
||||||
last_escalation = models.DateTimeField(blank=True, null=True, editable=False)
|
last_escalation = models.DateTimeField(blank=True, null=True, editable=False)
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ class Ticket(models.Model):
|
|||||||
ticket has no owner, or the users name if it's assigned. If the user
|
ticket has no owner, or the users name if it's assigned. If the user
|
||||||
has a full name configured, we use that, otherwise their username. """
|
has a full name configured, we use that, otherwise their username. """
|
||||||
if not self.assigned_to:
|
if not self.assigned_to:
|
||||||
return 'Unassigned'
|
return _('Unassigned')
|
||||||
else:
|
else:
|
||||||
if self.assigned_to.get_full_name():
|
if self.assigned_to.get_full_name():
|
||||||
return self.assigned_to.get_full_name()
|
return self.assigned_to.get_full_name()
|
||||||
@ -135,36 +136,36 @@ class Ticket(models.Model):
|
|||||||
""" A user-friendly ticket ID, which is a combination of ticket ID
|
""" A user-friendly ticket ID, which is a combination of ticket ID
|
||||||
and queue slug. This is generally used in e-mails. """
|
and queue slug. This is generally used in e-mails. """
|
||||||
|
|
||||||
return "[%s]" % (self.ticket_for_url)
|
return u"[%s]" % (self.ticket_for_url)
|
||||||
ticket = property(_get_ticket)
|
ticket = property(_get_ticket)
|
||||||
|
|
||||||
def _get_ticket_for_url(self):
|
def _get_ticket_for_url(self):
|
||||||
return "%s-%s" % (self.queue.slug, self.id)
|
return u"%s-%s" % (self.queue.slug, self.id)
|
||||||
ticket_for_url = property(_get_ticket_for_url)
|
ticket_for_url = property(_get_ticket_for_url)
|
||||||
|
|
||||||
def _get_priority_img(self):
|
def _get_priority_img(self):
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
return "%s/helpdesk/priorities/priority%s.png" % (settings.MEDIA_URL, self.priority)
|
return u"%s/helpdesk/priorities/priority%s.png" % (settings.MEDIA_URL, self.priority)
|
||||||
get_priority_img = property(_get_priority_img)
|
get_priority_img = property(_get_priority_img)
|
||||||
|
|
||||||
def _get_status(self):
|
def _get_status(self):
|
||||||
held_msg = ''
|
held_msg = ''
|
||||||
if self.on_hold: held_msg = ' - On Hold'
|
if self.on_hold: held_msg = _(' - On Hold')
|
||||||
return '%s%s' % (self.get_status_display(), held_msg)
|
return u'%s%s' % (self.get_status_display(), held_msg)
|
||||||
get_status = property(_get_status)
|
get_status = property(_get_status)
|
||||||
|
|
||||||
def _get_ticket_url(self):
|
def _get_ticket_url(self):
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
site = Site.objects.get_current()
|
site = Site.objects.get_current()
|
||||||
return "http://%s%s?ticket=%s&email=%s" % (site.domain, reverse('helpdesk_public_view'), self.ticket_for_url, self.submitter_email)
|
return u"http://%s%s?ticket=%s&email=%s" % (site.domain, reverse('helpdesk_public_view'), self.ticket_for_url, self.submitter_email)
|
||||||
ticket_url = property(_get_ticket_url)
|
ticket_url = property(_get_ticket_url)
|
||||||
|
|
||||||
def _get_staff_url(self):
|
def _get_staff_url(self):
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
site = Site.objects.get_current()
|
site = Site.objects.get_current()
|
||||||
return "http://%s%s" % (site.domain, reverse('helpdesk_view', args=[self.id]))
|
return u"http://%s%s" % (site.domain, reverse('helpdesk_view', args=[self.id]))
|
||||||
staff_url = property(_get_staff_url)
|
staff_url = property(_get_staff_url)
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
@ -213,13 +214,13 @@ class FollowUp(models.Model):
|
|||||||
although all staff can see them.
|
although all staff can see them.
|
||||||
"""
|
"""
|
||||||
ticket = models.ForeignKey(Ticket)
|
ticket = models.ForeignKey(Ticket)
|
||||||
date = models.DateTimeField(auto_now_add=True)
|
date = models.DateTimeField(_('Date'), auto_now_add=True)
|
||||||
title = models.CharField(max_length=200, blank=True, null=True)
|
title = models.CharField(_('Title'), max_length=200, blank=True, null=True)
|
||||||
comment = models.TextField(blank=True, null=True)
|
comment = models.TextField(_('Comment'), blank=True, null=True)
|
||||||
public = models.BooleanField(blank=True, null=True)
|
public = models.BooleanField(_('Public'), blank=True, null=True)
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
user = models.ForeignKey(User, blank=True, null=True)
|
||||||
|
|
||||||
new_status = models.IntegerField(choices=Ticket.STATUS_CHOICES, blank=True, null=True)
|
new_status = models.IntegerField(_('New Status'), choices=Ticket.STATUS_CHOICES, blank=True, null=True)
|
||||||
|
|
||||||
objects = FollowUpManager()
|
objects = FollowUpManager()
|
||||||
|
|
||||||
@ -233,7 +234,7 @@ class FollowUp(models.Model):
|
|||||||
return u'%s' % self.title
|
return u'%s' % self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return "%s#followup%s" % (self.ticket.get_absolute_url(), self.id)
|
return u"%s#followup%s" % (self.ticket.get_absolute_url(), self.id)
|
||||||
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -247,18 +248,18 @@ class TicketChange(models.Model):
|
|||||||
etc) are tracked here for display purposes.
|
etc) are tracked here for display purposes.
|
||||||
"""
|
"""
|
||||||
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
||||||
field = models.CharField(max_length=100, core=True)
|
field = models.CharField(_('Field'), max_length=100, core=True)
|
||||||
old_value = models.TextField(blank=True, null=True, core=True)
|
old_value = models.TextField(_('Old Value'), blank=True, null=True, core=True)
|
||||||
new_value = models.TextField(blank=True, null=True, core=True)
|
new_value = models.TextField(_('New Value'), blank=True, null=True, core=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
str = u'%s ' % field
|
str = u'%s ' % field
|
||||||
if not new_value:
|
if not new_value:
|
||||||
str += 'removed'
|
str += _('removed')
|
||||||
elif not old_value:
|
elif not old_value:
|
||||||
str += 'set to %s' % new_value
|
str += _('set to %s' % new_value)
|
||||||
else:
|
else:
|
||||||
str += 'changed from "%s" to "%s"' % (old_value, new_value)
|
str += _('changed from "%s" to "%s"' % (old_value, new_value))
|
||||||
return str
|
return str
|
||||||
|
|
||||||
|
|
||||||
@ -290,14 +291,14 @@ class DynamicFileField(models.FileField):
|
|||||||
|
|
||||||
class Attachment(models.Model):
|
class Attachment(models.Model):
|
||||||
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
||||||
file = DynamicFileField(upload_to='helpdesk/attachments', core=True)
|
file = DynamicFileField(_('File'), upload_to='helpdesk/attachments', core=True)
|
||||||
filename = models.CharField(max_length=100)
|
filename = models.CharField(_('Filename'), max_length=100)
|
||||||
mime_type = models.CharField(max_length=30)
|
mime_type = models.CharField(_('MIME Type'), max_length=30)
|
||||||
size = models.IntegerField(help_text='Size of this file in bytes')
|
size = models.IntegerField(_('Size'), help_text=_('Size of this file in bytes'))
|
||||||
|
|
||||||
def get_upload_to(self, field_attname):
|
def get_upload_to(self, field_attname):
|
||||||
""" Get upload_to path specific to this item """
|
""" Get upload_to path specific to this item """
|
||||||
return 'helpdesk/attachments/%s/%s' % (self.followup.ticket.ticket_for_url, self.followup.id)
|
return u'helpdesk/attachments/%s/%s' % (self.followup.ticket.ticket_for_url, self.followup.id)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'%s' % self.filename
|
return u'%s' % self.filename
|
||||||
@ -316,9 +317,9 @@ class PreSetReply(models.Model):
|
|||||||
When replying to a ticket, the user can select any reply set for the current
|
When replying to a ticket, the user can select any reply set for the current
|
||||||
queue, and the body text is fetched via AJAX."""
|
queue, and the body text is fetched via AJAX."""
|
||||||
|
|
||||||
queues = models.ManyToManyField(Queue, blank=True, null=True, help_text='Leave blank to allow this reply to be used for all queues, or select those queues you wish to limit this reply to.')
|
queues = models.ManyToManyField(Queue, blank=True, null=True, help_text=_('Leave blank to allow this reply to be used for all queues, or select those queues you wish to limit this reply to.'))
|
||||||
name = models.CharField(max_length=100, help_text='Only used to assist users with selecting a reply - not shown to the user.')
|
name = models.CharField(_('Name'), max_length=100, help_text=_('Only used to assist users with selecting a reply - not shown to the user.'))
|
||||||
body = models.TextField(help_text='Context available: {{ ticket }} - ticket object (eg {{ ticket.title }}); {{ queue }} - The queue; and {{ user }} - the current user.')
|
body = models.TextField(_('Body'), help_text=_('Context available: {{ ticket }} - ticket object (eg {{ ticket.title }}); {{ queue }} - The queue; and {{ user }} - the current user.'))
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
list_display = ('name',)
|
list_display = ('name',)
|
||||||
@ -330,11 +331,11 @@ class PreSetReply(models.Model):
|
|||||||
return u'%s' % self.name
|
return u'%s' % self.name
|
||||||
|
|
||||||
class EscalationExclusion(models.Model):
|
class EscalationExclusion(models.Model):
|
||||||
queues = models.ManyToManyField(Queue, blank=True, null=True, help_text='Leave blank for this exclusion to be applied to all queues, or select those queues you wish to exclude with this entry.')
|
queues = models.ManyToManyField(Queue, blank=True, null=True, help_text=_('Leave blank for this exclusion to be applied to all queues, or select those queues you wish to exclude with this entry.'))
|
||||||
|
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(_('Name'), max_length=100)
|
||||||
|
|
||||||
date = models.DateField(help_text='Date on which escalation should not happen')
|
date = models.DateField(_('Date'), help_text=_('Date on which escalation should not happen'))
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
pass
|
pass
|
||||||
@ -348,12 +349,12 @@ class EmailTemplate(models.Model):
|
|||||||
them in the database.
|
them in the database.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
template_name = models.CharField(max_length=100, unique=True)
|
template_name = models.CharField(_('Template Name'), max_length=100, unique=True)
|
||||||
|
|
||||||
subject = models.CharField(max_length=100, help_text=u'This will be prefixed with "[ticket.ticket] ticket.title". We recommend something simple such as "(Updated") or "(Closed)" - the same context is available as in plain_text, below.')
|
subject = models.CharField(_('Subject'), max_length=100, help_text=_('This will be prefixed with "[ticket.ticket] ticket.title". We recommend something simple such as "(Updated") or "(Closed)" - the same context is available as in plain_text, below.'))
|
||||||
heading = models.CharField(max_length=100, help_text=u'In HTML e-mails, this will be the heading at the top of the email - the same context is available as in plain_text, below.')
|
heading = models.CharField(_('Heading'), max_length=100, help_text=_('In HTML e-mails, this will be the heading at the top of the email - the same context is available as in plain_text, below.'))
|
||||||
plain_text = models.TextField(help_text=u'The context available to you includes {{ ticket }}, {{ queue }}, and depending on the time of the call: {{ resolution }} or {{ comment }}.')
|
plain_text = models.TextField(_('Plain Text'), help_text=_('The context available to you includes {{ ticket }}, {{ queue }}, and depending on the time of the call: {{ resolution }} or {{ comment }}.'))
|
||||||
html = models.TextField(help_text=u'The same context is available here as in plain_text, above.')
|
html = models.TextField(_('HTML'), help_text=_('The same context is available here as in plain_text, above.'))
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
pass
|
pass
|
||||||
|
0
scripts/__init__.py
Normal file
0
scripts/__init__.py
Normal file
@ -8,10 +8,13 @@ scripts/escalate_tickets.py - Easy way to escalate tickets based on their age,
|
|||||||
designed to be run from Cron or similar.
|
designed to be run from Cron or similar.
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timedelta, date
|
from datetime import datetime, timedelta, date
|
||||||
|
import sys, getopt
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
|
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
|
||||||
from helpdesk.lib import send_templated_mail
|
from helpdesk.lib import send_templated_mail
|
||||||
import sys, getopt
|
|
||||||
|
|
||||||
def escalate_tickets(queues, verbose):
|
def escalate_tickets(queues, verbose):
|
||||||
""" Only include queues with escalation configured """
|
""" Only include queues with escalation configured """
|
||||||
@ -64,13 +67,13 @@ def escalate_tickets(queues, verbose):
|
|||||||
title = 'Ticket Escalated',
|
title = 'Ticket Escalated',
|
||||||
date=datetime.now(),
|
date=datetime.now(),
|
||||||
public=True,
|
public=True,
|
||||||
comment='Ticket escalated after %s days' % q.escalate_days,
|
comment=_('Ticket escalated after %s days' % q.escalate_days),
|
||||||
)
|
)
|
||||||
f.save()
|
f.save()
|
||||||
|
|
||||||
tc = TicketChange(
|
tc = TicketChange(
|
||||||
followup = f,
|
followup = f,
|
||||||
field = 'Priority',
|
field = _('Priority'),
|
||||||
old_value = t.priority + 1,
|
old_value = t.priority + 1,
|
||||||
new_value = t.priority,
|
new_value = t.priority,
|
||||||
)
|
)
|
||||||
|
@ -24,53 +24,57 @@ def process_email():
|
|||||||
|
|
||||||
if (q.email_box_last_check + timedelta(minutes=q.email_box_interval)) > datetime.now():
|
if (q.email_box_last_check + timedelta(minutes=q.email_box_interval)) > datetime.now():
|
||||||
continue
|
continue
|
||||||
print "Processing: %s" % q
|
|
||||||
if q.email_box_type == 'pop3':
|
|
||||||
server = poplib.POP3(q.email_box_host)
|
|
||||||
server.getwelcome()
|
|
||||||
server.user(q.email_box_user)
|
|
||||||
server.pass_(q.email_box_pass)
|
|
||||||
|
|
||||||
messagesInfo = server.list()[1]
|
process_queue(q)
|
||||||
|
|
||||||
for msg in messagesInfo:
|
|
||||||
msgNum = msg.split(" ")[0]
|
|
||||||
msgSize = msg.split(" ")[1]
|
|
||||||
|
|
||||||
full_message = "\n".join(server.retr(msgNum)[1])
|
|
||||||
ticket_from_message(message=full_message, queue=q)
|
|
||||||
|
|
||||||
server.dele(msgNum)
|
|
||||||
server.quit()
|
|
||||||
|
|
||||||
elif q.email_box_type == 'imap':
|
|
||||||
if not q.email_box_port: q.email_box_port = 143
|
|
||||||
|
|
||||||
server = imaplib.IMAP4(q.email_box_host, q.email_box_port)
|
|
||||||
server.login(q.email_box_user, q.email_box_pass)
|
|
||||||
server.select(q.email_box_imap_folder)
|
|
||||||
status, data = server.search(None, 'ALL')
|
|
||||||
for num in data[0].split():
|
|
||||||
status, data = server.fetch(num, '(RFC822)')
|
|
||||||
ticket_from_message(message=data[0][1], queue=q)
|
|
||||||
server.store(num, '+FLAGS', '\\Deleted')
|
|
||||||
server.expunge()
|
|
||||||
server.close()
|
|
||||||
server.logout()
|
|
||||||
|
|
||||||
q.email_box_last_check = datetime.now()
|
q.email_box_last_check = datetime.now()
|
||||||
q.save()
|
q.save()
|
||||||
|
|
||||||
|
def process_queue(q):
|
||||||
|
print "Processing: %s" % q
|
||||||
|
if q.email_box_type == 'pop3':
|
||||||
|
server = poplib.POP3(q.email_box_host)
|
||||||
|
server.getwelcome()
|
||||||
|
server.user(q.email_box_user)
|
||||||
|
server.pass_(q.email_box_pass)
|
||||||
|
|
||||||
|
messagesInfo = server.list()[1]
|
||||||
|
|
||||||
|
for msg in messagesInfo:
|
||||||
|
msgNum = msg.split(" ")[0]
|
||||||
|
msgSize = msg.split(" ")[1]
|
||||||
|
|
||||||
|
full_message = "\n".join(server.retr(msgNum)[1])
|
||||||
|
ticket_from_message(message=full_message, queue=q)
|
||||||
|
|
||||||
|
server.dele(msgNum)
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
elif q.email_box_type == 'imap':
|
||||||
|
if not q.email_box_port: q.email_box_port = 143
|
||||||
|
|
||||||
|
server = imaplib.IMAP4(q.email_box_host, q.email_box_port)
|
||||||
|
server.login(q.email_box_user, q.email_box_pass)
|
||||||
|
server.select(q.email_box_imap_folder)
|
||||||
|
status, data = server.search(None, 'ALL')
|
||||||
|
for num in data[0].split():
|
||||||
|
status, data = server.fetch(num, '(RFC822)')
|
||||||
|
ticket_from_message(message=data[0][1], queue=q)
|
||||||
|
server.store(num, '+FLAGS', '\\Deleted')
|
||||||
|
server.expunge()
|
||||||
|
server.close()
|
||||||
|
server.logout()
|
||||||
|
|
||||||
def ticket_from_message(message, queue):
|
def ticket_from_message(message, queue):
|
||||||
# 'message' must be an RFC822 formatted message.
|
# 'message' must be an RFC822 formatted message.
|
||||||
msg = message
|
msg = message
|
||||||
message = email.message_from_string(msg)
|
message = email.message_from_string(msg)
|
||||||
subject = message.get('subject', 'Created from e-mail')
|
subject = message.get('subject', _('Created from e-mail'))
|
||||||
subject = subject.replace("Re: ", "").replace("Fw: ", "").strip()
|
subject = subject.replace("Re: ", "").replace("Fw: ", "").strip()
|
||||||
|
|
||||||
sender = message.get('from', 'Unknown Sender')
|
sender = message.get('from', _('Unknown Sender'))
|
||||||
|
|
||||||
sender_email = parseaddr(message.get('from', 'Unknown Sender'))[1]
|
sender_email = parseaddr(sender)[1]
|
||||||
if sender_email.startswith('postmaster'):
|
if sender_email.startswith('postmaster'):
|
||||||
sender_email = ''
|
sender_email = ''
|
||||||
|
|
||||||
@ -147,7 +151,7 @@ def ticket_from_message(message, queue):
|
|||||||
send_templated_mail('newticket_cc', context, recipients=queue.updated_ticket_cc, sender=queue.from_address, fail_silently=True)
|
send_templated_mail('newticket_cc', context, recipients=queue.updated_ticket_cc, sender=queue.from_address, fail_silently=True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
update = " (Updated)"
|
update = _(' (Updated)')
|
||||||
|
|
||||||
if t.assigned_to:
|
if t.assigned_to:
|
||||||
send_templated_mail('updated_owner', context, recipients=t.assigned_to.email, sender=queue.from_address, fail_silently=True)
|
send_templated_mail('updated_owner', context, recipients=t.assigned_to.email, sender=queue.from_address, fail_silently=True)
|
||||||
@ -157,7 +161,7 @@ def ticket_from_message(message, queue):
|
|||||||
|
|
||||||
f = FollowUp(
|
f = FollowUp(
|
||||||
ticket = t,
|
ticket = t,
|
||||||
title = 'E-Mail Received from %s' % sender_email,
|
title = _('E-Mail Received from %s' % sender_email),
|
||||||
date = datetime.now(),
|
date = datetime.now(),
|
||||||
public = True,
|
public = True,
|
||||||
comment = body,
|
comment = body,
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
{% load i18n %}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block helpdesk_title %}Helpdesk{% endblock %} Powered by Jutda Helpdesk</title>
|
<title>{% block helpdesk_title %}Helpdesk{% endblock %} :: {% trans "Powered by Jutda Helpdesk" %}</title>
|
||||||
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
||||||
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='My Open Tickets' />
|
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='{% trans "My Open Tickets" %}' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "recent" %}' type='application/rss+xml' title='All Recent Activity' />
|
<link rel='alternate' href='{% url helpdesk_rss "recent" %}' type='application/rss+xml' title='{% trans "All Recent Activity" %}' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='Unassigned Tickets' />
|
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='{% trans "Unassigned Tickets" %}' />
|
||||||
{% block helpdesk_head %}{% endblock %}
|
{% block helpdesk_head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id='container'>
|
<div id='container'>
|
||||||
<div id='header'>
|
<div id='header'>
|
||||||
<h1>Helpdesk</h1>
|
<h1>{% trans "Helpdesk" %}</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href='{% url helpdesk_home %}'>Dashboard</a></li>
|
<li><a href='{% url helpdesk_home %}'>{% trans "Dashboard" %}</a></li>
|
||||||
<li><a href='{% url helpdesk_list %}'>Tickets</a></li>
|
<li><a href='{% url helpdesk_list %}'>{% trans "Tickets" %}</a></li>
|
||||||
<li><a href='{% url helpdesk_submit %}'>New Ticket</a></li>
|
<li><a href='{% url helpdesk_submit %}'>{% trans "New Ticket" %}</a></li>
|
||||||
<li><a href='{% url helpdesk_report_index %}'>Stats</a></li>
|
<li><a href='{% url helpdesk_report_index %}'>{% trans "Stats" %}</a></li>
|
||||||
<li><a href='{% url logout %}'>Logout</a></li>
|
<li><a href='{% url logout %}'>{% trans "Logout" %}</a></li>
|
||||||
{% if not query %}<li><form id='searchform' method='get' action='{% url helpdesk_list %}'><input type='text' name='q' size='10' class='input' value='Search...' id='search_query' onFocus='s = document.getElementById("search_query");if (s.value == "Search...") { s.value = ""; }' /><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /></form></li>{% endif %}
|
{% if not query %}<li><form id='searchform' method='get' action='{% url helpdesk_list %}'><input type='text' name='q' size='10' class='input' value='{% trans "Search..." %}' id='search_query' onFocus='s=document.getElementById("search_query");if (s.value == "{% trans "Search..." %}") { s.value = ""; }' /><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /></form></li>{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id='body'>
|
<div id='body'>
|
||||||
{% block helpdesk_body %}{% endblock %}
|
{% block helpdesk_body %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
<p>Powered by <a href='http://www.jutda.com.au/'>Jutda HelpDesk</a>. <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='RSS Feeds' border='0' />RSS Feeds</a> <a href='{% url helpdesk_api_help %}'>API</a></p>
|
<p>{% trans "Powered by <a href='http://www.jutda.com.au/'>Jutda Helpdesk</a>." %} <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a> <a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "helpdesk/debug.html" %}
|
{% include "helpdesk/debug.html" %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
|
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
{% block helpdesk_title %}{% trans "Create Ticket" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
||||||
@ -12,9 +12,9 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>Submit a Ticket</h2>
|
{% blocktrans %}<h2>Submit a Ticket</h2>
|
||||||
|
|
||||||
<p>Unless otherwise stated, all fields are required. Please provide as descriptive a title and description as possible.</p>
|
<p>Unless otherwise stated, all fields are required. Please provide as descriptive a title and description as possible.</p>{% endblocktrans %}
|
||||||
|
|
||||||
<form method='post' action='./'>
|
<form method='post' action='./'>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<dd>{{ form.title }}</dd>
|
<dd>{{ form.title }}</dd>
|
||||||
{% if form.title.errors %}<dd class='error'>{{ form.title.errors }}</dd>{% endif %}
|
{% if form.title.errors %}<dd class='error'>{{ form.title.errors }}</dd>{% endif %}
|
||||||
|
|
||||||
<dt><label for='id_submitter_email'>{{ form.submitter_email.label }}</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_submitter_email'>{{ form.submitter_email.label }}</label> <span class='form_optional'>{% trans "(Optional)" %}</span></dt>
|
||||||
<dd>{{ form.submitter_email }}</dd>
|
<dd>{{ form.submitter_email }}</dd>
|
||||||
{% if form.submitter_email.errors %}<dd class='error'>{{ form.submitter_email.errors }}</dd>{% endif %}
|
{% if form.submitter_email.errors %}<dd class='error'>{{ form.submitter_email.errors }}</dd>{% endif %}
|
||||||
<dd class='form_help_text'>{{ form.submitter_email.help_text }}</dd>
|
<dd class='form_help_text'>{{ form.submitter_email.help_text }}</dd>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<dd>{{ form.body }}</dd>
|
<dd>{{ form.body }}</dd>
|
||||||
{% if form.body.errors %}<dd class='error'>{{ form.body.errors }}</dd>{% endif %}
|
{% if form.body.errors %}<dd class='error'>{{ form.body.errors }}</dd>{% endif %}
|
||||||
|
|
||||||
<dt><label for='id_assigned_to'>{{ form.assigned_to.label }}</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_assigned_to'>{{ form.assigned_to.label }}</label> <span class='form_optional'>{% trans "(Optional)" %}</span></dt>
|
||||||
<dd>{{ form.assigned_to }}</dd>
|
<dd>{{ form.assigned_to }}</dd>
|
||||||
{% if form.assigned_to.errors %}<dd class='error'>{{ form.assigned_to.errors }}</dd>{% endif %}
|
{% if form.assigned_to.errors %}<dd class='error'>{{ form.assigned_to.errors }}</dd>{% endif %}
|
||||||
<dd class='form_help_text'>{{ form.assigned_to.help_text }}</dd>
|
<dd class='form_help_text'>{{ form.assigned_to.help_text }}</dd>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<div class='buttons'>
|
<div class='buttons'>
|
||||||
<input type='submit' value='Submit Ticket' />
|
<input type='submit' value='{% trans "Submit Ticket" %}' />
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk Dashboard{% endblock %}
|
{% block helpdesk_title %}{% trans "Helpdesk Dashboard" %}{% endblock %}
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/hover.js'></script>
|
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/hover.js'></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<table width='30%'>
|
<table width='30%'>
|
||||||
<tr class='row_tablehead'><td colspan='4'>Helpdesk Summary</td></tr>
|
<tr class='row_tablehead'><td colspan='4'>{% trans "Helpdesk Summary" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>Queue</th><th>Open</th><th>Resolved</th></tr>
|
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th></tr>
|
||||||
{% for queue in dash_tickets %}
|
{% for queue in dash_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover '>
|
<tr class='row_{% cycle odd,even %} row_hover '>
|
||||||
<th><a href='{% url helpdesk_list %}?queue={{ queue.queue }}'>{{ queue.name }}</a></th>
|
<th><a href='{% url helpdesk_list %}?queue={{ queue.queue }}'>{{ queue.name }}</a></th>
|
||||||
@ -16,13 +16,14 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='6'>Your Tickets</td></tr>
|
<tr class='row_tablehead'><td colspan='6'>{% trans "Your Tickets" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>#</th><th>Pr</th><th>Title</th><th>Queue</th><th>Status</th><th>Last Update</th></tr>
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||||
{% for ticket in user_tickets %}
|
{% for ticket in user_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||||
<td><img src='{{ ticket.get_priority_img }}' alt='Priority {{ ticket.priority }}' title='Priority {{ ticket.priority }}' height='16' width='16' /></td>
|
<td><img src='{{ ticket.get_priority_img }}' alt='{% blocktrans with ticket.priority as priority %}Priority {{ priority }}{% endblocktrans %}' title='{% blocktrans with ticket.priority as priority %}Priority {{ priority }}{% endblocktrans %}' height='16' width='16' /></td>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
<td>{{ ticket.queue }}</td>
|
<td>{{ ticket.queue }}</td>
|
||||||
<td>{{ ticket.get_status }}</td>
|
<td>{{ ticket.get_status }}</td>
|
||||||
@ -32,16 +33,16 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='6'>Unassigned Tickets</td></tr>
|
<tr class='row_tablehead'><td colspan='6'>{% trans "Unassigned Tickets" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>#</th><th>Pr</th><th>Title</th><th>Queue</th><th>Created</th><th> </th></tr>
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Created" %}</th><th> </th></tr>
|
||||||
{% for ticket in unassigned_tickets %}
|
{% for ticket in unassigned_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||||
<td><img src='{{ ticket.get_priority_img }}' alt='Priority {{ ticket.priority }}' title='Priority {{ ticket.priority }}' height='16' width='16' /></td>
|
<td><img src='{{ ticket.get_priority_img }}' alt='{% blocktrans with ticket.priority as priority %}Priority {{ priority }}{% endblocktrans %}' title='{% blocktrans with ticket.priority as priority %}Priority {{ priority }}{% endblocktrans %}' height='16' width='16' /></td>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
<td>{{ ticket.queue }}</td>
|
<td>{{ ticket.queue }}</td>
|
||||||
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|timesince }} ago</span></td>
|
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|timesince }} ago</span></td>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}?take'><img src='{{ MEDIA_URL }}/helpdesk/buttons/take.png' width='60' height='15' alt='Take' title='Assign this ticket to yourself' /></a></th>
|
<th><a href='{{ ticket.get_absolute_url }}?take'><img src='{{ MEDIA_URL }}/helpdesk/buttons/take.png' width='60' height='15' alt='{% trans "Take" %}' title='{% trans "Assign this ticket to yourself" %}' /></a></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
|
|
||||||
{% block helpdesk_title %}Delete Ticket{% endblock %}
|
{% block helpdesk_title %}{% trans "Delete Ticket" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}{% blocktrans %}
|
||||||
<h2>Delete Ticket</h2>
|
<h2>Delete Ticket</h2>
|
||||||
|
|
||||||
<p>Are you sure you want to delete this ticket (<em>{{ ticket.title }}</em>)? All traces of the ticket, including followups, attachments, and updates will be irreversably removed.</p>
|
<p>Are you sure you want to delete this ticket (<em>{{ ticket.title }}</em>)? All traces of the ticket, including followups, attachments, and updates will be irreversably removed.</p>
|
||||||
@ -10,4 +10,4 @@
|
|||||||
<p><a href='../'>No, Don't Delete It</a></p>
|
<p><a href='../'>No, Don't Delete It</a></p>
|
||||||
|
|
||||||
<form method='post' action='./'><input type='submit' value='Yes - Delete It' /></form>
|
<form method='post' action='./'><input type='submit' value='Yes - Delete It' /></form>
|
||||||
{% endblock %}
|
{% endblocktrans %}{% endblock %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
{% load i18n %}<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{% block helpdesk_title %}Helpdesk{% endblock %}</title>
|
<title>{% block helpdesk_title %}{% trans "Helpdesk" %}{% endblock %}</title>
|
||||||
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
||||||
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
||||||
{% block helpdesk_head %}{% endblock %}
|
{% block helpdesk_head %}{% endblock %}
|
||||||
@ -8,17 +8,17 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id='container'>
|
<div id='container'>
|
||||||
<div id='header'>
|
<div id='header'>
|
||||||
<h1>Helpdesk</h1>
|
<h1>{% trans "Helpdesk" %}</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href='{% url helpdesk_home %}'>Submit A Ticket</a></li>
|
<li><a href='{% url helpdesk_home %}'>{% trans "Submit A Ticket" %}</a></li>
|
||||||
<li><a href='{% url login %}'>Log In</a></li>
|
<li><a href='{% url login %}'>{% trans "Log In" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id='body'>
|
<div id='body'>
|
||||||
{% block helpdesk_body %}{% endblock %}
|
{% block helpdesk_body %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
<p>Powered by <a href='http://www.jutda.com.au/'>Jutda HelpDesk</a></p>
|
<p>{% trans "Powered by <a href='http://www.jutda.com.au/'>Jutda HelpDesk</a>." %}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>{% include "helpdesk/debug.html" %}
|
</div>{% include "helpdesk/debug.html" %}
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
|
||||||
|
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
||||||
@ -11,25 +10,25 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>View a Ticket</h2>
|
<h2>{% trans "View a Ticket" %}</h2>
|
||||||
|
|
||||||
<form method='get' action='{% url helpdesk_public_view %}'>
|
<form method='get' action='{% url helpdesk_public_view %}'>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><label for='id_ticket'>Ticket</label></dt>
|
<dt><label for='id_ticket'>{% trans "Ticket" %}</label></dt>
|
||||||
<dd><input type='text' name='ticket' /></dd>
|
<dd><input type='text' name='ticket' /></dd>
|
||||||
|
|
||||||
<dt><label for='id_email'>Your E-mail Address</label></dt>
|
<dt><label for='id_email'>{% trans "Your E-mail Address" %}</label></dt>
|
||||||
<dd><input type='text' name='email' /></dd>
|
<dd><input type='text' name='email' /></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<input type='submit' value='View Ticket' />
|
<input type='submit' value='{% trans "View Ticket" %}' />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2 name='submit'>Submit a Ticket</h2>
|
<h2 name='submit'>{% trans "Submit a Ticket" %}</h2>
|
||||||
|
|
||||||
<p>All fields are required. Please provide as descriptive a title and description as possible.</p>
|
<p>{% trans "All fields are required. Please provide as descriptive a title and description as possible." %}</p>
|
||||||
|
|
||||||
<form method='post' action='./#submit'>
|
<form method='post' action='./#submit'>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
@ -63,7 +62,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<div class='buttons'>
|
<div class='buttons'>
|
||||||
<input type='submit' value='Submit Ticket' />
|
<input type='submit' value='{% trans "Submit Ticket" %}' />
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>View a Ticket</h2>
|
<h2>{% trans "View a Ticket" %}</h2>
|
||||||
|
|
||||||
<form method='get' action='{% url helpdesk_public_view %}'>
|
<form method='get' action='{% url helpdesk_public_view %}'>
|
||||||
|
|
||||||
{% if error_message %}<p><strong>Error:</strong> {{ error_message }}</p>{% endif %}
|
{% if error_message %}<p><strong>{% trans "Error:" %}</strong> {{ error_message }}</p>{% endif %}
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><label for='id_ticket'>Ticket</label></dt>
|
<dt><label for='id_ticket'>{% trans "Ticket" %}</label></dt>
|
||||||
<dd><input type='text' name='ticket' value='{{ ticket }}' /></dd>
|
<dd><input type='text' name='ticket' /></dd>
|
||||||
|
|
||||||
<dt><label for='id_email'>Your E-mail Address</label></dt>
|
<dt><label for='id_email'>{% trans "Your E-mail Address" %}</label></dt>
|
||||||
<dd><input type='text' name='email' value='{{ email }}' /></dd>
|
<dd><input type='text' name='email' /></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<input type='submit' value='View Ticket' />
|
<input type='submit' value='{% "View Ticket" %}' />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
{% block helpdesk_title %}{% trans "View a Ticket" %}{% endblock %}
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -13,32 +13,32 @@
|
|||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]</td></tr>
|
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]</td></tr>
|
||||||
<tr class='row_columnheads'><th colspan='2'>Queue: {{ ticket.queue }}</th></tr>
|
<tr class='row_columnheads'><th colspan='2'>{% blocktrans %}Queue: {{ ticket.queue }}{% endblocktrans %}</th></tr>
|
||||||
|
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<th>Submitted On</th>
|
<th>{% trans "Submitted On" %}</th>
|
||||||
<td>{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)</td>
|
<td>{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<th>Submitter E-Mail</th>
|
<th>{% trans "Submitter E-Mail" %}</th>
|
||||||
<td>{{ ticket.submitter_email }}</td>
|
<td>{{ ticket.submitter_email }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<th>Priority</th>
|
<th>{% trans "Priority" %}</th>
|
||||||
<td>{{ ticket.get_priority_display }}</td>
|
<td>{{ ticket.get_priority_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<th colspan='2'>Description</th>
|
<th colspan='2'>{% trans "Description" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<td colspan='2'>{{ ticket.description }}</td>
|
<td colspan='2'>{{ ticket.description }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% if ticket.resolution %}<tr class='row_even'>
|
{% if ticket.resolution %}<tr class='row_even'>
|
||||||
<th colspan='2'>Resolution{% ifequal ticket.get_status_display "Resolved" %} <a href='?close'><img src='{{ MEDIA_URL }}/helpdesk/buttons/accept.png' alt='Accept' title='Accept and Close' width='60' height='15' /></a>{% endifequal %}</th>
|
<th colspan='2'>{% trans "Resolution" %}{% ifequal ticket.get_status_display "Resolved" %} <a href='?close'><img src='{{ MEDIA_URL }}/helpdesk/buttons/accept.png' alt='{% trans "Accept" %}' title='{% trans "Accept and Close" %}' width='60' height='15' /></a>{% endifequal %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<td colspan='2'>{{ ticket.resolution }}</td>
|
<td colspan='2'>{{ ticket.resolution }}</td>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if ticket.followup_set.public_followups %}
|
{% if ticket.followup_set.public_followups %}
|
||||||
<h3>Follow-Ups</h3>
|
<h3>{% trans "Follow-Ups" %}</h3>
|
||||||
{% load ticket_to_link %}
|
{% load ticket_to_link %}
|
||||||
{% for followup in ticket.followup_set.public_followups %}
|
{% for followup in ticket.followup_set.public_followups %}
|
||||||
<div class='followup'>
|
<div class='followup'>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
{{ followup.comment|num_to_link }}
|
{{ followup.comment|num_to_link }}
|
||||||
{% if followup.ticketchange_set.all %}<div class='changes'><ul>
|
{% if followup.ticketchange_set.all %}<div class='changes'><ul>
|
||||||
{% for change in followup.ticketchange_set.all %}
|
{% for change in followup.ticketchange_set.all %}
|
||||||
<li>Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.</li>
|
<li>{% blocktrans %}Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.{% endblocktrans %}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div></ul>{% endif %}
|
</div></ul>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
|
|
||||||
{% block helpdesk_title %}Reports & Statistics{% endblock %}
|
{% block helpdesk_title %}{% trans "Reports & Statistics" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}{% blocktrans %}
|
||||||
<h2>Reports & Statistics</h2>
|
<h2>Reports & Statistics</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@ -24,4 +24,4 @@
|
|||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblocktrans %}{% endblock %}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
|
|
||||||
{% block helpdesk_title %}Reports & Statistics{% endblock %}
|
{% block helpdesk_title %}{% trans "Reports & Statistics" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>Reports & Statistics</h2>
|
<h2>{% trans "Reports & Statistics" %}</h2>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>{% for h in headings %}<th>{{ h }}</th>{% endfor %}</tr>
|
<tr>{% for h in headings %}<th>{{ h }}</th>{% endfor %}</tr>
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}RSS Feeds{% endblock %}
|
{% block helpdesk_title %}{% trans "RSS Feeds" %}{% endblock %}
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>RSS Feeds</h2>
|
<h2>{% trans "RSS Feeds" %}</h2>
|
||||||
|
|
||||||
<p>The following RSS feeds are available for you to monitor using your preferred RSS software. With the exception of the 'Latest Activity' feed, all feeds provide information only on Open and Reopened cases. This ensures your RSS reader isn't full of information about closed or historical tasks.</p>
|
<p>{% trans "The following RSS feeds are available for you to monitor using your preferred RSS software. With the exception of the 'Latest Activity' feed, all feeds provide information only on Open and Reopened cases. This ensures your RSS reader isn't full of information about closed or historical tasks." %}</p>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt><a href='{% url helpdesk_rss "user" %}{{ user.username }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='My Open Tickets' border='0' />My Open Tickets</a></dt>
|
<dt><a href='{% url helpdesk_rss "user" %}{{ user.username }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "My Open Tickets" %}' border='0' />{% trans "My Open Tickets" %}</a></dt>
|
||||||
<dd>A summary of your open tickets - useful for getting alerted to new tickets opened for you</dd>
|
<dd>{% trans "A summary of your open tickets - useful for getting alerted to new tickets opened for you" %}</dd>
|
||||||
|
|
||||||
<dt><a href='{% url helpdesk_rss "recent_activity" %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='Latest Activity' border='0' />Latest Activity</a></dt>
|
<dt><a href='{% url helpdesk_rss "recent_activity" %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "Latest Activity" %}' border='0' />{% trans "Latest Activity" %}</a></dt>
|
||||||
<dd>A summary of all helpdesk activity - including comments, emails, attachments, and more</dd>
|
<dd>{% trans "A summary of all helpdesk activity - including comments, emails, attachments, and more" %}</dd>
|
||||||
|
|
||||||
<dt><a href='{% url helpdesk_rss "unassigned" %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='Unassigned Tickets' border='0' />Unassigned Tickets</a></dt>
|
<dt><a href='{% url helpdesk_rss "unassigned" %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "Unassigned Tickets" %}' border='0' />{% trans "Unassigned Tickets" %}</a></dt>
|
||||||
<dd>All unassigned tickets - useful for being alerted to new tickets opened by the public via the web or via e-mail</dd>
|
<dd>{% trans "All unassigned tickets - useful for being alerted to new tickets opened by the public via the web or via e-mail" %}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p>These RSS feeds allow you to view a summary of either your own tickets, or all tickets, for each of the queues in your helpdesk. For example, if you manage the staff who utilise a particular queue, this may be used to view new tickets coming into that queue.</p>
|
<p>{% trans "These RSS feeds allow you to view a summary of either your own tickets, or all tickets, for each of the queues in your helpdesk. For example, if you manage the staff who utilise a particular queue, this may be used to view new tickets coming into that queue." %}</p>
|
||||||
|
|
||||||
<table width='50%'>
|
<table width='50%'>
|
||||||
<tr class='row_tablehead'><td colspan='4'>Per-Queue Feeds</td></tr>
|
<tr class='row_tablehead'><td colspan='4'>{% trans "Per-Queue Feeds" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>Queue</th><th align='center'>All Open Tickets</th><th align='center'>My Open Tickets</th></tr>
|
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th align='center'>{% trans "All Open Tickets" %}</th><th align='center'>{% trans "My Open Tickets" %}</th></tr>
|
||||||
{% for queue in queues %}
|
{% for queue in queues %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ queue.title }}</td>
|
<td>{{ queue.title }}</td>
|
||||||
<td align='center'><a href='{% url helpdesk_rss "queue" %}{{ queue.slug }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='Open Tickets' border='0' /></a></td>
|
<td align='center'><a href='{% url helpdesk_rss "queue" %}{{ queue.slug }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "Open Tickets" %}' border='0' /></a></td>
|
||||||
<td align='center'><a href='{% url helpdesk_rss "user" %}{{ user.username }}/{{ queue.slug }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='My Open Tickets' border='0' /></a></td>
|
<td align='center'><a href='{% url helpdesk_rss "user" %}{{ user.username }}/{{ queue.slug }}/'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "My Open Tickets" %}' border='0' /></a></td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
{% block helpdesk_title %}{% trans "View Ticket Details" %}{% endblock %}
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -33,7 +33,7 @@
|
|||||||
distribution, this will have to do. */
|
distribution, this will have to do. */
|
||||||
$(".AddAnotherFile>a").click(function() {
|
$(".AddAnotherFile>a").click(function() {
|
||||||
$(this).parent().hide();
|
$(this).parent().hide();
|
||||||
$("#FileUpload>dl").append("<dt><label>Attach another File</label></dt><dd><input type='file' name='attachment' id='file' /> <span class='AddAnotherFile'>(<a href='#'>Add Another File</a>)</span></dd>");
|
$("#FileUpload>dl").append("<dt><label>{% trans "Attach another File" %}</label></dt><dd><input type='file' name='attachment' id='file' /> <span class='AddAnotherFile'>(<a href='#'>{% trans "Add Another File" %}</a>)</span></dd>");
|
||||||
processAddFileClick();
|
processAddFileClick();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -45,38 +45,38 @@
|
|||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]</td><td align='right'><a href='#edit'><img src='{{ MEDIA_URL }}/helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a><a href='{% url helpdesk_delete ticket.id %}'><img src='{{ MEDIA_URL }}/helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>{% if ticket.on_hold %}<a href='unhold/'>Unhold</a>{% else %}<a href='hold/'>Hold</a>{% endif %}</td></tr>
|
<tr class='row_tablehead'><td>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]</td><td align='right'><a href='#edit'><img src='{{ MEDIA_URL }}/helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a><a href='{% url helpdesk_delete ticket.id %}'><img src='{{ MEDIA_URL }}/helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>{% if ticket.on_hold %}<a href='unhold/'>{% trans "Unhold" %}</a>{% else %}<a href='hold/'>{% trans "Hold" %}</a>{% endif %}</td></tr>
|
||||||
<tr class='row_columnheads'><th colspan='2'>Queue: {{ ticket.queue }}</th></tr>
|
<tr class='row_columnheads'><th colspan='2'>{% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}</th></tr>
|
||||||
|
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<th>Submitted On</th>
|
<th>{% trans "Submitted On" %}</th>
|
||||||
<td>{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)</td>
|
<td>{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<th>Assigned To</th>
|
<th>{% trans "Assigned To" %}</th>
|
||||||
<td>{{ ticket.get_assigned_to }}{% ifequal ticket.get_assigned_to 'Unassigned' %} <strong><a href='?take'><img src='{{ MEDIA_URL }}/helpdesk/buttons/take.png' width='60' height='15' alt='Take' title='Assign this ticket to yourself' /></a></strong>{% endifequal %}</td>
|
<td>{{ ticket.get_assigned_to }}{% ifequal ticket.get_assigned_to _('Unassigned') %} <strong><a href='?take'><img src='{{ MEDIA_URL }}/helpdesk/buttons/take.png' width='60' height='15' alt='{% trans "Take" %}' title='{% trans "Assign this ticket to yourself" %}' /></a></strong>{% endifequal %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<th>Submitter E-Mail</th>
|
<th>{% trans "Submitter E-Mail" %}</th>
|
||||||
<td>{{ ticket.submitter_email }}</td>
|
<td>{{ ticket.submitter_email }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<th>Priority</th>
|
<th>{% trans "Priority" %}</th>
|
||||||
<td>{{ ticket.get_priority_display }}</td>
|
<td>{{ ticket.get_priority_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class='row_odd'>
|
<tr class='row_odd'>
|
||||||
<th colspan='2'>Description</th>
|
<th colspan='2'>{% trans "Description" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<td colspan='2'>{{ ticket.description|safe }}</td>
|
<td colspan='2'>{{ ticket.description|safe }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% if ticket.resolution %}<tr class='row_odd'>
|
{% if ticket.resolution %}<tr class='row_odd'>
|
||||||
<th colspan='2'>Resolution{% ifequal ticket.get_status_display "Resolved" %} <a href='?close'><img src='{{ MEDIA_URL }}/helpdesk/buttons/accept.png' alt='Accept' title='Accept and Close' width='60' height='15' /></a>{% endifequal %}</th>
|
<th colspan='2'>{% trans "Resolution" %}{% ifequal ticket.get_status_display "Resolved" %} <a href='?close'><img src='{{ MEDIA_URL }}/helpdesk/buttons/accept.png' alt='{% trans "Accept" %}' title='{% trans "Accept and Close" %}' width='60' height='15' /></a>{% endifequal %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class='row_even'>
|
<tr class='row_even'>
|
||||||
<td colspan='2'>{{ ticket.resolution|safe }}</td>
|
<td colspan='2'>{{ ticket.resolution|safe }}</td>
|
||||||
@ -85,15 +85,15 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if ticket.followup_set.all %}
|
{% if ticket.followup_set.all %}
|
||||||
<h3>Follow-Ups</h3>
|
<h3>{% trans "Follow-Ups" %}</h3>
|
||||||
{% load ticket_to_link %}
|
{% load ticket_to_link %}
|
||||||
{% for followup in ticket.followup_set.all %}
|
{% for followup in ticket.followup_set.all %}
|
||||||
<div class='followup'>
|
<div class='followup'>
|
||||||
<div class='title'>{{ followup.title }} <span class='byline'>{% if followup.user %}by {{ followup.user }}{% endif %} <span title='{{ followup.date|date:"r" }}'>{{ followup.date|timesince }} ago</span>{% if not followup.public %} <span class='private'>(Private)</span>{% endif %}</span></div>
|
<div class='title'>{{ followup.title }} <span class='byline'>{% if followup.user %}by {{ followup.user }}{% endif %} <span title='{{ followup.date|date:"r" }}'>{{ followup.date|timesince }} ago</span>{% if not followup.public %} <span class='private'>({% trans "Private" %})</span>{% endif %}</span></div>
|
||||||
{% if followup.comment %}{{ followup.comment|num_to_link|safe }}{% endif %}
|
{% if followup.comment %}{{ followup.comment|num_to_link|safe }}{% endif %}
|
||||||
{% for change in followup.ticketchange_set.all %}
|
{% for change in followup.ticketchange_set.all %}
|
||||||
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
||||||
<li>Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.</li>
|
<li>{% blocktrans %}Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.{% endblocktrans %}</li>
|
||||||
{% if forloop.last %}</div></ul>{% endif %}
|
{% if forloop.last %}</div></ul>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
||||||
@ -104,80 +104,80 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h3>Respond to this ticket</h3>
|
<h3>{% trans "Respond to this ticket" %}</h3>
|
||||||
|
|
||||||
<form method='post' action='update/' enctype='multipart/form-data'>
|
<form method='post' action='update/' enctype='multipart/form-data'>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><label for='id_preset'>Use a Pre-set Reply</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_preset'>{% trans "Use a Pre-set Reply" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||||
<dd><select name='preset' id='id_preset'><option value=''>------</option>{% for preset in preset_replies %}<option value='{{ preset.id }}'>{{ preset.name }}</option>{% endfor %}</select></dd>
|
<dd><select name='preset' id='id_preset'><option value=''>------</option>{% for preset in preset_replies %}<option value='{{ preset.id }}'>{{ preset.name }}</option>{% endfor %}</select></dd>
|
||||||
<dd class='form_help_text'>Selecting a pre-set reply will over-write your comment below. You can then modify the pre-set reply to your liking before saving this update.</dd>
|
<dd class='form_help_text'>{% trans "Selecting a pre-set reply will over-write your comment below. You can then modify the pre-set reply to your liking before saving this update." %}</dd>
|
||||||
|
|
||||||
<dt><label for='commentBox'>Comment / Resolution</label></dt>
|
<dt><label for='commentBox'>{% trans "Comment / Resolution" %}</label></dt>
|
||||||
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
||||||
<dd class='form_help_text'>You can use the ticket and queue template variables in your message.</dd>
|
<dd class='form_help_text'>{% trans "You can use the ticket and queue template variables in your message." %}</dd>
|
||||||
|
|
||||||
<dt><label>New Status</label></dt>
|
<dt><label>{% trans "New Status" %}</label></dt>
|
||||||
{% ifequal ticket.status 1 %}
|
{% ifequal ticket.status 1 %}
|
||||||
<dd><input type='radio' name='new_status' value='1' id='st_open' checked='checked'><label for='st_open' class='active'>Open</label> »
|
<dd><input type='radio' name='new_status' value='1' id='st_open' checked='checked'><label for='st_open' class='active'>{% trans "Open" %}</label> »
|
||||||
<input type='radio' name='new_status' value='3' id='st_resolved'><label for='st_resolved'>Resolved</label> »
|
<input type='radio' name='new_status' value='3' id='st_resolved'><label for='st_resolved'>{% trans "Resolved" %}</label> »
|
||||||
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>Closed</label></dd>
|
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>{% trans "Closed" %}</label></dd>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal ticket.status 2 %}
|
{% ifequal ticket.status 2 %}
|
||||||
<dd><input type='radio' name='new_status' value='2' id='st_reopened' checked='checked'><label for='st_reopened' class='active'>Reopened</label> »
|
<dd><input type='radio' name='new_status' value='2' id='st_reopened' checked='checked'><label for='st_reopened' class='active'>{% trans "Reopened" %}</label> »
|
||||||
<input type='radio' name='new_status' value='3' id='st_resolved'><label for='st_resolved'>Resolved</label> »
|
<input type='radio' name='new_status' value='3' id='st_resolved'><label for='st_resolved'>{% trans "Resolved" %}</label> »
|
||||||
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>Closed</label> </dd>
|
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>{% trans "Closed" %}</label> </dd>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal ticket.status 3 %}
|
{% ifequal ticket.status 3 %}
|
||||||
<dd><input type='radio' name='new_status' value='2' id='st_reopened'><label for='st_reopened'>Reopened</label> «
|
<dd><input type='radio' name='new_status' value='2' id='st_reopened'><label for='st_reopened'>{% trans "Reopened" %}</label> «
|
||||||
<input type='radio' name='new_status' value='3' id='st_resolved' checked='checked'><label for='st_resolved' class='active'>Resolved</label> »
|
<input type='radio' name='new_status' value='3' id='st_resolved' checked='checked'><label for='st_resolved' class='active'>{% trans "Resolved" %}</label> »
|
||||||
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>Closed</label></dd>
|
<input type='radio' name='new_status' value='4' id='st_closed'><label for='st_closed'>{% trans "Closed" %}</label></dd>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal ticket.status 4 %}
|
{% ifequal ticket.status 4 %}
|
||||||
<dd><input type='radio' name='new_status' value='2' id='st_reopened'><label for='st_reopened'>Reopened</label> «
|
<dd><input type='radio' name='new_status' value='2' id='st_reopened'><label for='st_reopened'>{% trans "Reopened" %}</label> «
|
||||||
<input type='radio' name='new_status' value='4' id='st_closed' checked='checked'><label for='st_closed'>Closed</label></dd>
|
<input type='radio' name='new_status' value='4' id='st_closed' checked='checked'><label for='st_closed'>{% trans "Closed" %}</label></dd>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
|
||||||
<dt><label for='id_public'>Is this update public?</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_public'>{% trans "Is this update public?" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||||
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dD>
|
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dD>
|
||||||
<dd class='form_help_text'>If this is public, the submitter will be e-mailed your comment or resolution.</dd>
|
<dd class='form_help_text'>{% trans "If this is public, the submitter will be e-mailed your comment or resolution." %}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p id='ShowFurtherOptPara'><a href='#' id='ShowFurtherEditOptions'>Change Further Details »</a></p>
|
<p id='ShowFurtherOptPara'><a href='#' id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</a></p>
|
||||||
|
|
||||||
<div id='FurtherEditOptions' style='display: none;'>
|
<div id='FurtherEditOptions' style='display: none;'>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
|
||||||
<dt><label for='id_title'>Title</label></dt>
|
<dt><label for='id_title'>{% trans "Title" %}</label></dt>
|
||||||
<dd><input type='text' name='title' value='{{ ticket.title|escape }}' /></dd>
|
<dd><input type='text' name='title' value='{{ ticket.title|escape }}' /></dd>
|
||||||
|
|
||||||
<dt><label for='id_owner'>Owner</label></dt>
|
<dt><label for='id_owner'>{% trans "Owner" %}</label></dt>
|
||||||
<dd><select id='id_owner' name='owner'><option value='0'>Unassign</option>{% for u in active_users %}<option value='{{ u.id }}' {% ifequal u.id ticket.assigned_to.id %}selected{% endifequal %}>{{ u }}</option>{% endfor %}</select></dd>
|
<dd><select id='id_owner' name='owner'><option value='0'>{% trans "Unassign" %}</option>{% for u in active_users %}<option value='{{ u.id }}' {% ifequal u.id ticket.assigned_to.id %}selected{% endifequal %}>{{ u }}</option>{% endfor %}</select></dd>
|
||||||
|
|
||||||
<dt><label for='id_priority'>Priority</label></dt>
|
<dt><label for='id_priority'>{% trans "Priority" %}</label></dt>
|
||||||
<dd><select id='id_priority' name='priority'>{% for p in priorities %}<option value='{{ p.0 }}'{% ifequal p.0 ticket.priority %} selected='selected'{% endifequal %}>{{ p.1 }}</option>{% endfor %}</select></dd>
|
<dd><select id='id_priority' name='priority'>{% for p in priorities %}<option value='{{ p.0 }}'{% ifequal p.0 ticket.priority %} selected='selected'{% endifequal %}>{{ p.1 }}</option>{% endfor %}</select></dd>
|
||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p id='ShowFileUploadPara'><a href='#' id='ShowFileUpload'>Attach File(s) »</a></p>
|
<p id='ShowFileUploadPara'><a href='#' id='ShowFileUpload'>{% trans "Attach File(s) »" %}</a></p>
|
||||||
|
|
||||||
<div id='FileUpload' style='display: none;'>
|
<div id='FileUpload' style='display: none;'>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
|
||||||
<dt><label for='id_file'>Attach a File</label></dt>
|
<dt><label for='id_file'>{% trans "Attach a File" %}</label></dt>
|
||||||
<dd><input type='file' name='attachment' id='file' /> <span class='AddAnotherFile'>(<a href='#'>Add Another File</a>)</span></dd>
|
<dd><input type='file' name='attachment' id='file' /> <span class='AddAnotherFile'>(<a href='#'>{% trans "Add Another File" %}</a>)</span></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<input type='submit' value='Update This Ticket' />
|
<input type='submit' value='{% trans "Update This Ticket" %}' />
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "helpdesk/base.html" %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Ticket Listing{% endblock %}
|
{% block helpdesk_title %}{% trans "Ticket Listing" %}{% endblock %}
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/filter.js'></script>
|
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/filter.js'></script>
|
||||||
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/hover.js'></script>
|
<script type='text/javascript' language='javascript' src='{{ MEDIA_URL }}/helpdesk/hover.js'></script>
|
||||||
@ -9,58 +9,58 @@
|
|||||||
{% load in_list %}
|
{% load in_list %}
|
||||||
|
|
||||||
<form><select name='select' id='filterBuilderSelect'>
|
<form><select name='select' id='filterBuilderSelect'>
|
||||||
<option value='Sort'>Sorting</option>
|
<option value='Sort'>{% trans "Sorting" %}</option>
|
||||||
<option value='Owner'>Owner</option>
|
<option value='Owner'>{% trans "Owner" %}</option>
|
||||||
<option value='Queue'>Queue</option>
|
<option value='Queue'>{% trans "Queue" %}</option>
|
||||||
<option value='Status'>Status</option>
|
<option value='Status'>{% trans "Status" %}</option>
|
||||||
<option value='Keywords'>Keywords</option>
|
<option value='Keywords'>{% trans "Keywords" %}</option>
|
||||||
</select>
|
</select>
|
||||||
<input type='button' id='filterBuilderButton' value='+' /></form>
|
<input type='button' id='filterBuilderButton' value='+' /></form>
|
||||||
|
|
||||||
<form method='get' action='./'>
|
<form method='get' action='./'>
|
||||||
<div class='filterBox{% if sort %} filterBoxShow{% endif %}' id='filterBoxSort'>
|
<div class='filterBox{% if sort %} filterBoxShow{% endif %}' id='filterBoxSort'>
|
||||||
<label for='id_sort'>Sorting</label> <select id='id_sort' name='sort'>
|
<label for='id_sort'>Sorting</label> <select id='id_sort' name='sort'>
|
||||||
<option value='created'{% ifequal sort "created"%} selected='selected'{% endifequal %}>Created</option>
|
<option value='created'{% ifequal sort "created"%} selected='selected'{% endifequal %}>{% trans "Created" %}</option>
|
||||||
<option value='title'{% ifequal sort "title"%} selected='selected'{% endifequal %}>Title</option>
|
<option value='title'{% ifequal sort "title"%} selected='selected'{% endifequal %}>{% trans "Title" %}</option>
|
||||||
<option value='queue'{% ifequal sort "queue"%} selected='selected'{% endifequal %}>Queue</option>
|
<option value='queue'{% ifequal sort "queue"%} selected='selected'{% endifequal %}>{% trans "Queue" %}</option>
|
||||||
<option value='status'{% ifequal sort "status"%} selected='selected'{% endifequal %}>Status</option>
|
<option value='status'{% ifequal sort "status"%} selected='selected'{% endifequal %}>{% trans "Status" %}</option>
|
||||||
<option value='priority'{% ifequal sort "priority"%} selected='selected'{% endifequal %}>Priority</option>
|
<option value='priority'{% ifequal sort "priority"%} selected='selected'{% endifequal %}>{% trans "Priority" %}</option>
|
||||||
<option value='assigned_to'{% ifequal sort "assigned_to"%} selected='selected'{% endifequal %}>Owner</option>
|
<option value='assigned_to'{% ifequal sort "assigned_to"%} selected='selected'{% endifequal %}>{% trans "Owner" %}</option>
|
||||||
</select>
|
</select>
|
||||||
<input type='button' class='filterBuilderRemove' value='-' />
|
<input type='button' class='filterBuilderRemove' value='-' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='filterBox{% if owners %} filterBoxShow{% endif %}' id='filterBoxOwner'>
|
<div class='filterBox{% if owners %} filterBoxShow{% endif %}' id='filterBoxOwner'>
|
||||||
<label for='id_owners'>Owner(s)</label> <select id='id_owners' name='assigned_to' multiple='selected' size='5'>{% for u in user_choices %}<option value='{{ u.id }}'{% if u.id|in_list:owners %} selected='selected'{% endif %}>{{ u.username }}</option>{% endfor %}</select>
|
<label for='id_owners'>{% trans "Owner(s)" %}</label> <select id='id_owners' name='assigned_to' multiple='selected' size='5'>{% for u in user_choices %}<option value='{{ u.id }}'{% if u.id|in_list:owners %} selected='selected'{% endif %}>{{ u.username }}</option>{% endfor %}</select>
|
||||||
<input type='button' class='filterBuilderRemove' value='-' />
|
<input type='button' class='filterBuilderRemove' value='-' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='filterBox{% if queues %} filterBoxShow{% endif %}' id='filterBoxQueue'>
|
<div class='filterBox{% if queues %} filterBoxShow{% endif %}' id='filterBoxQueue'>
|
||||||
<label for='id_queues'>Queue(s)</label> <select id='id_queues' name='queue' multiple='selected' size='5'>{% for q in queue_choices %}<option value='{{ q.id }}'{% if q.id|in_list:queues %} selected='selected'{% endif %}>{{ q.title }}</option>{% endfor %}</select>
|
<label for='id_queues'>{% trans "Queue(s)" %}</label> <select id='id_queues' name='queue' multiple='selected' size='5'>{% for q in queue_choices %}<option value='{{ q.id }}'{% if q.id|in_list:queues %} selected='selected'{% endif %}>{{ q.title }}</option>{% endfor %}</select>
|
||||||
<input type='button' class='filterBuilderRemove' value='-' />
|
<input type='button' class='filterBuilderRemove' value='-' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='filterBox{% if statuses %} filterBoxShow{% endif %}' id='filterBoxStatus'>
|
<div class='filterBox{% if statuses %} filterBoxShow{% endif %}' id='filterBoxStatus'>
|
||||||
<label for='id_statuses'>Status(es)</label> {% for s in status_choices %}<input type='checkbox' name='status' value='{{ s.0 }}'{% if s.0|in_list:statuses %} checked='checked'{% endif %}> {{ s.1 }}{% endfor %}
|
<label for='id_statuses'>{% trans "Status(es)" %}</label> {% for s in status_choices %}<input type='checkbox' name='status' value='{{ s.0 }}'{% if s.0|in_list:statuses %} checked='checked'{% endif %}> {{ s.1 }}{% endfor %}
|
||||||
<input type='button' class='filterBuilderRemove' value='-' />
|
<input type='button' class='filterBuilderRemove' value='-' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class='filterBox{% if query %} filterBoxShow{% endif %}' id='filterBoxKeywords'>
|
<div class='filterBox{% if query %} filterBoxShow{% endif %}' id='filterBoxKeywords'>
|
||||||
<label for='id_query'>Keywords</label> <input type='text' name='q' value='{{ query }}' id='id_query' />
|
<label for='id_query'>{% trans "Keywords" %}</label> <input type='text' name='q' value='{{ query }}' id='id_query' />
|
||||||
<input type='button' class='filterBuilderRemove' value='-' />
|
<input type='button' class='filterBuilderRemove' value='-' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type='submit' value='Go!' />
|
<input type='submit' value='{% trans "Apply Filter" %}' />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='7'>Tickets</td></tr>
|
<tr class='row_tablehead'><td colspan='7'>{% trans "Tickets" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>#</th><th>Pr</th><th>Title</th><th>Queue</th><th>Status</th><th>Created</th><th>Owner</th></tr>
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Created" %}</th><th>{% trans "Owner" %}</th></tr>
|
||||||
{% if tickets %}{% for ticket in tickets %}
|
{% if tickets %}{% for ticket in tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||||
<td><img src='{{ ticket.get_priority_img }}' alt='Priority {{ ticket.priority }}' title='Priority {{ ticket.priority }}' height='16' width='16' /></td>
|
<td><img src='{{ ticket.get_priority_img }}' alt='{% trans "Priority {{ ticket.priority }}" %}' title='{% trans "Priority {{ ticket.priority }}" %}' height='16' width='16' /></td>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
<td>{{ ticket.queue }}</td>
|
<td>{{ ticket.queue }}</td>
|
||||||
<td>{{ ticket.get_status }}</td>
|
<td>{{ ticket.get_status }}</td>
|
||||||
@ -68,7 +68,7 @@
|
|||||||
<td>{{ ticket.get_assigned_to }}</td>
|
<td>{{ ticket.get_assigned_to }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}{% else %}
|
{% endfor %}{% else %}
|
||||||
<tr class='row_odd'><td colspan='5'>No Tickets Match Your Selection</td></tr>
|
<tr class='row_odd'><td colspan='5'>{% trans "No Tickets Match Your Selection" %}</td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
9
templates/registration/logged_out.html
Normal file
9
templates/registration/logged_out.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
|
{% block helpdesk_title %}{% trans "Logged Out" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block helpdesk_body %}{% blocktrans %}
|
||||||
|
<h2>Logged Out</h2>
|
||||||
|
|
||||||
|
<p>Thanks for being here. Hopefully you've helped resolve a few tickets and make the world a better place.</p>
|
||||||
|
|
||||||
|
{% endblocktrans %}{% endblock %}
|
@ -1,20 +1,20 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}Helpdesk Login{% endblock %}
|
{% block helpdesk_title %}{% trans "Helpdesk Login" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>Login</h2>
|
<h2>{% trans "Login" %}</h2>
|
||||||
|
|
||||||
<p>To log in and begin responding to cases, simply enter your username and password below.</p>
|
<p>{% trans "To log in and begin responding to cases, simply enter your username and password below." %}</p>
|
||||||
|
|
||||||
<form method='post' action='./'>
|
<form method='post' action='./'>
|
||||||
{% if form.has_errors %}<p>Your username and password didn't match. Please try again.</p>{% endif %}
|
{% if form.has_errors %}<p>{% trans "Your username and password didn't match. Please try again." %}</p>{% endif %}
|
||||||
<dl>
|
<dl>
|
||||||
<dt><label>Username</label></dt>
|
<dt><label>{% trans "Username" %}</label></dt>
|
||||||
<dd>{{ form.username }}</dd>
|
<dd>{{ form.username }}</dd>
|
||||||
<dt><label>Password</label></dt>
|
<dt><label>{% trans "Password" %}</label></dt>
|
||||||
<dd>{{ form.password }}</dd>
|
<dd>{{ form.password }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<input type='submit' value='Login' />
|
<input type='submit' value='{% trans "Login" %}' />
|
||||||
<input type="hidden" name="next" value="{% if next %}{{ next }}{% else %}../{% endif %}" />
|
<input type="hidden" name="next" value="{% if next %}{{ next }}{% else %}../{% endif %}" />
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}
|
|
||||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
|
||||||
<h2>Logout</h2>
|
|
||||||
|
|
||||||
<p>Thanks for being here. Hopefully you've helped resolve a few tickets and make the world a better place.</p>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
35
views.py
35
views.py
@ -15,9 +15,10 @@ from django.db.models import Q
|
|||||||
from django.http import HttpResponseRedirect, Http404, HttpResponse
|
from django.http import HttpResponseRedirect, Http404, HttpResponse
|
||||||
from django.shortcuts import render_to_response, get_object_or_404
|
from django.shortcuts import render_to_response, get_object_or_404
|
||||||
from django.template import loader, Context, RequestContext
|
from django.template import loader, Context, RequestContext
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from helpdesk.forms import TicketForm, PublicTicketForm
|
from helpdesk.forms import TicketForm, PublicTicketForm
|
||||||
from helpdesk.lib import send_templated_mail, line_chart, bar_chart
|
from helpdesk.lib import send_templated_mail, line_chart, bar_chart, query_to_dict
|
||||||
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment
|
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment
|
||||||
|
|
||||||
def dashboard(request):
|
def dashboard(request):
|
||||||
@ -43,7 +44,7 @@ def dashboard(request):
|
|||||||
GROUP BY queue, name
|
GROUP BY queue, name
|
||||||
ORDER BY q.id;
|
ORDER BY q.id;
|
||||||
""")
|
""")
|
||||||
dash_tickets = cursor.dictfetchall()
|
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
||||||
|
|
||||||
return render_to_response('helpdesk/dashboard.html',
|
return render_to_response('helpdesk/dashboard.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
@ -92,7 +93,7 @@ def view_ticket(request, ticket_id):
|
|||||||
owner = 0
|
owner = 0
|
||||||
else:
|
else:
|
||||||
owner = ticket.assigned_to.id
|
owner = ticket.assigned_to.id
|
||||||
request.POST = {'new_status': Ticket.CLOSED_STATUS, 'public': 1, 'owner': owner, 'title': ticket.title, 'comment': "Accepted resolution and closed ticket"}
|
request.POST = {'new_status': Ticket.CLOSED_STATUS, 'public': 1, 'owner': owner, 'title': ticket.title, 'comment': _('Accepted resolution and closed ticket')}
|
||||||
return update_ticket(request, ticket_id)
|
return update_ticket(request, ticket_id)
|
||||||
|
|
||||||
return render_to_response('helpdesk/ticket.html',
|
return render_to_response('helpdesk/ticket.html',
|
||||||
@ -126,11 +127,11 @@ def update_ticket(request, ticket_id):
|
|||||||
if owner:
|
if owner:
|
||||||
if owner != 0 and (ticket.assigned_to and owner != ticket.assigned_to.id) or not ticket.assigned_to:
|
if owner != 0 and (ticket.assigned_to and owner != ticket.assigned_to.id) or not ticket.assigned_to:
|
||||||
new_user = User.objects.get(id=owner)
|
new_user = User.objects.get(id=owner)
|
||||||
f.title = 'Assigned to %s' % new_user.username
|
f.title = _('Assigned to %(username)s') % {'username': new_user.username}
|
||||||
ticket.assigned_to = new_user
|
ticket.assigned_to = new_user
|
||||||
reassigned = True
|
reassigned = True
|
||||||
else:
|
else:
|
||||||
f.title = 'Unassigned'
|
f.title = _('Unassigned')
|
||||||
ticket.assigned_to = None
|
ticket.assigned_to = None
|
||||||
|
|
||||||
if new_status != ticket.status:
|
if new_status != ticket.status:
|
||||||
@ -144,19 +145,19 @@ def update_ticket(request, ticket_id):
|
|||||||
|
|
||||||
if not f.title:
|
if not f.title:
|
||||||
if f.comment:
|
if f.comment:
|
||||||
f.title = 'Comment'
|
f.title = _('Comment')
|
||||||
else:
|
else:
|
||||||
f.title = 'Updated'
|
f.title = _('Updated')
|
||||||
|
|
||||||
f.save()
|
f.save()
|
||||||
|
|
||||||
if title != ticket.title:
|
if title != ticket.title:
|
||||||
c = TicketChange(followup=f, field='Title', old_value=ticket.title, new_value=title)
|
c = TicketChange(followup=f, field=_('Title'), old_value=ticket.title, new_value=title)
|
||||||
c.save()
|
c.save()
|
||||||
ticket.title = title
|
ticket.title = title
|
||||||
|
|
||||||
if priority != ticket.priority:
|
if priority != ticket.priority:
|
||||||
c = TicketChange(followup=f, field='Priority', old_value=ticket.priority, new_value=priority)
|
c = TicketChange(followup=f, field=_('Priority'), old_value=ticket.priority, new_value=priority)
|
||||||
c.save()
|
c.save()
|
||||||
ticket.priority = priority
|
ticket.priority = priority
|
||||||
|
|
||||||
@ -315,7 +316,7 @@ def public_view(request):
|
|||||||
RequestContext(request, {'ticket': t,}))
|
RequestContext(request, {'ticket': t,}))
|
||||||
except:
|
except:
|
||||||
t = False;
|
t = False;
|
||||||
error_message = 'Invalid ticket ID or e-mail address. Please try again.'
|
error_message = _('Invalid ticket ID or e-mail address. Please try again.')
|
||||||
|
|
||||||
return render_to_response('helpdesk/public_view_form.html',
|
return render_to_response('helpdesk/public_view_form.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
@ -329,10 +330,10 @@ def hold_ticket(request, ticket_id, unhold=False):
|
|||||||
|
|
||||||
if unhold:
|
if unhold:
|
||||||
ticket.on_hold = False
|
ticket.on_hold = False
|
||||||
title = 'Ticket taken off hold'
|
title = _('Ticket taken off hold')
|
||||||
else:
|
else:
|
||||||
ticket.on_hold = True
|
ticket.on_hold = True
|
||||||
title = 'Ticket placed on hold'
|
title = _('Ticket placed on hold')
|
||||||
|
|
||||||
f = FollowUp(
|
f = FollowUp(
|
||||||
ticket = ticket,
|
ticket = ticket,
|
||||||
@ -368,15 +369,15 @@ def run_report(request, report):
|
|||||||
priority_sql = []
|
priority_sql = []
|
||||||
priority_columns = []
|
priority_columns = []
|
||||||
for p in Ticket.PRIORITY_CHOICES:
|
for p in Ticket.PRIORITY_CHOICES:
|
||||||
priority_sql.append("COUNT(CASE t.priority WHEN '%s' THEN t.id END) AS \"%s\"" % (p[0], p[1]))
|
priority_sql.append("COUNT(CASE t.priority WHEN '%s' THEN t.id END) AS \"%s\"" % (p[0], p[1]._proxy____unicode_cast()))
|
||||||
priority_columns.append("%s" % p[1])
|
priority_columns.append("%s" % p[1]._proxy____unicode_cast())
|
||||||
priority_sql = ", ".join(priority_sql)
|
priority_sql = ", ".join(priority_sql)
|
||||||
|
|
||||||
status_sql = []
|
status_sql = []
|
||||||
status_columns = []
|
status_columns = []
|
||||||
for s in Ticket.STATUS_CHOICES:
|
for s in Ticket.STATUS_CHOICES:
|
||||||
status_sql.append("COUNT(CASE t.status WHEN '%s' THEN t.id END) AS \"%s\"" % (s[0], s[1]))
|
status_sql.append("COUNT(CASE t.status WHEN '%s' THEN t.id END) AS \"%s\"" % (s[0], s[1]._proxy____unicode_cast()))
|
||||||
status_columns.append("%s" % s[1])
|
status_columns.append("%s" % s[1]._proxy____unicode_cast())
|
||||||
status_sql = ", ".join(status_sql)
|
status_sql = ", ".join(status_sql)
|
||||||
|
|
||||||
queue_sql = []
|
queue_sql = []
|
||||||
@ -483,7 +484,7 @@ def run_report(request, report):
|
|||||||
from django.db import connection
|
from django.db import connection
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
report_output = cursor.dictfetchall()
|
report_output = query_to_dict(cursor.fetchall(), cursor.description)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user