forked from extern/django-helpdesk
Custom logic for determining if the user is considered helpdesk staff.
This commit is contained in:
parent
3bd2d67193
commit
13830a84e5
@ -75,15 +75,15 @@ These changes are visible throughout django-helpdesk
|
|||||||
**Default:** ``HELPDESK_SHOW_CHANGE_PASSWORD = False``
|
**Default:** ``HELPDESK_SHOW_CHANGE_PASSWORD = False``
|
||||||
|
|
||||||
- **HELPDESK_FOLLOWUP_MOD** Allow user to override default layout for 'followups' (work in progress)
|
- **HELPDESK_FOLLOWUP_MOD** Allow user to override default layout for 'followups' (work in progress)
|
||||||
|
|
||||||
**Default:** ``HELPDESK_FOLLOWUP_MOD = False``
|
**Default:** ``HELPDESK_FOLLOWUP_MOD = False``
|
||||||
|
|
||||||
- **HELPDESK_CUSTOM_WELCOME** Show custom welcome message in dashboard?
|
- **HELPDESK_CUSTOM_WELCOME** Show custom welcome message in dashboard?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_CUSTOM_WELCOME = False``
|
**Default:** ``HELPDESK_CUSTOM_WELCOME = False``
|
||||||
|
|
||||||
- **HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE ** Auto-subscribe user to ticket as a 'CC' if (s)he responds to a ticket?
|
- **HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE ** Auto-subscribe user to ticket as a 'CC' if (s)he responds to a ticket?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE = False``
|
**Default:** ``HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE = False``
|
||||||
|
|
||||||
- **HELPDESK_EMAIL_SUBJECT_TEMPLATE ** Subject template for templated emails. ``%(subject)s`` represents the subject wording from the email template (e.g. "(Closed)").
|
- **HELPDESK_EMAIL_SUBJECT_TEMPLATE ** Subject template for templated emails. ``%(subject)s`` represents the subject wording from the email template (e.g. "(Closed)").
|
||||||
@ -97,28 +97,35 @@ Options shown on public pages
|
|||||||
These options only change display of items on public-facing pages, not staff pages.
|
These options only change display of items on public-facing pages, not staff pages.
|
||||||
|
|
||||||
- **HELPDESK_VIEW_A_TICKET_PUBLIC** Show 'View a Ticket' section on public page?
|
- **HELPDESK_VIEW_A_TICKET_PUBLIC** Show 'View a Ticket' section on public page?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_VIEW_A_TICKET_PUBLIC = True``
|
**Default:** ``HELPDESK_VIEW_A_TICKET_PUBLIC = True``
|
||||||
|
|
||||||
- **HELPDESK_SUBMIT_A_TICKET_PUBLIC** Show 'submit a ticket' section & form on public page?
|
- **HELPDESK_SUBMIT_A_TICKET_PUBLIC** Show 'submit a ticket' section & form on public page?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_SUBMIT_A_TICKET_PUBLIC = True``
|
**Default:** ``HELPDESK_SUBMIT_A_TICKET_PUBLIC = True``
|
||||||
|
|
||||||
- **HELPDESK_SHOW_KB_ON_HOMEPAGE** Should we should the KB categories on the homepage?
|
- **HELPDESK_SHOW_KB_ON_HOMEPAGE** Should we should the KB categories on the homepage?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_SHOW_KB_ON_HOMEPAGE = False``
|
**Default:** ``HELPDESK_SHOW_KB_ON_HOMEPAGE = False``
|
||||||
|
|
||||||
|
|
||||||
Options that change ticket updates
|
Options that change ticket updates
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
- **HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE** Allow non-staff users to interact with tickets? This will also change how 'staff_member_required'
|
- **HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE** Allow non-staff users to interact with tickets? This will also change how 'staff_member_required'
|
||||||
in staff.py will be defined.
|
in staff.py will be defined.
|
||||||
|
|
||||||
**Default:** ``HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False``
|
**Default:** ``HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False``
|
||||||
|
|
||||||
|
- **HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK** Apply a custom authorisation logic when defining 'staff_member_required' in staff.py.
|
||||||
|
If set, `HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE` will be ignored when determining staff access.
|
||||||
|
The value should be a function accepting the active user as a parameter and returning True if the user is considered helpdesk
|
||||||
|
staff.
|
||||||
|
|
||||||
|
**Default:** ``HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = None``
|
||||||
|
|
||||||
- **HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP** Show edit buttons in ticket follow ups?
|
- **HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP** Show edit buttons in ticket follow ups?
|
||||||
|
|
||||||
**Default:** ``HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = True``
|
**Default:** ``HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = True``
|
||||||
|
|
||||||
- **HELPDESK_SHOW_DELETE_BUTTON_SUPERUSER_FOLLOW_UP** Show delete buttons in ticket follow ups if user is 'superuser'?
|
- **HELPDESK_SHOW_DELETE_BUTTON_SUPERUSER_FOLLOW_UP** Show delete buttons in ticket follow ups if user is 'superuser'?
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Default settings for django-helpdesk.
|
Default settings for django-helpdesk.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import warnings
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
@ -60,10 +60,17 @@ HELPDESK_SUBMIT_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_SUBMIT_A_TICKET_PU
|
|||||||
|
|
||||||
|
|
||||||
''' options for update_ticket views '''
|
''' options for update_ticket views '''
|
||||||
# allow non-staff users to interact with tickets? this will also change how 'staff_member_required'
|
# allow non-staff users to interact with tickets? this will also change how 'staff_member_required'
|
||||||
# in staff.py will be defined.
|
# in staff.py will be defined.
|
||||||
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, 'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', False)
|
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, 'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', False)
|
||||||
|
|
||||||
|
# apply a custom authorisation logic when defining 'staff_member_required' in staff.py.
|
||||||
|
HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK = getattr(settings, 'HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK', None)
|
||||||
|
if HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK and HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||||
|
warnings.warn(
|
||||||
|
"The HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE and HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK settings cannot be both defined. "
|
||||||
|
"Only HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK will be considered in determining staff access.", RuntimeWarning)
|
||||||
|
|
||||||
# show edit buttons in ticket follow ups.
|
# show edit buttons in ticket follow ups.
|
||||||
HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, 'HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP', True)
|
HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, 'HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP', True)
|
||||||
|
|
||||||
@ -73,10 +80,10 @@ HELPDESK_SHOW_DELETE_BUTTON_SUPERUSER_FOLLOW_UP = getattr(settings, 'HELPDESK_SH
|
|||||||
# make all updates public by default? this will hide the 'is this update public' checkbox
|
# make all updates public by default? this will hide the 'is this update public' checkbox
|
||||||
HELPDESK_UPDATE_PUBLIC_DEFAULT = getattr(settings, 'HELPDESK_UPDATE_PUBLIC_DEFAULT', False)
|
HELPDESK_UPDATE_PUBLIC_DEFAULT = getattr(settings, 'HELPDESK_UPDATE_PUBLIC_DEFAULT', False)
|
||||||
|
|
||||||
# only show staff users in ticket owner drop-downs
|
# only show staff users in ticket owner drop-downs
|
||||||
HELPDESK_STAFF_ONLY_TICKET_OWNERS = getattr(settings, 'HELPDESK_STAFF_ONLY_TICKET_OWNERS', False)
|
HELPDESK_STAFF_ONLY_TICKET_OWNERS = getattr(settings, 'HELPDESK_STAFF_ONLY_TICKET_OWNERS', False)
|
||||||
|
|
||||||
# only show staff users in ticket cc drop-down
|
# only show staff users in ticket cc drop-down
|
||||||
HELPDESK_STAFF_ONLY_TICKET_CC = getattr(settings, 'HELPDESK_STAFF_ONLY_TICKET_CC', False)
|
HELPDESK_STAFF_ONLY_TICKET_CC = getattr(settings, 'HELPDESK_STAFF_ONLY_TICKET_CC', False)
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +39,10 @@ from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTi
|
|||||||
from helpdesk.lib import send_templated_mail, query_to_dict, apply_query, safe_template_context
|
from helpdesk.lib import send_templated_mail, query_to_dict, apply_query, safe_template_context
|
||||||
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC, TicketDependency
|
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC, TicketDependency
|
||||||
from helpdesk import settings as helpdesk_settings
|
from helpdesk import settings as helpdesk_settings
|
||||||
|
|
||||||
if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
if helpdesk_settings.HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK:
|
||||||
|
staff_member_required = user_passes_test(helpdesk_settings.HELPDESK_CUSTOM_STAFF_FILTER_CALLBACK)
|
||||||
|
elif helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||||
# treat 'normal' users like 'staff'
|
# treat 'normal' users like 'staff'
|
||||||
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active)
|
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active)
|
||||||
else:
|
else:
|
||||||
@ -69,7 +71,7 @@ def dashboard(request):
|
|||||||
|
|
||||||
# closed & resolved tickets, assigned to current user
|
# closed & resolved tickets, assigned to current user
|
||||||
tickets_closed_resolved = Ticket.objects.filter(
|
tickets_closed_resolved = Ticket.objects.filter(
|
||||||
assigned_to=request.user,
|
assigned_to=request.user,
|
||||||
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS])
|
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS])
|
||||||
|
|
||||||
unassigned_tickets = Ticket.objects.filter(
|
unassigned_tickets = Ticket.objects.filter(
|
||||||
@ -107,7 +109,7 @@ def dashboard(request):
|
|||||||
GROUP BY queue, name
|
GROUP BY queue, name
|
||||||
ORDER BY q.id;
|
ORDER BY q.id;
|
||||||
""")
|
""")
|
||||||
|
|
||||||
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
||||||
|
|
||||||
return render_to_response('helpdesk/dashboard.html',
|
return render_to_response('helpdesk/dashboard.html',
|
||||||
@ -200,7 +202,7 @@ def view_ticket(request, ticket_id):
|
|||||||
|
|
||||||
if request.GET.has_key('take'):
|
if request.GET.has_key('take'):
|
||||||
# Allow the user to assign the ticket to themselves whilst viewing it.
|
# Allow the user to assign the ticket to themselves whilst viewing it.
|
||||||
|
|
||||||
# Trick the update_ticket() view into thinking it's being called with
|
# Trick the update_ticket() view into thinking it's being called with
|
||||||
# a valid POST.
|
# a valid POST.
|
||||||
request.POST = {
|
request.POST = {
|
||||||
@ -261,7 +263,7 @@ view_ticket = staff_member_required(view_ticket)
|
|||||||
|
|
||||||
def return_ticketccstring_and_show_subscribe(user, ticket):
|
def return_ticketccstring_and_show_subscribe(user, ticket):
|
||||||
''' used in view_ticket() and followup_edit()'''
|
''' used in view_ticket() and followup_edit()'''
|
||||||
# create the ticketcc_string and check whether current user is already
|
# create the ticketcc_string and check whether current user is already
|
||||||
# subscribed
|
# subscribed
|
||||||
username = user.username.upper()
|
username = user.username.upper()
|
||||||
useremail = user.email.upper()
|
useremail = user.email.upper()
|
||||||
@ -448,7 +450,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
|
|
||||||
messages_sent_to = []
|
messages_sent_to = []
|
||||||
|
|
||||||
# ticket might have changed above, so we re-instantiate context with the
|
# ticket might have changed above, so we re-instantiate context with the
|
||||||
# (possibly) updated ticket.
|
# (possibly) updated ticket.
|
||||||
context = safe_template_context(ticket)
|
context = safe_template_context(ticket)
|
||||||
context.update(
|
context.update(
|
||||||
@ -457,7 +459,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if public and (f.comment or (f.new_status in (Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS))):
|
if public and (f.comment or (f.new_status in (Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS))):
|
||||||
|
|
||||||
|
|
||||||
if f.new_status == Ticket.RESOLVED_STATUS:
|
if f.new_status == Ticket.RESOLVED_STATUS:
|
||||||
template = 'resolved_'
|
template = 'resolved_'
|
||||||
@ -712,7 +714,7 @@ def ticket_list(request):
|
|||||||
or request.GET.has_key('status')
|
or request.GET.has_key('status')
|
||||||
or request.GET.has_key('q')
|
or request.GET.has_key('q')
|
||||||
or request.GET.has_key('sort')
|
or request.GET.has_key('sort')
|
||||||
or request.GET.has_key('sortreverse')
|
or request.GET.has_key('sortreverse')
|
||||||
):
|
):
|
||||||
|
|
||||||
# Fall-back if no querying is being done, force the list to only
|
# Fall-back if no querying is being done, force the list to only
|
||||||
@ -751,7 +753,7 @@ def ticket_list(request):
|
|||||||
date_from = request.GET.get('date_from')
|
date_from = request.GET.get('date_from')
|
||||||
if date_from:
|
if date_from:
|
||||||
query_params['filtering']['created__gte'] = date_from
|
query_params['filtering']['created__gte'] = date_from
|
||||||
|
|
||||||
date_to = request.GET.get('date_to')
|
date_to = request.GET.get('date_to')
|
||||||
if date_to:
|
if date_to:
|
||||||
query_params['filtering']['created__lte'] = date_to
|
query_params['filtering']['created__lte'] = date_to
|
||||||
@ -842,7 +844,7 @@ def edit_ticket(request, ticket_id):
|
|||||||
return HttpResponseRedirect(ticket.get_absolute_url())
|
return HttpResponseRedirect(ticket.get_absolute_url())
|
||||||
else:
|
else:
|
||||||
form = EditTicketForm(instance=ticket)
|
form = EditTicketForm(instance=ticket)
|
||||||
|
|
||||||
return render_to_response('helpdesk/edit_ticket.html',
|
return render_to_response('helpdesk/edit_ticket.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
'form': form,
|
'form': form,
|
||||||
@ -854,7 +856,7 @@ def create_ticket(request):
|
|||||||
assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by('username')
|
assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by('username')
|
||||||
else:
|
else:
|
||||||
assignable_users = User.objects.filter(is_active=True).order_by('username')
|
assignable_users = User.objects.filter(is_active=True).order_by('username')
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = TicketForm(request.POST, request.FILES)
|
form = TicketForm(request.POST, request.FILES)
|
||||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
||||||
@ -955,7 +957,7 @@ def run_report(request, report):
|
|||||||
return HttpResponseRedirect(reverse("helpdesk_report_index"))
|
return HttpResponseRedirect(reverse("helpdesk_report_index"))
|
||||||
|
|
||||||
report_queryset = Ticket.objects.all().select_related()
|
report_queryset = Ticket.objects.all().select_related()
|
||||||
|
|
||||||
from_saved_query = False
|
from_saved_query = False
|
||||||
saved_query = None
|
saved_query = None
|
||||||
|
|
||||||
@ -993,7 +995,7 @@ def run_report(request, report):
|
|||||||
_('Nov'),
|
_('Nov'),
|
||||||
_('Dec'),
|
_('Dec'),
|
||||||
)
|
)
|
||||||
|
|
||||||
first_ticket = Ticket.objects.all().order_by('created')[0]
|
first_ticket = Ticket.objects.all().order_by('created')[0]
|
||||||
first_month = first_ticket.created.month
|
first_month = first_ticket.created.month
|
||||||
first_year = first_ticket.created.year
|
first_year = first_ticket.created.year
|
||||||
@ -1106,15 +1108,15 @@ def run_report(request, report):
|
|||||||
if report == 'daysuntilticketclosedbymonth':
|
if report == 'daysuntilticketclosedbymonth':
|
||||||
summarytable2[metric1, metric2] += metric3
|
summarytable2[metric1, metric2] += metric3
|
||||||
|
|
||||||
|
|
||||||
table = []
|
table = []
|
||||||
|
|
||||||
if report == 'daysuntilticketclosedbymonth':
|
if report == 'daysuntilticketclosedbymonth':
|
||||||
for key in summarytable2.keys():
|
for key in summarytable2.keys():
|
||||||
summarytable[key] = summarytable2[key] / summarytable[key]
|
summarytable[key] = summarytable2[key] / summarytable[key]
|
||||||
|
|
||||||
header1 = sorted(set(list( i.encode('utf-8') for i,_ in summarytable.keys() )))
|
header1 = sorted(set(list( i.encode('utf-8') for i,_ in summarytable.keys() )))
|
||||||
|
|
||||||
column_headings = [col1heading] + possible_options
|
column_headings = [col1heading] + possible_options
|
||||||
|
|
||||||
# Pivot the data so that 'header1' fields are always first column
|
# Pivot the data so that 'header1' fields are always first column
|
||||||
@ -1330,11 +1332,11 @@ def calc_basic_ticket_stats(Ticket):
|
|||||||
date_30_str = date_30.strftime('%Y-%m-%d')
|
date_30_str = date_30.strftime('%Y-%m-%d')
|
||||||
date_60_str = date_60.strftime('%Y-%m-%d')
|
date_60_str = date_60.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
# > 0 & <= 30
|
# > 0 & <= 30
|
||||||
ota_le_30 = all_open_tickets.filter(created__gte = date_30_str)
|
ota_le_30 = all_open_tickets.filter(created__gte = date_30_str)
|
||||||
N_ota_le_30 = len(ota_le_30)
|
N_ota_le_30 = len(ota_le_30)
|
||||||
|
|
||||||
# >= 30 & <= 60
|
# >= 30 & <= 60
|
||||||
ota_le_60_ge_30 = all_open_tickets.filter(created__gte = date_60_str, created__lte = date_30_str)
|
ota_le_60_ge_30 = all_open_tickets.filter(created__gte = date_60_str, created__lte = date_30_str)
|
||||||
N_ota_le_60_ge_30 = len(ota_le_60_ge_30)
|
N_ota_le_60_ge_30 = len(ota_le_60_ge_30)
|
||||||
|
|
||||||
@ -1357,7 +1359,7 @@ def calc_basic_ticket_stats(Ticket):
|
|||||||
average_nbr_days_until_ticket_closed_last_60_days = calc_average_nbr_days_until_ticket_resolved(all_closed_last_60_days)
|
average_nbr_days_until_ticket_closed_last_60_days = calc_average_nbr_days_until_ticket_resolved(all_closed_last_60_days)
|
||||||
|
|
||||||
# put together basic stats
|
# put together basic stats
|
||||||
basic_ticket_stats = { 'average_nbr_days_until_ticket_closed': average_nbr_days_until_ticket_closed,
|
basic_ticket_stats = { 'average_nbr_days_until_ticket_closed': average_nbr_days_until_ticket_closed,
|
||||||
'average_nbr_days_until_ticket_closed_last_60_days': average_nbr_days_until_ticket_closed_last_60_days,
|
'average_nbr_days_until_ticket_closed_last_60_days': average_nbr_days_until_ticket_closed_last_60_days,
|
||||||
'open_ticket_stats': ots, }
|
'open_ticket_stats': ots, }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user