Beispiel #1
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid in [None, '']:
            return

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()
        
        for i in Escalation.objects.exclude(Q(escalation_id='') | Q(status='C')):
            i.gsx_account.connect(i.created_by)
            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at: # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies: # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
Beispiel #2
0
def check_mail():
    """Checks IMAP box for incoming mail"""
    uid = Configuration.conf('imap_act')

    if empty(uid):
        raise ConfigurationError('Incoming message user not configured')

    counter = 0
    user = User.objects.get(pk=uid)
    server = Configuration.get_imap_server()
    typ, data = server.search(None, "UnSeen")

    for num in data[0].split():
        #logging.debug("** Processing message %s" % num)
        typ, data = server.fetch(num, "(RFC822)")
        # parsestr() seems to return an email.message?
        msg = Parser().parsestr(data[0][1])
        Note.from_email(msg, user)
        #server.copy(num, 'servo')
        server.store(num, '+FLAGS', '\\Seen')
        counter += 1

    server.close()
    server.logout()

    return '%d messages processed' % counter
Beispiel #3
0
def apply_rules(event):

	rules = cache.get('rules', get_rules())

	for r in rules:
		if (r['event'] == event.action) and (r['match'] == event.description):

			if r['action'] == "set_queue":
				order = event.content_object
				order.set_queue(r['data'], event.triggered_by)

			if r['action'] == "send_sms":
				number = 0
				order = event.content_object

				try:
					number = order.customer.get_standard_phone()
				except Exception as e:
					continue

				note = Note(order=order, created_by=event.triggered_by)

				note.body = r['data']
				note.render_body({'order': order})
				note.save()

				return note.send_sms(number, event.triggered_by)
Beispiel #4
0
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'])
Beispiel #5
0
    def handle(self, *args, **options):
        # get local user to create notes as
        uid = Configuration.conf('imap_act')

        if empty(uid):
            raise ConfigurationError('Incoming message user not defined')

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()

        for i in Escalation.objects.exclude(
                Q(escalation_id='') | Q(status='C')):
            # connect per-user since the escalations can be under different ship-tos
            try:
                i.gsx_account.connect(i.created_by)
            except Exception:
                continue  # skip auth errors so we don't get stuck

            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at:  # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies:  # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
    def handle(self, *args, **options):
        # get local user to create notes as
        uid = Configuration.conf('imap_act')
        
        if empty(uid):
            raise ConfigurationError('Incoming message user not defined')

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()
        
        for i in Escalation.objects.exclude(Q(escalation_id='') | Q(status='C')):
            # connect per-user since the escalations can be under different ship-tos
            try:
                i.gsx_account.connect(i.created_by)
            except Exception:
                continue # skip auth errors so we don't get stuck

            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at: # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies: # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
Beispiel #7
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid == '':
            raise ValueError('Incoming message user not configured')

        user = User.objects.get(pk=uid)
        server = Configuration.get_imap_server()
        typ, data = server.search(None, "UnSeen")

        for num in data[0].split():
            #logging.debug("** Processing message %s" % num)
            typ, data = server.fetch(num, "(RFC822)")
            # parsestr() seems to return an email.message?
            msg = Parser().parsestr(data[0][1])
            Note.from_email(msg, user)
            #server.copy(num, 'servo')
            server.store(num, '+FLAGS', '\\Seen')

        server.close()
        server.logout()
Beispiel #8
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid == '':
            raise ValueError('Incoming message user not configured')

        user = User.objects.get(pk=uid)
        server = Configuration.get_imap_server()
        typ, data = server.search(None, "UnSeen")

        for num in data[0].split():
            #logging.debug("** Processing message %s" % num)
            typ, data = server.fetch(num, "(RFC822)")
            # parsestr() seems to return an email.message?
            msg = Parser().parsestr(data[0][1])
            Note.from_email(msg, user)
            #server.copy(num, 'servo')
            server.store(num, '+FLAGS', '\\Seen')

        server.close()
        server.logout()
Beispiel #9
0
def copy(request, pk):
    """Copy a note with its attachments and labels."""
    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():  # also copy the attachments
        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)
