From 63b0fc6269b38edf7234b9f151b80d81f614c0a3 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Tue, 4 Aug 2015 10:11:24 +0300 Subject: Initial commit First public commit --- servo/views/note.py | 435 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 servo/views/note.py (limited to 'servo/views/note.py') 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()) -- cgit v1.2.3