From 97886abc7697ef20e3d646272c9601ac54a6e4e1 Mon Sep 17 00:00:00 2001 From: Ross Poulton Date: Sat, 29 Jan 2011 06:02:03 +0000 Subject: [PATCH] Add ability for FollowUp records to be edited by staff. Closes Google Code issue #131; Github issue #5. Thanks to Google user 'alecs.box' for the patch. --- helpdesk/forms.py | 9 +++ helpdesk/htdocs/helpdesk.css | 5 ++ helpdesk/models.py | 4 +- .../templates/helpdesk/followup_edit.html | 31 ++++++++++ helpdesk/templates/helpdesk/ticket.html | 60 ++----------------- .../templates/helpdesk/ticket_desc_table.html | 53 ++++++++++++++++ helpdesk/urls.py | 4 ++ helpdesk/views/staff.py | 40 ++++++++++++- 8 files changed, 147 insertions(+), 59 deletions(-) create mode 100644 helpdesk/templates/helpdesk/followup_edit.html create mode 100644 helpdesk/templates/helpdesk/ticket_desc_table.html diff --git a/helpdesk/forms.py b/helpdesk/forms.py index f91eab55..cde9618d 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -23,6 +23,15 @@ class EditTicketForm(forms.ModelForm): model = Ticket exclude = ('created', 'modified', 'status', 'on_hold', 'resolution', 'last_escalation', 'assigned_to') +class EditFollowUpForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + "Filter not openned tickets here." + super(EditFollowUpForm, self).__init__(*args, **kwargs) + self.fields["ticket"].queryset = Ticket.objects.filter(status__in=(Ticket.OPEN_STATUS, Ticket.REOPENED_STATUS)) + class Meta: + model = FollowUp + exclude = ('date', 'user',) + class TicketForm(forms.Form): queue = forms.ChoiceField( label=_('Queue'), diff --git a/helpdesk/htdocs/helpdesk.css b/helpdesk/htdocs/helpdesk.css index d38333c4..331ceb44 100644 --- a/helpdesk/htdocs/helpdesk.css +++ b/helpdesk/htdocs/helpdesk.css @@ -151,6 +151,7 @@ td { div.followup { width: 100%; border-top: solid #666 1px; + padding:0 0 2px; } div.followup .title { @@ -257,3 +258,7 @@ span.priority5 { background-color: #8c5; color: #fff; } + +a.followup-edit { + float:right; +} \ No newline at end of file diff --git a/helpdesk/models.py b/helpdesk/models.py index 638eef10..69698ba4 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -453,7 +453,8 @@ class FollowUp(models.Model): ticket = models.ForeignKey(Ticket) date = models.DateTimeField( - _('Date'), + _('Date'), + default = datetime.now() ) title = models.CharField( @@ -505,7 +506,6 @@ class FollowUp(models.Model): def save(self, force_insert=False, force_update=False): t = self.ticket t.modified = datetime.now() - self.date = datetime.now() t.save() super(FollowUp, self).save(force_insert, force_update) diff --git a/helpdesk/templates/helpdesk/followup_edit.html b/helpdesk/templates/helpdesk/followup_edit.html new file mode 100644 index 00000000..d25d73c7 --- /dev/null +++ b/helpdesk/templates/helpdesk/followup_edit.html @@ -0,0 +1,31 @@ +{% extends "helpdesk/base.html" %}{% load i18n %} +{% block helpdesk_title %}{% trans "Edit followup" %}{% endblock %} +{% block helpdesk_head %}{% endblock helpdesk_head %} + +{% block helpdesk_body %} + +{% include "helpdesk/ticket_desc_table.html" %} + +

{% trans "Edit FollowUp" %}

+
+ {{ form.non_field_errors }} +
+
+
+
{{ form.ticket }}
+
+
{{ form.title }}
+ +
+
{{ form.comment }}
+ +
+
{{ form.public }}
+

Public tickets are viewable by the submitter and all staff, but non-public tickets can only be seen by staff.

+
+
{{ form.new_status }}
+

If the status was changed, what was it changed to?

+
+