Beispiel #10
0
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)
Beispiel #11
0
def index(request):

    if request.method == 'GET':
        reset_session(request)
        
    title = _('Service Order Check-In')    

    dcat = request.GET.get('d', 'mac')
    dmap = {
        'mac'       : _('Mac'),
        'iphone'    : _('iPhone'),
        'ipad'      : _('iPad'),
        'ipod'      : _('iPod'),
        'acc'       : _('Apple Accessory'),
        'beats'     : _('Beats Products'),
        'other'     : _('Other Devices'),
    }

    issue_form = IssueForm()
    device = Device(description=dmap[dcat])

    if dcat in ('mac', 'iphone', 'ipad', 'ipod'):
        sn_form = AppleSerialNumberForm()
    else:
        sn_form = SerialNumberForm()

    tags = Tag.objects.filter(type="order")
    device_form = DeviceForm(instance=device)
    customer_form =  CustomerForm(request)

    if request.method == 'POST':

        sn_form = SerialNumberForm(request.POST)
        issue_form = IssueForm(request.POST, request.FILES)
        customer_form = CustomerForm(request, request.POST)
        device_form = DeviceForm(request.POST, request.FILES)

        if device_form.is_valid() and issue_form.is_valid() and customer_form.is_valid():

            user = User.objects.get(pk=request.session['checkin_user'])

            idata = issue_form.cleaned_data
            ddata = device_form.cleaned_data
            cdata = customer_form.cleaned_data

            customer_id = request.session.get('checkin_customer')
            if customer_id:
                customer = Customer.objects.get(pk=customer_id)
            else:
                customer = Customer()

            name = u'{0} {1}'.format(cdata['fname'], cdata['lname'])
            
            if len(cdata['company']):
                name += ', ' + cdata['company']

            customer.name  = name
            customer.city  = cdata['city']
            customer.phone = cdata['phone']
            customer.email = cdata['email']
            customer.phone = cdata['phone']
            customer.zip_code = cdata['postal_code']
            customer.street_address = cdata['address']
            customer.save()

            order = Order(customer=customer, created_by=user)
            order.location_id = request.session['checkin_location']
            order.checkin_location = cdata['checkin_location']
            order.checkout_location = cdata['checkout_location']

            order.save()
            order.check_in(user)

            try:
                device = get_device(request, ddata['sn'])
            except GsxError as e:
                pass

            device.username = ddata['username']
            device.password = ddata['password']
            device.description = ddata['description']
            device.purchased_on = ddata['purchased_on']
            device.purchase_country = ddata['purchase_country']
            device.save()
            
            order.add_device(device, user)

            note = Note(created_by=user, body=idata['issue_description'])
            note.is_reported = True
            note.order = order
            note.save()

            # Proof of purchase was supplied
            if ddata.get('pop'):
                f = {'content_type': Attachment.get_content_type('note').pk}
                f['object_id'] = note.pk
                a = AttachmentForm(f, {'content': ddata['pop']})
                a.save()

            if request.POST.get('tags'):
                order.set_tags(request.POST.getlist('tags'), request.user)

            # Check checklists early for validation
            answers = []

            # @FIXME: should try to move this to a formset...
            for k, v in request.POST.items():
                if k.startswith('__cl__'):
                    answers.append('- **' + k[6:] + '**: ' + v)

            if len(answers) > 0:
                note = Note(created_by=user, body="\r\n".join(answers))

                if Configuration.true('checkin_report_checklist'):
                    note.is_reported = True

                note.order = order
                note.save()

            # mark down internal notes (only if logged in)
            if len(idata.get('notes')):
                note = Note(created_by=user, body=idata['notes'])
                note.is_reported = False
                note.order = order
                note.save()

            # mark down condition of device
            if len(ddata.get('condition')):
                note = Note(created_by=user, body=ddata['condition'])
                note.is_reported = True
                note.order = order
                note.save()

            # mark down supplied accessories
            if len(ddata.get('accessories')):
                accs = ddata['accessories'].strip().split("\n")
                order.set_accessories(accs, device)

            redirect_to = thanks

            """
            if request.user.is_authenticated():
                if request.user.autoprint:
                    redirect_to = print_confirmation
            """
            return redirect(redirect_to, order.url_code)

    try:
        pk = Configuration.conf('checkin_checklist')
        questions = ChecklistItem.objects.filter(checklist_id=pk)
    except ValueError:
        # Checklists probably not configured
        pass

    if request.GET.get('phone'):

        if not request.user.is_authenticated():
            return

        results = []

        for c in Customer.objects.filter(phone=request.GET['phone']):
            title = '%s - %s' % (c.phone, c.name)
            results.append({'id': c.pk, 'name': c.name, 'title': title})

        return HttpResponse(json.dumps(results), content_type='application/json')

    if request.GET.get('sn'):

        device = Device(sn=request.GET['sn'])
        device.description = _('Other Device')
        device_form = DeviceForm(instance=device)

        try:
            apple_sn_validator(device.sn)
        except Exception as e: # not an Apple serial number
            return render(request, "checkin/device_form.html", locals())

        try:
            device = get_device(request, device.sn)
            device_form = DeviceForm(instance=device)
        except GsxError as e:
            error = e

        return render(request, "checkin/device_form.html", locals())

    return render(request, "checkin/newindex.html", locals())
