Beispiel #1
0
def banktransactions_match(request, transid):
    authenticate_backend_group(request, 'Invoice managers')

    trans = get_object_or_404(PendingBankTransaction, pk=transid)
    invoices = Invoice.objects.filter(finalized=True, paidat__isnull=True, deleted=False).order_by('invoicedate')

    def _match_invoice(i):
        matchinfos = []
        if i.total_amount == trans.amount:
            matchinfos.append('Amount matches exact')
        if i.payment_reference in trans.transtext.replace(' ', ''):
            matchinfos.append('Payment reference found')

        return {
            'matchinfo': ",\n".join(matchinfos),
            'matchlabel': len(matchinfos) > 0 and 'success' or '',
            'i': i,
        }

    im = map(_match_invoice, invoices)

    pm = trans.method.get_implementation()
    matchers = PendingBankMatcher.objects.filter(foraccount__num=pm.config('bankaccount'), amount=trans.amount)

    return render(request, 'invoices/banktransactions_match.html', {
        'transaction': trans,
        'invoice_matchinfo': im,
        'matchers': matchers,
        'topadmin': 'Invoices',
        'breadcrumbs': [('/admin/invoices/banktransactions/', 'Pending bank transactions'), ],
        'helplink': 'payment',
    })
Beispiel #2
0
def new(request, year):
    authenticate_backend_group(request, 'Accounting managers')

    year = int(year)

    # Default the date to the same date as the last entry for this year,
    # provided one exists. Otherwise, just the start of the year.
    try:
        lastentry = JournalEntry.objects.filter(year=year).order_by('-date')[0]
        d = lastentry.date
    except IndexError:
        d = date(year, 1, 1)

    year = get_object_or_404(Year, year=year)
    highseq = JournalEntry.objects.filter(year=year).aggregate(
        Max('seq'))['seq__max']
    if highseq is None:
        highseq = 0
    entry = JournalEntry(year=year, seq=highseq + 1, date=d, closed=False)
    entry.save()

    # Disable any search query to make sure we can actually see
    # the record we've just created.
    _setup_search(request, '')

    return HttpResponseRedirect('/accounting/e/%s/' % entry.pk)