{% csrf_token %} +
+{% endblock helpdesk_body %} \ No newline at end of file diff --git a/helpdesk/templates/helpdesk/ticket.html b/helpdesk/templates/helpdesk/ticket.html index 07b35450..bb1205a6 100644 --- a/helpdesk/templates/helpdesk/ticket.html +++ b/helpdesk/templates/helpdesk/ticket.html @@ -42,66 +42,18 @@ {% block helpdesk_body %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{% if tags_enabled %} - - - - -{% endif %} - - - - - - - - - -{% if ticket.resolution %} - - - - -{% endif %} - -
{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]EditDelete{% if ticket.on_hold %}{% trans "Unhold" %}{% else %}{% trans "Hold" %}{% endif %}
{% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}
{% trans "Submitted On" %}{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)
{% trans "Assigned To" %}{{ ticket.get_assigned_to }}{% ifequal ticket.get_assigned_to _('Unassigned') %} {% trans "Take" %}{% endifequal %}
{% trans "Submitter E-Mail" %}{{ ticket.submitter_email }}{% if user.is_superuser %} {% trans "Ignore" %}{% endif %}
{% trans "Priority" %}{{ ticket.get_priority_display }}
{% trans "Copies To" %}{% for ticketcc in ticket.ticketcc_set.all %}{{ ticketcc.display }}{% if not forloop.last %}, {% endif %}{% endfor %} {% trans "Manage" %}
{% trans "Tags" %}{{ ticket.tags }}
{% trans "Description" %}
{{ ticket.description|force_escape|linebreaksbr }}
{% trans "Resolution" %}{% ifequal ticket.get_status_display "Resolved" %} {% trans "Accept" %}{% endifequal %}
{{ ticket.resolution|force_escape }}
+{% include "helpdesk/ticket_desc_table.html" %} {% if ticket.followup_set.all %}

{% trans "Follow-Ups" %}

{% load ticket_to_link %} {% for followup in ticket.followup_set.all %}
-
{{ followup.title }}
-{% if followup.comment %}{{ followup.comment|force_escape|num_to_link|linebreaksbr }}{% endif %} +
+ {{ followup.title }} + Edit +
+{% if followup.comment %}{{ followup.comment|force_escape|num_to_link|linebreaksbr }}{% endif %} {% for change in followup.ticketchange_set.all %} {% if forloop.first %}
    {% endif %}
  • {% blocktrans with change.field as field and change.old_value as old_value and change.new_value as new_value %}Changed {{ field }} from {{ old_value }} to {{ new_value }}.{% endblocktrans %}
  • diff --git a/helpdesk/templates/helpdesk/ticket_desc_table.html b/helpdesk/templates/helpdesk/ticket_desc_table.html new file mode 100644 index 00000000..7a257dee --- /dev/null +++ b/helpdesk/templates/helpdesk/ticket_desc_table.html @@ -0,0 +1,53 @@ +{% load i18n %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if tags_enabled %} + + + + +{% endif %} + + + + + + + + + +{% if ticket.resolution %} + + + + +{% endif %} + +
    {{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}]EditDelete{% if ticket.on_hold %}{% trans "Unhold" %}{% else %}{% trans "Hold" %}{% endif %}
    {% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}
    {% trans "Submitted On" %}{{ ticket.created|date:"r" }} ({{ ticket.created|timesince }} ago)
    {% trans "Assigned To" %}{{ ticket.get_assigned_to }}{% ifequal ticket.get_assigned_to _('Unassigned') %} {% trans "Take" %}{% endifequal %}
    {% trans "Submitter E-Mail" %}{{ ticket.submitter_email }}{% if user.is_superuser %} {% trans "Ignore" %}{% endif %}
    {% trans "Priority" %}{{ ticket.get_priority_display }}
    {% trans "Copies To" %}{% for ticketcc in ticket.ticketcc_set.all %}{{ ticketcc.display }}{% if not forloop.last %}, {% endif %}{% endfor %} {% trans "Manage" %}
    {% trans "Tags" %}{{ ticket.tags }}
    {% trans "Description" %}
    {{ ticket.description|force_escape|linebreaksbr }}
    {% trans "Resolution" %}{% ifequal ticket.get_status_display "Resolved" %} {% trans "Accept" %}{% endifequal %}
    {{ ticket.resolution|force_escape }}
    \ No newline at end of file diff --git a/helpdesk/urls.py b/helpdesk/urls.py index 1e792233..8226ae1b 100644 --- a/helpdesk/urls.py +++ b/helpdesk/urls.py @@ -34,6 +34,10 @@ urlpatterns = patterns('helpdesk.views.staff', url(r'^tickets/(?P[0-9]+)/$', 'view_ticket', name='helpdesk_view'), + + url(r'^tickets/(?P[0-9]+)/followup_edit/(?P[0-9]+)/$', + 'followup_edit', + name='helpdesk_followup_edit'), url(r'^tickets/(?P[0-9]+)/edit/$', 'edit_ticket', diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index 39fe8010..c9f8c4b8 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -21,8 +21,9 @@ from django.http import HttpResponseRedirect, Http404, HttpResponse, HttpRespons from django.shortcuts import render_to_response, get_object_or_404 from django.template import loader, Context, RequestContext from django.utils.translation import ugettext as _ +from django.utils.html import escape -from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm +from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm, EditFollowUpForm from helpdesk.lib import send_templated_mail, line_chart, bar_chart, query_to_dict, apply_query, safe_template_context from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC from helpdesk.settings import HAS_TAG_SUPPORT @@ -96,7 +97,40 @@ def delete_ticket(request, ticket_id): return HttpResponseRedirect(reverse('helpdesk_home')) delete_ticket = staff_member_required(delete_ticket) - +def followup_edit(request, ticket_id, followup_id, ): + "Edit followup options with an ability to change the ticket." + followup = get_object_or_404(FollowUp, id=followup_id) + ticket = get_object_or_404(Ticket, id=ticket_id) + if request.method == 'GET': + form = EditFollowUpForm(initial= + {'title': escape(followup.title), + 'ticket': followup.ticket, + 'comment': escape(followup.comment), + 'public': followup.public, + 'new_status': followup.new_status, + }) + + return render_to_response('helpdesk/followup_edit.html', + RequestContext(request, { + 'followup': followup, + 'ticket': ticket, + 'form': form, + })) + elif request.method == 'POST': + form = EditFollowUpForm(request.POST) + if form.is_valid(): + title = form.cleaned_data['title'] + _ticket = form.cleaned_data['ticket'] + comment = form.cleaned_data['comment'] + public = form.cleaned_data['public'] + new_status = form.cleaned_data['new_status'] + #will save previous date + old_date = followup.date + followup.delete() + new_followup = FollowUp(title=title, date=old_date, ticket=_ticket, comment=comment, public=public, new_status=new_status, ) + new_followup.save() + return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket.id])) + def view_ticket(request, ticket_id): ticket = get_object_or_404(Ticket, id=ticket_id) @@ -749,7 +783,7 @@ def run_report(request, report): 'Dec', ) month_columns = [] - + # Throw an error if there are no tickets first_ticket = Ticket.objects.all().order_by('created')[0] first_month = first_ticket.created.month first_year = first_ticket.created.year