Beispiel #12
0
def edit(request,
         pk=None,
         order_id=None,
         parent=None,
         recipient=None,
         customer=None):
    """
    Edit a note.

    @FIXME: Should split this up into smaller pieces
    """
    to = []
    order = None
    command = _('Save')
    note = Note(order_id=order_id)
    excluded_emails = note.get_excluded_emails()

    if recipient is not None:
        to.append(recipient)
        command = _('Send')

    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 = get_object_or_404(Customer, 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 as 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 = get_object_or_404(Note, 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 as e:
                        messages.error(request, e)
                        return redirect(note)

                note.attachments.add(*files)

                if form.cleaned_data.get('attach_confirmation'):
                    from servo.views.order import put_on_paper
                    response = put_on_paper(request, note.order_id, fmt='pdf')
                    filename = response.filename
                    content = response.render().content
                    content = ContentFile(content, filename)
                    attachment = Attachment(content=content,
                                            content_object=note)
                    attachment.save()
                    attachment.content.save(filename, content)
                    note.attachments.add(attachment)

                note.save()

                try:
                    msg = note.send_and_save(request.user)
                    messages.success(request, msg)
                except ValueError as e:
                    messages.error(request, e)

            return redirect(note)

    return render(request, "notes/form.html", locals())
Beispiel #13
0
def index(request):
    """
    Render the checkin homepage.

    @FIXME: would be nice to break this into smaller chunks...
    """
    if request.method == 'GET':
        try:
            init_session(request)
        except ConfigurationError as e:
            error = {'message': e}
            return render(request, 'checkin/error.html', error)

    title = _('Service Order Check-In')
    dcat = request.GET.get('d', 'mac')
    dmap = {
        'mac': _('Mac'),
        'iphone': _('iPhone'),
        'ipad': _('iPad'),
        'ipod': _('iPod'),
        'acc': _('Apple Accessory'),
        'beats': _('Beats Products'),
        'other': _('Other Devices'),
    }

    issue_form = IssueForm()
    device = Device(description=dmap[dcat])

    if dcat in ('mac', 'iphone', 'ipad', 'ipod'):
        sn_form = AppleSerialNumberForm()
    else:
        sn_form = SerialNumberForm()

    tags = Tag.objects.filter(type="order")
    device_form = DeviceForm(instance=device)
    customer_form = CustomerForm(request)

    if request.method == 'POST':

        if not request.session.test_cookie_worked():
            error = {
                'message': _('Please enable cookies to use this application.')
            }
            return render(request, 'checkin/error.html', error)
        else:
            request.session.delete_test_cookie()

        sn_form = SerialNumberForm(request.POST)
        issue_form = IssueForm(request.POST, request.FILES)
        customer_form = CustomerForm(request, request.POST)
        device_form = DeviceForm(request.POST, request.FILES)

        if device_form.is_valid() and issue_form.is_valid(
        ) and customer_form.is_valid():

            user = get_object_or_404(User, pk=request.session['checkin_user'])

            idata = issue_form.cleaned_data
            ddata = device_form.cleaned_data
            cdata = customer_form.cleaned_data
            customer_id = request.session.get('checkin_customer')

            if customer_id:
                customer = get_object_or_404(Customer, pk=customer_id)
            else:
                customer = Customer()

            name = u'{0} {1}'.format(cdata['fname'], cdata['lname'])

            if len(cdata['company']):
                name += ', ' + cdata['company']

            customer.name = name
            customer.city = cdata['city']
            customer.phone = cdata['phone']
            customer.email = cdata['email']
            customer.phone = cdata['phone']
            customer.zip_code = cdata['postal_code']
            customer.street_address = cdata['address']
            customer.save()

            order = Order(customer=customer, created_by=user)
            order.location_id = request.session['checkin_location']
            order.checkin_location = cdata['checkin_location']
            order.checkout_location = cdata['checkout_location']

            order.save()
            order.check_in(user)

            try:
                device = get_device(request, ddata['sn'])
            except GsxError as e:
                pass

            device.username = ddata['username']
            device.password = ddata['password']
            device.description = ddata['description']
            device.purchased_on = ddata['purchased_on']
            device.purchase_country = ddata['purchase_country']
            device.save()

            order.add_device(device, user)

            note = Note(created_by=user, body=idata['issue_description'])
            note.is_reported = True
            note.order = order
            note.save()

            # Proof of purchase was supplied
            if ddata.get('pop'):
                f = {'content_type': Attachment.get_content_type('note').pk}
                f['object_id'] = note.pk
                a = AttachmentForm(f, {'content': ddata['pop']})
                a.save()

            if request.POST.get('tags'):
                order.set_tags(request.POST.getlist('tags'), request.user)

            # Check checklists early for validation
            answers = []

            # @FIXME: should try to move this to a formset...
            for k, v in request.POST.items():
                if k.startswith('__cl__'):
                    answers.append('- **' + k[6:] + '**: ' + v)

            if len(answers) > 0:
                note = Note(created_by=user, body="\r\n".join(answers))

                if Configuration.true('checkin_report_checklist'):
                    note.is_reported = True

                note.order = order
                note.save()

            # mark down internal notes (only if logged in)
            if len(idata.get('notes')):
                note = Note(created_by=user, body=idata['notes'])
                note.is_reported = False
                note.order = order
                note.save()

            # mark down condition of device
            if len(ddata.get('condition')):
                note = Note(created_by=user, body=ddata['condition'])
                note.is_reported = True
                note.order = order
                note.save()

            # mark down supplied accessories
            if len(ddata.get('accessories')):
                accs = ddata['accessories'].strip().split("\n")
                order.set_accessories(accs, device)

            redirect_to = thanks
            """
            if request.user.is_authenticated():
                if request.user.autoprint:
                    redirect_to = print_confirmation
            """
            return redirect(redirect_to, order.url_code)

    try:
        pk = Configuration.conf('checkin_checklist')
        questions = ChecklistItem.objects.filter(checklist_id=pk)
    except ValueError:
        # Checklists probably not configured
        pass

    if request.GET.get('phone'):
        return find_customer(request, request.GET['phone'])

    if request.GET.get('sn'):
        return find_device(request)

    return render(request, "checkin/newindex.html", locals())
Beispiel #14
0
def apply_rules(event):
    """
    Applies configured rules

    event is the Event object that was triggered
    """
    counter = 0
    rules = cache.get('rules', get_rules())
    order = event.content_object
    user  = event.triggered_by

    for r in rules:
        match = r.get('match', event.description)

        if (r['event'] == event.action and match == event.description):
            if isinstance(r['data'], dict):
                tpl_id = r['data']['template']
                r['data'] = Template.objects.get(pk=tpl_id).render(order)
            else:
                r['data'] = Template(content=r['data']).render(order)

            if r['action'] == "set_queue":
                order.set_queue(r['data'], user)

            if r['action'] == "set_priority":
                pass

            if r['action'] == "send_email":
                try:
                    email = order.customer.valid_email()
                except Exception:
                    continue # skip customers w/o valid emails
                
                note = Note(order=order, created_by=user)
                note.body = r['data']
                note.recipient = email
                note.render_subject({'note': note})
                note.save()

                try:
                    note.send_mail(user)
                except ValueError as e:
                    print('Sending email failed (%s)' % e)

            if r['action'] == "send_sms":
                number = 0

                try:
                    number = order.customer.get_standard_phone()
                except Exception:
                    continue # skip customers w/o valid phone numbers

                note = Note(order=order, created_by=user)

                note.body = r['data']
                note.save()

                try:
                    note.send_sms(number, user)
                except ValueError as e:
                    print('Sending SMS to %s failed (%s)' % (number, e))

            counter += 1

    return '%d/%d rules processed' % (counter, len(rules))
Beispiel #15
0
def batch_process(user, data):
    """
    /orders/batch
    """
    processed = 0
    orders = data['orders'].strip().split("\r\n")
    
    for o in orders:
        try:
            order = Order.objects.get(code=o)
        except Exception as e:
            continue

        if data['status'] and order.queue:
            status = order.queue.queuestatus_set.get(status_id=data['status'])
            order.set_status(status, user)
        
        if data['queue']:
            order.set_queue(data['queue'], user)

        if len(data['sms']) > 0:
            try:
                number = order.customer.get_standard_phone()
                note = Note(order=order, created_by=user, body=data['sms'])
                note.render_body({'order': order})
                note.save()

                try:
                    note.send_sms(number, user)
                except Exception as e:
                    note.delete()
                    print("Failed to send SMS to: %s" % number)

            except AttributeError as e: # customer has no phone number
                continue

        if len(data['email']) > 0:
            note = Note(order=order, created_by=user, body=data['email'])
            note.sender = user.email

            try:
                note.recipient = order.customer.email
                note.render_subject({'note': note})
                note.render_body({'order': order})
                note.save()
                note.send_mail(user)
            except Exception as e:
                # customer has no email address or some other error...
                pass

        if len(data['note']) > 0:
            note = Note(order=order, created_by=user, body=data['note'])
            note.render_body({'order': order})
            note.save()

        processed += 1

    return '%d/%d orders processed' % (processed, len(orders))
Beispiel #16
0
def edit(request, pk=None, order_id=None, parent=None, recipient=None,
         customer=None):
    """
    Edits a note
    @FIXME: Should split this up into smaller pieces
    """
    to = []
    order = None
    command = _('Save')
    note = Note(order_id=order_id)
    excluded_emails = note.get_excluded_emails()

    if recipient is not None:
        to.append(recipient)
        command = _('Send')

    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 = get_object_or_404(Customer, 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 as 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 = get_object_or_404(Note, 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 as 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 as e:
                    messages.error(request, e)

            return redirect(note)

    return render(request, "notes/form.html", locals())