Beispiel #3
0
def emailinvoice(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')

    if request.method != 'POST':
        raise HttpResponse('Must be POST', status=401)

    if 'reason' not in request.POST:
        return HttpResponse('Reason is missing!', status=401)
    if request.POST['reason'] not in ('initial', 'reminder'):
        return HttpResponse('Invalid reason given!', status=401)

    invoice = get_object_or_404(Invoice, pk=invoicenum)

    if not invoice.finalized:
        return HttpResponse("Not finalized!", status=401)

    # Ok, it seems we're good to go...
    wrapper = InvoiceWrapper(invoice)
    if request.POST['reason'] == 'initial':
        wrapper.email_invoice()
    elif request.POST['reason'] == 'reminder':
        wrapper.email_reminder()
    else:
        raise Exception("Cannot happen")

    return HttpResponse("OK")
Beispiel #4
0
def search(request):
    authenticate_backend_group(request, 'Invoice managers')

    term = request.GET['term']
    upstream = request.GET.get('upstream', False)

    users = User.objects.filter(
        Q(username__icontains=term) |
        Q(first_name__icontains=term) |
        Q(last_name__icontains=term) |
        Q(email__icontains=term)
        )
    if users:
        return HttpResponse(json.dumps([{'ui': u.id, 'u': u.username, 'n': u.first_name + ' ' + u.last_name, 'e': u.email} for u in users]), content_type='application/json')

    if not upstream:
        return HttpResponse('[]', content_type='application/json')

    # Perform upstream search
    users = user_search(term)
    # All users need a negative id so we can differentiate them
    for n in range(0, len(users)):
        users[n]['i'] = -1 - n
    return HttpResponse(json.dumps([{'ui': u['i'],
                                     'u': u['u'],
                                     'n': u['f'] + ' ' + u['l'],
                                     'e': u['e'],
                                     } for u in users]), content_type='application/json')
Beispiel #5
0
def _homeview(request, invoice_objects, unpaid=False, pending=False, deleted=False, paid=False, searchterm=None):
    # Utility function for all main invoice views, so make the shared permissions
    # check here.
    authenticate_backend_group(request, 'Invoice managers')

    # Add info about refunds to all invoices
    invoice_objects = invoice_objects.extra(select={
        'has_refund': 'EXISTS (SELECT 1 FROM invoices_invoicerefund r WHERE r.invoice_id=invoices_invoice.id)',
    })

    # Render a list of all invoices
    (invoices, paginator, page_range) = simple_pagination(request, invoice_objects, 50)

    has_pending = Invoice.objects.filter(finalized=False).exists()
    has_unpaid = Invoice.objects.filter(finalized=True, paidat__isnull=False).exists()
    return render(request, 'invoices/home.html', {
        'invoices': invoices,
        'paid': paid,
        'unpaid': unpaid,
        'pending': pending,
        'deleted': deleted,
        'has_pending': has_pending,
        'has_unpaid': has_unpaid,
        'searchterm': searchterm,
        'page_range': page_range,
        'breadcrumbs': [('/invoiceadmin/', 'Invoices'), ],
        'helplink': 'payment',
    })
Beispiel #6
0
def bankfile_transaction_methodchoice(request):
    authenticate_backend_group(request, 'Invoice managers')

    methods = InvoicePaymentMethod.objects.filter(
        config__has_key='file_upload_interval').order_by('internaldescription')
    if not methods:
        # Should never happen since the button is only visible if they exist
        messages.error(request, "No managed bank providers configured!")
        return HttpResponseRedirect("/admin/")

    if len(methods) == 1:
        # Only one, so no need for prompt
        return HttpResponseRedirect("{}/".format(methods[0].id))

    if request.method == 'POST':
        form = BankfilePaymentMethodChoiceForm(methods=methods,
                                               data=request.POST)
        if form.is_valid():
            return HttpResponseRedirect("{}/".format(
                form.cleaned_data['paymentmethod'].id))
    else:
        form = BankfilePaymentMethodChoiceForm(methods=methods)

    return render(
        request, 'confreg/admin_backend_form.html', {
            'basetemplate': 'adm/admin_base.html',
            'form': form,
            'whatverb': 'View',
            'what': 'bank transactions',
            'savebutton': 'View transactions',
            'cancelurl': '/admin/',
            'cancelname': 'Back',
            'topadmin': 'Invoices',
            'helplink': 'payment',
        })
Beispiel #7
0
def meeting_log(request, meetingid):
    authenticate_backend_group(request, 'Membership administrators')

    meeting = get_object_or_404(Meeting, pk=meetingid)

    if meeting.meetingtype != MeetingType.WEB:
        messages.warning(request,
                         "Meeting log is only available for web meetings")
        return HttpResponseRedirect("../")

    log = MeetingMessageLog.objects.select_related('sender').only(
        't', 'message', 'sender__fullname').filter(meeting=meeting)

    if request.method == 'POST':
        with transaction.atomic():
            curs = connection.cursor()
            curs.execute(
                """DELETE FROM membership_meetingmessagelog l WHERE meeting_id=%(meetingid)s AND (
 t < (SELECT min(t) FROM membership_meetingmessagelog l2 WHERE l2.meeting_id=%(meetingid)s AND l2.message='This meeting is now open.')
OR
 t > (SELECT max(t) FROM membership_meetingmessagelog l3 WHERE l3.meeting_id=%(meetingid)s AND l3.message='This meeting is now finished.')
)""", {'meetingid': meetingid})
            messages.info(
                request, 'Removed {} entries from meeting {}.'.format(
                    curs.rowcount, meetingid))
            return HttpResponseRedirect(".")

    if request.GET.get('format', None) == 'csv':
        response = HttpResponse(content_type='text/csv; charset=utf8')
        response[
            'Content-Disposition'] = 'attachment;filename={} log.csv'.format(
                meeting.name)
        c = csv.writer(response, delimiter=';')
        c.writerow(['Time', 'Sender', 'Text'])
        for l in log:
            c.writerow([l.t, l.sender.fullname if l.sender else '', l.message])
        return response
    else:
        log = list(
            log.extra(
                select={
                    'inmeeting':
                    "CASE WHEN t < (SELECT min(t) FROM membership_meetingmessagelog l2 WHERE l2.meeting_id=membership_meetingmessagelog.meeting_id AND message='This meeting is now open.') OR t > (SELECT max(t) FROM membership_meetingmessagelog l3 WHERE l3.meeting_id=membership_meetingmessagelog.meeting_id AND message='This meeting is now finished.') THEN false ELSE true END",
                }))
        return render(
            request, 'membership/meeting_log.html', {
                'meeting':
                meeting,
                'log':
                log,
                'numextra':
                sum(0 if l.inmeeting else 1 for l in log),
                'topadmin':
                'Membership',
                'breadcrumbs': (
                    ('/admin/membership/meetings/', 'Meetings'),
                    ('/admin/membership/meetings/{}/'.format(
                        meeting.pk), meeting.name),
                ),
            })
Beispiel #8
0
def sendmail(request):
    authenticate_backend_group(request, 'Membership administrators')

    if request.method == 'POST':
        idlist = list(map(int, request.POST['idlist'].split(',')))
    else:
        idlist = list(map(int, request.GET['idlist'].split(',')))

    cfg = get_config()

    recipients = Member.objects.filter(pk__in=idlist)

    initial = {
        '_from':
        '{0} <{1}>'.format(settings.ORG_NAME, cfg.sender_email),
        'recipients':
        escape(", ".join([
            '{0} <{1}>'.format(x.fullname, x.user.email) for x in recipients
        ])),
        'idlist':
        ",".join(map(str, idlist)),
    }

    if request.method == 'POST':
        p = request.POST.copy()
        p['recipients'] = initial['recipients']
        form = BackendMemberSendEmailForm(data=p, initial=initial)
        if form.is_valid():
            with transaction.atomic():
                for r in recipients:
                    msgtxt = "{0}\n\n-- \nThis message was sent to members of {1}\n".format(
                        form.cleaned_data['message'], settings.ORG_NAME)
                    send_simple_mail(
                        cfg.sender_email,
                        r.user.email,
                        form.cleaned_data['subject'],
                        msgtxt,
                        sendername=settings.ORG_NAME,
                        receivername=r.fullname,
                    )
                messages.info(request,
                              "Email sent to %s attendees" % len(recipients))

            return HttpResponseRedirect("../")
    else:
        form = BackendMemberSendEmailForm(initial=initial)

    return render(
        request, 'confreg/admin_backend_form.html', {
            'basetemplate': 'adm/admin_base.html',
            'form': form,
            'what': 'new email',
            'savebutton': 'Send email',
            'cancelurl': '../',
            'breadcrumbs': [
                ('../', 'Members'),
            ],
        })
Beispiel #9
0
def viewreceipt(request, invoiceid):
    invoice = get_object_or_404(Invoice, pk=invoiceid)
    if invoice.recipient_user != request.user:
        # End users can only view their own invoices, but invoice managers can view all
        authenticate_backend_group(request, 'Invoice managers')

    r = HttpResponse(content_type='application/pdf')
    r.write(base64.b64decode(invoice.pdf_receipt))
    return r
Beispiel #10
0
def viewinvoice(request, invoiceid):
    invoice = get_object_or_404(Invoice, pk=invoiceid, deleted=False, finalized=True)
    if invoice.recipient_user != request.user:
        # End users can only view their own invoices, but invoice managers can view all
        authenticate_backend_group(request, 'Invoice managers')

    return render(request, 'invoices/userinvoice.html', {
        'invoice': InvoicePresentationWrapper(invoice, "%s/invoices/%s/" % (settings.SITEBASE, invoice.pk)),
    })
Beispiel #11
0
def invoicepayment(request, methodid, invoiceid):
    invoice = get_object_or_404(Invoice,
                                pk=invoiceid,
                                deleted=False,
                                finalized=True)
    if invoice.recipient_user != request.user:
        authenticate_backend_group(request, 'Invoice managers')

    return _invoice_payment(request, methodid, invoice)
Beispiel #12
0
def refundinvoice(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')

    invoice = get_object_or_404(Invoice, pk=invoicenum)

    if request.method == 'POST':
        form = RefundForm(data=request.POST, invoice=invoice)
        if form.is_valid():
            # Do some sanity checking
            if form.cleaned_data['vatrate']:
                vatamount = (Decimal(form.cleaned_data['amount']) *
                             form.cleaned_data['vatrate'].vatpercent /
                             Decimal(100)).quantize(Decimal('0.01'))
                if vatamount > invoice.total_refunds['remaining']['vatamount']:
                    messages.error(request,
                                   "Unable to refund, VAT amount mismatch!")
                    return HttpResponseRedirect('.')
            else:
                vatamount = 0

            mgr = InvoiceManager()
            r = mgr.refund_invoice(
                invoice,
                form.cleaned_data['reason'],
                Decimal(form.cleaned_data['amount']),
                vatamount,
                form.cleaned_data['vatrate'],
            )
            if invoice.can_autorefund:
                messages.info(request, "Refund initiated.")
            else:
                messages.info(request, "Refund flagged.")

            return HttpResponseRedirect(".")
    else:
        form = RefundForm(invoice=invoice)

    # Check if all invoicerows have the same VAT rate (NULL or specified)
    vinfo = invoice.invoicerow_set.all().aggregate(n=Count('vatrate',
                                                           distinct=True),
                                                   v=Max('vatrate'))

    return render(
        request, 'invoices/refundform.html', {
            'form':
            form,
            'invoice':
            invoice,
            'breadcrumbs': [
                ('/invoiceadmin/', 'Invoices'),
                ('/invoiceadmin/{0}/'.format(
                    invoice.pk), 'Invoice #{0}'.format(invoice.pk)),
            ],
            'helplink':
            'payment',
        })
Beispiel #13
0
def previewinvoice(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')

    invoice = get_object_or_404(Invoice, pk=invoicenum)

    # We assume there is no PDF yet
    wrapper = InvoiceWrapper(invoice)
    r = HttpResponse(content_type='application/pdf')
    r.write(wrapper.render_pdf_invoice(True))
    return r
Beispiel #14
0
def importuser(request):
    authenticate_backend_group(request, 'Invoice managers')

    uid = request.POST['uid']
    try:
        user_import(uid)
    except Exception as e:
        return HttpResponse('%s' % e, content_type='text/plain')

    return HttpResponse('OK', content_type='text/plain')
Beispiel #15
0
def banktransactions_match_multiple(request, transid):
    authenticate_backend_group(request, 'Invoice managers')

    trans = get_object_or_404(PendingBankTransaction, pk=transid)

    pm = trans.method.get_implementation()

    invoices = [
        get_object_or_404(Invoice, pk=invoiceid)
        for invoiceid in request.GET.getlist('invoiceid')
    ]
    if not invoices:
        invoices = [
            get_object_or_404(Invoice, pk=invoiceid)
            for invoiceid in request.POST.get('invoiceidlist').split(',')
        ]

    if len(invoices) == 0:
        raise Http404("No invoices")

    if request.method == 'POST':
        r = _flag_invoices(request, trans, invoices, pm, None)
        if r:
            return HttpResponseRedirect("/admin/invoices/banktransactions/")
        else:
            return HttpResponseRedirect(".")

    total_amount = sum([i.total_amount for i in invoices])

    return render(
        request, 'invoices/banktransactions_match_invoice.html', {
            'transaction':
            trans,
            'invoices':
            invoices,
            'topadmin':
            'Invoices',
            'match': {
                'amountdiff':
                total_amount - trans.amount,
                'absdiff':
                abs(total_amount - trans.amount),
                'percentdiff':
                (abs(total_amount - trans.amount) / total_amount) * 100,
            },
            'cantmatch': (total_amount != trans.amount),
            'breadcrumbs': [
                ('/admin/invoices/banktransactions/',
                 'Pending bank transactions'),
                ('/admin/invoices/banktransactions/{0}/'.format(
                    trans.id), 'Transaction'),
            ],
            'helplink':
            'payment',
        })
Beispiel #16
0
def banktransactions_match_invoice(request, transid, invoiceid):
    authenticate_backend_group(request, 'Invoice managers')

    trans = get_object_or_404(PendingBankTransaction, pk=transid)
    invoice = get_object_or_404(Invoice, pk=invoiceid)

    pm = trans.method.get_implementation()

    if request.method == 'POST':
        if pm.config('feeaccount'):
            fee_account = Account.objects.get(num=pm.config('feeaccount'))
        else:
            fee_account = get_object_or_404(Account, num=request.POST['account'])

        r = _flag_invoices(request,
                           trans,
                           [invoice, ],
                           pm,
                           fee_account)

        if r:
            return HttpResponseRedirect("/admin/invoices/banktransactions/")
        else:
            return HttpResponseRedirect(".")

    # Generate the form

    if pm.config('feeaccount'):
        fee_account = Account.objects.get(num=pm.config('feeaccount'))
        accounts = []
    else:
        fee_account = None
        accounts = get_account_choices()

    return render(request, 'invoices/banktransactions_match_invoice.html', {
        'transaction': trans,
        'invoices': [invoice, ],
        'topadmin': 'Invoices',
        'fee_account': fee_account,
        'accounts': accounts,
        'match': {
            'amountdiff': invoice.total_amount - trans.amount,
            'absdiff': abs(invoice.total_amount - trans.amount),
            'percentdiff': (abs(invoice.total_amount - trans.amount) / invoice.total_amount) * 100,
            'found_ref': invoice.payment_reference in trans.transtext,
            'found_id': str(invoice.id) in trans.transtext,
            'highlight_ref': re.sub('({0})'.format(invoice.payment_reference), r'<strong>\1</strong>', escape(trans.transtext)),
            'highlight_id': re.sub('({0})'.format(invoice.id), r'<strong>\1</strong>', escape(trans.transtext)),
        },
        'breadcrumbs': [
            ('/admin/invoices/banktransactions/', 'Pending bank transactions'),
            ('/admin/invoices/banktransactions/{0}/'.format(trans.id), 'Transaction'),
        ],
        'helplink': 'payment',
    })
Beispiel #17
0
def bankfile_transactions(request, methodid):
    authenticate_backend_group(request, 'Invoice managers')

    method = get_object_or_404(InvoicePaymentMethod, pk=methodid)

    # Needed for backlinks
    methodcount = InvoicePaymentMethod.objects.filter(
        config__has_key='file_upload_interval').count()

    backbutton = "../"
    breadlabel = "Bank transactions"

    if methodcount == 1:
        # If there is only one method, we have to return all the way back to the index page, or we'll
        # just get redirected back to ourselves.
        backbutton = "/admin/"

    q = Q(method=method)
    if 'file' in request.GET:
        q = q & Q(fromfile=get_int_or_error(request.GET, 'file'))
        backbutton = "../../"
        breadlabel = "Bankfiles"

    allrows = BankStatementRow.objects.filter(q).order_by('-date', 'id')
    (rows, paginator, page_range) = simple_pagination(request, allrows, 50)

    extrakeys = set()
    hasvaluefor = {
        'uniqueid': False,
        'balance': False,
    }
    for r in rows:
        extrakeys.update(r.other.keys())
        for k in hasvaluefor.keys():
            if getattr(r, k, None):
                hasvaluefor[k] = True

    params = request.GET.copy()
    if 'page' in params:
        del params['page']

    return render(
        request, 'invoices/bankfile_transactions.html', {
            'rows': rows,
            'extrakeys': extrakeys,
            'hasvaluefor': hasvaluefor,
            'page_range': page_range,
            'topadmin': 'Invoices',
            'helplink': 'payment',
            'requestparams': params.urlencode(),
            'breadcrumbs': [
                (backbutton, breadlabel),
            ],
            'backbutton': backbutton,
        })
Beispiel #18
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',
        })
Beispiel #19
0
def edit_meeting(request, rest):
    authenticate_backend_group(request, 'Membership administrators')

    return backend_list_editor(request,
                               None,
                               BackendMeetingForm,
                               rest,
                               bypass_conference_filter=True,
                               topadmin='Membership',
                               return_url='/admin/',
    )
Beispiel #20
0
def edit_vatvalidationcache(request, rest):
    authenticate_backend_group(request, 'Invoice managers')

    return backend_list_editor(request,
                               None,
                               BackendVatValidationCacheForm,
                               rest,
                               bypass_conference_filter=True,
                               topadmin='Invoices',
                               return_url='/admin/',
    )
Beispiel #21
0
def bankfiles(request):
    authenticate_backend_group(request, 'Invoice managers')

    if request.method == 'POST':
        # Uploading a file!
        method = get_object_or_404(InvoicePaymentMethod,
                                   active=True,
                                   config__has_key='file_upload_interval',
                                   id=get_int_or_error(request.POST, 'id'))
        if 'f' not in request.FILES:
            messages.error(request, "No file included in upload")
        elif request.FILES['f'].size < 1:
            messages.error(request, "Uploaded file is empty")
        else:
            f = request.FILES['f']
            impl = method.get_implementation()

            try:
                (contents, numrows, numtrans,
                 numpending) = impl.parse_uploaded_file(f)
                BankFileUpload(
                    method=method,
                    uploadby=request.user.username,
                    name=f.name,
                    textcontents=contents,
                    parsedrows=numrows,
                    newtrans=numtrans,
                    newpending=numpending,
                ).save()
                messages.info(
                    request,
                    "File uploaded. {} rows parsed, {} transactions stored, resulting in {} pending transactions."
                    .format(numrows, numtrans, numpending))
                return HttpResponseRedirect('.')
            except Exception as e:
                messages.error(request, "Error uploading file: {}".format(e))

    methods = InvoicePaymentMethod.objects.filter(
        active=True, config__has_key='file_upload_interval').annotate(
            latest_file=Max('bankfileupload__created'))
    file_objects = BankFileUpload.objects.select_related(
        'method').all().order_by('-created')[:1000]
    (files, paginator, page_range) = simple_pagination(request, file_objects,
                                                       50)

    return render(
        request, 'invoices/bankfiles.html', {
            'files': files,
            'page_range': page_range,
            'methods': methods,
            'topadmin': 'Invoices',
            'helplink': 'payment',
        })
def edit_object(request, rest):
    authenticate_backend_group(request, 'Accounting managers')

    return backend_list_editor(
        request,
        None,
        BackendObjectForm,
        rest,
        bypass_conference_filter=True,
        topadmin='Accounting',
        return_url='/admin/',
    )
def edit_election(request, rest):
    authenticate_backend_group(request, 'Election administrators')

    return backend_list_editor(
        request,
        None,
        BackendElectionForm,
        rest,
        bypass_conference_filter=True,
        topadmin='Elections',
        return_url='/admin/',
    )
Beispiel #24
0
def edit_news(request, rest):
    authenticate_backend_group(request, 'News administrators')

    return backend_list_editor(
        request,
        None,
        BackendNewsForm,
        rest,
        bypass_conference_filter=True,
        topadmin='News',
        return_url='/admin/',
    )
Beispiel #25
0
def member_email_list(request):
    authenticate_backend_group(request, 'Membership administrators')

    return render(
        request, 'membership/admin_email_list.html', {
            'mails':
            MemberMail.objects.only('sentat', 'subject').order_by('-sentat'),
            'helplink':
            'membership',
            'breadcrumbs': [
                ('../../', 'Membership'),
            ],
        })
def edit_postqueue(request, rest):
    authenticate_backend_group(request, 'News administrators')

    return backend_list_editor(
        request,
        None,
        BackendPostQueueForm,
        rest,
        bypass_conference_filter=True,
        object_queryset=ConferenceTweetQueue.objects.filter(
            conference__isnull=True),
        topadmin='News',
        return_url='/admin/',
    )
Beispiel #27
0
def refunds(request):
    authenticate_backend_group(request, 'Invoice managers')

    refund_objects = InvoiceRefund.objects.\
        select_related('invoice', 'invoice__paidusing').\
        only('id', 'invoice_id', 'completed', 'issued', 'registered', 'reason', 'invoice__paidusing__internaldescription').\
        order_by(F('completed').desc(nulls_first=True), F('issued').desc(nulls_first=True), F('registered').desc())

    (refunds, paginator, page_range) = simple_pagination(request, refund_objects, 20)

    return render(request, 'invoices/refunds.html', {
        'refunds': refunds,
        'page_range': page_range,
        'breadcrumbs': [('/admin/invoices/refunds/', 'Refunds'), ],
        'helplink': 'payment',
    })
Beispiel #28
0
def extend_cancel(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')

    invoice = get_object_or_404(Invoice, pk=invoicenum)

    try:
        days = int(request.GET.get('days', 5))
    except Exception as e:
        days = 5

    invoice.canceltime += timedelta(days=days)
    invoice.save()

    InvoiceHistory(invoice=invoice, txt='Extended autocancel by {0} days to {1}'.format(days, invoice.canceltime)).save()

    return HttpResponseRedirect("/invoiceadmin/%s/" % invoice.id)
Beispiel #29
0
def cancelinvoice(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')

    invoice = get_object_or_404(Invoice, pk=invoicenum)

    reason = request.POST.get('reason', '')
    if not reason:
        return HttpResponseForbidden("Can't cancel an invoice without a reason!")

    manager = InvoiceManager()
    try:
        manager.cancel_invoice(invoice, reason, request.user.username)
    except Exception as ex:
        messages.warning(request, "Failed to cancel: %s" % ex)

    return HttpResponseRedirect("/invoiceadmin/%s/" % invoice.id)
def accountstructure(request):
    authenticate_backend_group(request, 'Accounting managers')

    accounts = exec_to_dict(
        """SELECT ac.id AS classid, ac.name AS classname, ac.inbalance,
ag.id AS groupid, ag.name AS groupname,
a.id AS accountid, a.num AS accountnum, a.name AS accountname
FROM accounting_accountclass ac
INNER JOIN accounting_accountgroup ag ON ag.accountclass_id=ac.id
INNER JOIN accounting_account a ON a.group_id=ag.id
ORDER BY a.num""")

    return render(request, 'accounting/structure.html', {
        'accounts': accounts,
        'topadmin': 'Accounting',
        'helplink': 'accounting',
    })