Ejemplo n.º 1
0
def banktransactions_match_matcher(request, transid, matcherid):
    authenticate_backend_group(request, 'Invoice managers')

    trans = get_object_or_404(PendingBankTransaction, pk=transid)
    matcher = get_object_or_404(PendingBankMatcher, pk=matcherid)

    pm = trans.method.get_implementation()

    if request.method == 'POST':
        if trans.amount != matcher.amount:
            # Should not happen, but let's make sure
            messages.error(request, "Amount mismatch")
            return HttpResponseRedirect(".")

        if matcher.journalentry.closed:
            messages.error(request, "Accounting entry already closed")
            return HttpResponseRedirect(".")

        # The whole point of what we do here is to ignore the text of the match,
        # so once the amount is correct, we just complete it.
        matcher.journalentry.closed = True
        matcher.journalentry.save()

        InvoiceLog(
            message=
            "Manually matched bank transaction of {0}{1} with text {2} to journal entry {3}."
            .format(
                trans.amount,
                settings.CURRENCY_ABBREV,
                trans.transtext,
                matcher.journalentry,
            )).save()

        # Remove both the pending transaction *and* the pending matcher
        trans.delete()
        matcher.delete()
        return HttpResponseRedirect("../../")

    return render(
        request, 'invoices/banktransactions_match_matcher.html', {
            'transaction':
            trans,
            'matcher':
            matcher,
            'topadmin':
            'Invoices',
            'breadcrumbs': [
                ('/admin/invoices/banktransactions/',
                 'Pending bank transactions'),
                ('/admin/invoices/banktransactions/{0}/'.format(
                    trans.id), 'Transaction'),
            ],
            'helplink':
            'payment',
        })
Ejemplo n.º 2
0
def _flag_invoices(request, trans, invoices, pm, fee_account):
    manager = InvoiceManager()
    invoicelog = []

    transaction.set_autocommit(False)

    def invoicelogger(msg):
        invoicelog.append(msg)

    if len(invoices) == 1:
        fee = invoices[0].total_amount - trans.amount  # Calculated fee
    else:
        # There can be no fees when using multiple invoices, so ensure that
        if sum([i.total_amount for i in invoices]) != trans.amount:
            raise Exception("Fees not supported for multi-invoice flagging")
        fee = 0

    for invoice in invoices:
        (status, _invoice,
         _processor) = manager.process_incoming_payment_for_invoice(
             invoice, invoice.total_amount,
             "Bank transfer from {0} with id {1}, manually matched".format(
                 trans.method.internaldescription,
                 trans.methodidentifier), fee, pm.config('bankaccount'),
             fee_account and fee_account.num, [], invoicelogger, trans.method)

        if status != manager.RESULT_OK:
            messages.error(request, "Failed to run invoice processor:")
            for m in invoicelog:
                messages.warning(request, m)

            # Roll back any changes so far
            transaction.rollback()

            return False

        BankTransferFees(invoice=invoice, fee=fee).save()

        InvoiceLog(
            message=
            "Manually matched invoice {0} for {1} {2}, bank transaction {3} {2}, fees {4}"
            .format(
                invoice.id,
                invoice.total_amount,
                settings.CURRENCY_ABBREV,
                trans.amount,
                fee,
            )).save()

    # Remove the pending transaction
    trans.delete()

    transaction.commit()

    return True
Ejemplo n.º 3
0
def banktransactions(request):
    authenticate_backend_group(request, 'Invoice managers')

    if request.method == 'POST':
        if 'submit' not in request.POST:
            return HttpResponseRedirect(".")

        if 'transid' in request.POST:
            trans = get_object_or_404(PendingBankTransaction,
                                      id=get_int_or_error(
                                          request.POST, 'transid'))

            if request.POST['submit'] == 'Discard':
                InvoiceLog(
                    message="Discarded bank transaction of {0}{1} with text {2}"
                    .format(trans.amount, settings.CURRENCY_ABBREV,
                            trans.transtext)).save()

                trans.delete()

                messages.info(request, "Transaction discarded")
                return HttpResponseRedirect(".")
            elif request.POST['submit'] == 'Create accounting record':
                pm = trans.method.get_implementation()

                accrows = [
                    (pm.config('bankaccount'), trans.transtext, trans.amount,
                     None),
                ]
                entry = create_accounting_entry(date.today(), accrows, True)

                InvoiceLog(
                    message=
                    "Created manual accounting entry for transaction of {0}{1} with text {2}"
                    .format(trans.amount, settings.CURRENCY_ABBREV,
                            trans.transtext)).save()

                trans.delete()

                return HttpResponseRedirect("/accounting/e/{0}/".format(
                    entry.id))
            elif request.POST['submit'] == 'Return to sender':
                pm = trans.method.get_implementation()

                pm.return_payment(trans)

                InvoiceLog(
                    message=
                    "Scheduled transaction '{0}' ({1}{2}) for return to sender using {3}"
                    .format(trans.transtext, trans.amount,
                            settings.CURRENCY_ABBREV,
                            trans.method.internaldescription)).save()
                trans.delete()

                return HttpResponseRedirect(".")
            else:
                raise Http404("Invalid request")
        elif 'matcherid' in request.POST:
            matcher = get_object_or_404(PendingBankMatcher,
                                        pk=get_int_or_error(
                                            request.POST, 'matcherid'))
            if request.POST['submit'] == 'Discard':
                InvoiceLog(
                    message="Discarded pending bank matcher {0} for {1} {2}".
                    format(matcher.pattern, matcher.amount,
                           settings.CURRENCY_ABBREV)).save()

                matcher.delete()

                messages.info(request, "Matcher discarded")
                return HttpResponseRedirect(".")
            else:
                raise Http404("Invalid request")
        else:
            raise Http404("Invalid request")

    pendingtransactions = PendingBankTransaction.objects.order_by('created')
    pendingmatchers = PendingBankMatcher.objects.order_by('created')

    return render(
        request, 'invoices/banktransactions.html', {
            'transactions': pendingtransactions,
            'matchers': pendingmatchers,
            'topadmin': 'Invoices',
            'helplink': 'payment',
        })