aboutsummaryrefslogtreecommitdiffstats
path: root/servo/views/note.py
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
committerFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
commit63b0fc6269b38edf7234b9f151b80d81f614c0a3 (patch)
tree555de3068f33f8dddb4619349bbea7d9b7c822fd /servo/views/note.py
downloadServo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.gz
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.bz2
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.zip
Initial commit
First public commit
Diffstat (limited to 'servo/views/note.py')
-rw-r--r--servo/views/note.py435
1 files changed, 435 insertions, 0 deletions
diff --git a/servo/views/note.py b/servo/views/note.py
new file mode 100644
index 0000000..29c74e1
--- /dev/null
+++ b/servo/views/note.py
@@ -0,0 +1,435 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, First Party Software
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+import json
+import StringIO
+from gsxws import escalations
+
+from django import template
+from django.contrib import messages
+from django.http import HttpResponse
+from django.utils.translation import ugettext as _
+from django.forms.models import modelformset_factory
+from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.cache import cache_page
+from django.shortcuts import render, redirect, get_object_or_404
+from django.contrib.auth.decorators import permission_required
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+
+from reportlab.lib.units import mm
+from reportlab.graphics.shapes import Drawing
+from reportlab.graphics.barcode import createBarcodeDrawing
+
+from servo.models import Order, Template, Tag, Customer, Note, Attachment, Escalation
+from servo.forms import NoteForm, NoteSearchForm, EscalationForm
+
+
+class BarcodeDrawing(Drawing):
+ def __init__(self, text_value, *args, **kwargs):
+ barcode = createBarcodeDrawing(
+ "Code128",
+ value=text_value.encode("utf-8"),
+ barHeight=10*mm,
+ width=80*mm
+ )
+
+ Drawing.__init__(self, barcode.width, barcode.height, *args, **kwargs)
+ self.add(barcode, name="barcode")
+
+
+def show_barcode(request, text):
+ """
+ Returns text as a barcode
+ """
+ if request.GET.get('f') == 'svg':
+ import barcode
+ output = StringIO.StringIO()
+ code = barcode.Code39(text, add_checksum=False)
+ code.write(output)
+ contents = output.getvalue()
+ output.close()
+ return HttpResponse(contents, content_type="image/svg+xml")
+
+ d = BarcodeDrawing(text)
+ return HttpResponse(d.asString("png"), content_type="image/png")
+
+
+def prep_list_view(request, kind):
+ """
+ Prepares the view for listing notes/messages
+ """
+ data = {'title': _("Messages")}
+ all_notes = Note.objects.all().order_by("-created_at")
+
+ if kind == "inbox":
+ all_notes = all_notes.filter(order=None).order_by("is_read", "-created_at")
+ if kind == "sent":
+ all_notes = all_notes.filter(created_by=request.user)
+ if kind == "flagged":
+ all_notes = all_notes.filter(is_flagged=True)
+ if kind == "escalations":
+ all_notes = Note.objects.all().exclude(escalation=None)
+
+ page = request.GET.get("page")
+ paginator = Paginator(all_notes, 20)
+
+ try:
+ notes = paginator.page(page)
+ except PageNotAnInteger:
+ notes = paginator.page(1)
+ except EmptyPage:
+ notes = paginator.page(paginator.num_pages)
+
+ data['kind'] = kind
+ data['notes'] = notes
+ data['inbox_count'] = Note.objects.filter(order=None).count()
+
+ return data
+
+
+@permission_required('servo.change_note')
+def copy(request, pk):
+ """
+ Copies a note with its attachments and labels
+ """
+ from servo.lib.shorturl import from_time
+ note = get_object_or_404(Note, pk=pk)
+
+ new_note = Note(created_by=request.user)
+ new_note.body = note.body
+ new_note.order = note.order
+ new_note.subject = note.subject
+ new_note.save()
+
+ new_note.labels = note.labels.all()
+
+ for a in note.attachments.all():
+ a.pk = None
+ a.content_object = new_note
+ a.save()
+ new_note.attachments.add(a)
+
+ return redirect(edit, pk=new_note.pk, order_id=note.order_id)
+
+
+@permission_required('servo.change_note')
+def edit(request, pk=None, order_id=None, parent=None, recipient=None, customer=None):
+ """
+ Edits a note
+ """
+ to = []
+ order = None
+ note = Note(order_id=order_id)
+ excluded_emails = note.get_excluded_emails()
+
+ if recipient is not None:
+ to.append(recipient)
+
+ if order_id is not None:
+ order = get_object_or_404(Order, pk=order_id)
+
+ if order.user and (order.user != request.user):
+ note.is_read = False
+ if order.user.email not in excluded_emails:
+ to.append(order.user.email)
+
+ if order.customer is not None:
+ customer = order.customer_id
+
+ if customer is not None:
+ customer = Customer.objects.get(pk=customer)
+ note.customer = customer
+
+ if order_id is None:
+ to.append(customer.email)
+
+ tpl = template.Template(note.subject)
+ note.subject = tpl.render(template.Context({'note': note}))
+
+ note.recipient = ', '.join(to)
+ note.created_by = request.user
+ note.sender = note.get_default_sender()
+
+ fields = escalations.CONTEXTS
+
+ try:
+ note.escalation = Escalation(created_by=request.user)
+ except Exception, e:
+ messages.error(request, e)
+ return redirect(request.META['HTTP_REFERER'])
+
+ AttachmentFormset = modelformset_factory(Attachment,
+ fields=('content',),
+ can_delete=True,
+ extra=3,
+ exclude=[])
+ formset = AttachmentFormset(queryset=Attachment.objects.none())
+
+ if pk is not None:
+ note = get_object_or_404(Note, pk=pk)
+ formset = AttachmentFormset(queryset=note.attachments.all())
+
+ if parent is not None:
+ parent = Note.objects.get(pk=parent)
+ note.parent = parent
+ note.body = parent.quote()
+
+ if parent.subject:
+ note.subject = _(u'Re: %s') % parent.clean_subject()
+ if parent.sender not in excluded_emails:
+ note.recipient = parent.sender
+ if parent.order:
+ order = parent.order
+ note.order = parent.order
+
+ note.customer = parent.customer
+ note.escalation = parent.escalation
+ note.is_reported = parent.is_reported
+
+ title = note.subject
+ form = NoteForm(instance=note)
+
+ if note.escalation:
+ contexts = json.loads(note.escalation.contexts)
+
+ escalation_form = EscalationForm(prefix='escalation', instance=note.escalation)
+
+ if request.method == "POST":
+ escalation_form = EscalationForm(request.POST,
+ prefix='escalation',
+ instance=note.escalation)
+
+ if escalation_form.is_valid():
+ note.escalation = escalation_form.save()
+
+ form = NoteForm(request.POST, instance=note)
+
+ if form.is_valid():
+
+ note = form.save()
+ formset = AttachmentFormset(request.POST, request.FILES)
+
+ if formset.is_valid():
+
+ files = formset.save(commit=False)
+
+ for f in files:
+ f.content_object = note
+ try:
+ f.save()
+ except ValueError, e:
+ messages.error(request, e)
+ return redirect(note)
+
+ note.attachments.add(*files)
+ note.save()
+
+ try:
+ msg = note.send_and_save(request.user)
+ messages.success(request, msg)
+ except ValueError, e:
+ messages.error(request, e)
+
+ return redirect(note)
+
+ return render(request, "notes/form.html", locals())
+
+
+def delete_note(request, pk):
+ """
+ Deletes a note
+ """
+ note = get_object_or_404(Note, pk=pk)
+
+ if request.method == 'POST':
+ note.delete()
+ messages.success(request, _("Note deleted"))
+
+ if request.session.get('return_to'):
+ url = request.session.get('return_to')
+ del(request.session['return_to'])
+ elif note.order_id:
+ url = note.order.get_absolute_url()
+
+ return redirect(url)
+
+ return render(request, 'notes/remove.html', {'note': note})
+
+
+@csrf_exempt
+def render_template(request):
+ """
+ Renders the template with this title with the current
+ Service Order as the context
+ """
+ content = ''
+ title = request.POST.get('title')
+ tpl = Template.objects.get(title=title)
+
+ if request.session.get('current_order_id'):
+ tpl = template.Template(tpl.content)
+ order = Order.objects.get(pk=request.session['current_order_id'])
+ content = tpl.render(template.Context({'order': order}))
+
+ return HttpResponse(content)
+
+
+def templates(request, template_id=None):
+ if template_id is not None:
+ tpl = Template.objects.get(pk=template_id)
+ content = tpl.content
+ if request.session.get('current_order_id'):
+ tpl = template.Template(content)
+ order = Order.objects.get(pk=request.session['current_order_id'])
+ content = tpl.render(template.Context({'order': order}))
+
+ return HttpResponse(content)
+
+ templates = Template.objects.all()
+ return render(request, 'notes/templates.html', {'templates': templates})
+
+
+def toggle_flag(request, pk, flag):
+ field = 'is_%s' % flag
+ note = Note.objects.get(pk=pk)
+ attr = getattr(note, field)
+ setattr(note, field, not attr)
+ note.save()
+
+ return HttpResponse(getattr(note, 'get_%s_title' % flag)())
+
+
+def toggle_tag(request, pk, tag_id):
+ note = Note.objects.get(pk=pk)
+ tag = Tag.objects.get(pk=tag_id)
+
+ if tag in note.labels.all():
+ note.labels.remove(tag)
+ else:
+ note.labels.add(tag)
+
+ if note.order:
+ return redirect(note.order)
+
+ return HttpResponse(_('OK'))
+
+def list_notes(request, kind="inbox"):
+ data = prep_list_view(request, kind)
+ request.session['return_to'] = request.path
+ return render(request, "notes/list_notes.html", data)
+
+
+def view_note(request, kind, pk):
+ note = Note.objects.get(pk=pk)
+ data = prep_list_view(request, kind)
+ data['title'] = note.subject
+ data['note'] = note
+
+ if kind == 'escalations':
+ return render(request, "notes/view_escalation.html", data)
+ else:
+ return render(request, "notes/view_note.html", data)
+
+
+def search(request):
+ query = request.GET.get("q")
+ request.session['search_query'] = query
+
+ title = _(u'Notes containing "%s"') % query
+ results = Note.objects.filter(body__icontains=query).order_by('-created_at')
+ paginator = Paginator(results, 10)
+
+ page = request.GET.get("page")
+
+ try:
+ notes = paginator.page(page)
+ except PageNotAnInteger:
+ notes = paginator.page(1)
+ except EmptyPage:
+ notes = paginator.page(paginator.num_pages)
+
+ return render(request, "notes/search.html", locals())
+
+
+def find(request):
+ form = NoteSearchForm(request.GET)
+ results = Note.objects.none()
+
+ if request.GET and form.is_valid():
+
+ fdata = form.cleaned_data
+ results = Note.objects.all()
+
+ if fdata.get('body'):
+ results = results.filter(body__icontains=fdata['body'])
+ if fdata.get('recipient'):
+ results = results.filter(recipient__icontains=fdata['recipient'])
+ if fdata.get('sender'):
+ results = results.filter(sender__icontains=fdata['sender'])
+ if fdata.get('order_code'):
+ results = results.filter(order__code__icontains=fdata['order_code'])
+
+ results = results.order_by('-created_at')
+
+ paginator = Paginator(results, 10)
+ page = request.GET.get("page")
+
+ try:
+ notes = paginator.page(page)
+ except PageNotAnInteger:
+ notes = paginator.page(1)
+ except EmptyPage:
+ notes = paginator.page(paginator.num_pages)
+
+ title = _('Message search')
+ return render(request, "notes/find.html", locals())
+
+
+def edit_escalation(request):
+ pass
+
+
+def create_escalation(request):
+ esc = Escalation()
+ form = EscalationForm()
+ title = _('Edit Escalation')
+
+ if request.method == 'POST':
+ data = request.POST.copy()
+ data['created_by'] = request.user
+ form = EscalationForm(data, request.FILES, instance=esc)
+ if form.is_valid():
+ note = form.save()
+ #esc.submit(request.user)
+ return redirect(view_note, 'escalations', note.pk)
+
+ return render(request, 'notes/edit_escalation.html', locals())
+
+
+def list_messages(request, pk):
+ note = get_object_or_404(Note, pk=pk)
+ messages = note.message_set.all()
+ return render(request, "notes/messages.html", locals())