Added payments report

This commit is contained in:
Marc Aymerich 2015-06-03 12:49:30 +00:00
parent a17e8d9b8c
commit 3fe01a834b
9 changed files with 97 additions and 22 deletions

View File

@ -5,7 +5,7 @@ from functools import wraps
from django.conf import settings
from django.contrib import admin
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, NoReverseMatch
from django.db import models
from django.shortcuts import redirect
import importlib
@ -107,12 +107,16 @@ def admin_link(*args, **kwargs):
return '---'
if not getattr(obj, 'pk', None):
return '---'
url = change_url(obj)
display = kwargs.get('display')
if display:
display = getattr(obj, display, 'merda')
else:
display = obj
try:
url = change_url(obj)
except NoReverseMatch:
# Does not has admin
return str(display)
extra = ''
if kwargs['popup']:
extra = 'onclick="return showAddAnotherPopup(this);"'

View File

@ -1,6 +1,6 @@
import io
import zipfile
from datetime import date
from io import StringIO
from django.contrib import messages
from django.contrib.admin import helpers
@ -22,17 +22,17 @@ from .helpers import validate_contact
def download_bills(modeladmin, request, queryset):
if queryset.count() > 1:
stringio = StringIO()
archive = zipfile.ZipFile(stringio, 'w')
bytesio = io.BytesIO()
archive = zipfile.ZipFile(bytesio, 'w')
for bill in queryset:
pdf = html_to_pdf(bill.html or bill.render())
pdf = bill.as_pdf()
archive.writestr('%s.pdf' % bill.number, pdf)
archive.close()
response = HttpResponse(stringio.getvalue(), content_type='application/pdf')
response = HttpResponse(bytesio.getvalue(), content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="orchestra-bills.zip"'
return response
bill = queryset.get()
pdf = html_to_pdf(bill.html or bill.render(), pagination=bill.has_multiple_pages)
pdf = bill.as_pdf()
return HttpResponse(pdf, content_type='application/pdf')
download_bills.verbose_name = _("Download")
download_bills.url_name = 'download'

View File

@ -136,7 +136,7 @@ class Bill(models.Model):
if not self.is_open:
return self.total
try:
return self.computed_total
return round(self.computed_total, 2)
except AttributeError:
self.computed_total = self.compute_total()
return self.computed_total
@ -199,8 +199,7 @@ class Bill(models.Model):
return transaction
def send(self):
html = self.html or self.render()
pdf = html_to_pdf(html, pagination=self.has_multiple_pages)
pdf = self.as_pdf()
self.account.send_email(
template=settings.BILLS_EMAIL_NOTIFICATION_TEMPLATE,
context={
@ -243,6 +242,10 @@ class Bill(models.Model):
html = html.replace('-pageskip-', '<pdf:nextpage />')
return html
def as_pdf(self):
html = self.html or self.render()
return html_to_pdf(html, pagination=self.has_multiple_pages)
def save(self, *args, **kwargs):
if not self.type:
self.type = self.get_type()

View File

@ -50,7 +50,7 @@ class Message(models.Model):
def sent(self):
self.state = self.SENT
self.save(update_fiields=('state',))
self.save(update_fields=('state',))
def log(self, error):
result = SMTPLog.SUCCESS

View File

@ -109,7 +109,7 @@ class BackendOperationInline(admin.TabularInline):
def instance_link(self, operation):
link = admin_link('instance')(self, operation)
if not link.startswith('<a'):
if link == '---':
return _("Deleted {0}").format(operation.instance_repr or '-'.join(
(escape(operation.content_type), escape(operation.object_id))))
return link

View File

@ -182,3 +182,15 @@ def delete_selected(modeladmin, request, queryset):
helpers.post_delete_processes(modelamdin, request, related_transactions)
return response
delete_selected.short_description = actions.delete_selected.short_description
def report(modeladmin, request, queryset):
if queryset.model == Transaction:
transactions = queryset
else:
transactions = queryset.values_list('transactions__id', flat=True).distinct()
transactions = Transaction.objects.filter(id__in=transactions)
context = {
'transactions': transactions
}
return render(request, 'admin/payments/transaction/report.html', context)

View File

@ -87,11 +87,11 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
)
}),
)
actions = (
actions.process_transactions, actions.mark_as_executed,
actions.mark_as_secured, actions.mark_as_rejected
change_view_actions = (
actions.process_transactions, actions.mark_as_executed, actions.mark_as_secured,
actions.mark_as_rejected,
)
change_view_actions = actions
actions = change_view_actions + (actions.report,)
filter_by_account_fields = ('bill', 'source')
change_readonly_fields = ('amount', 'currency')
readonly_fields = ('bill_link', 'display_state', 'process_link', 'account_link', 'source_link')
@ -123,7 +123,9 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin):
fields = ('data', 'file_url', 'created_at')
readonly_fields = ('data', 'file_url', 'display_transactions', 'created_at')
inlines = [TransactionInline]
change_view_actions = (actions.mark_process_as_executed, actions.abort, actions.commit)
change_view_actions = (
actions.mark_process_as_executed, actions.abort, actions.commit, actions.report
)
actions = change_view_actions + (actions.delete_selected,)
def file_url(self, process):

View File

@ -131,22 +131,22 @@ class Transaction(models.Model):
def mark_as_processed(self):
self.check_state(self.WAITTING_PROCESSING)
self.state = self.WAITTING_EXECUTION
self.save(update_fields=['state'])
self.save(update_fields=['state', 'modified_at'])
def mark_as_executed(self):
self.check_state(self.WAITTING_EXECUTION)
self.state = self.EXECUTED
self.save(update_fields=['state'])
self.save(update_fields=['state', 'modified_at'])
def mark_as_secured(self):
self.check_state(self.EXECUTED)
self.state = self.SECURED
self.save(update_fields=['state'])
self.save(update_fields=['state', 'modified_at'])
def mark_as_rejected(self):
self.check_state(self.EXECUTED)
self.state = self.REJECTED
self.save(update_fields=['state'])
self.save(update_fields=['state', 'modified_at'])
class TransactionProcess(models.Model):

View File

@ -0,0 +1,54 @@
{% load i18n %}
<html>
<head>
<title>Transaction Report</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
@page {
size: 11.69in 8.27in;
}
table {
font-family: sans;
font-size: 10px;
max-width: 10in;
}
table tr:nth-child(even) {
background-color: #eee;
}
table tr:nth-child(odd) {
background-color: #fff;
}
table th {
color: white;
background-color: grey;
}
</style>
</head>
<body>
<table>
<tr id="transaction">
<th class="title column-id">ID</th>
<th class="title column-bill">{% trans "Bill" %}</th>
<th class="title column-billcontant">{% trans "Contact" %}</th>
<th class="title column-iban">IBAN</th>
<th class="title column-amount">{% trans "Amount" %}</th>
<th class="title column-state">{% trans "State" %}</th>
<th class="title column-created">{% trans "Created" %}</th>
<th class="title column-updated">{% trans "Updated" %}</th>
</tr>
{% for transaction in transactions %}
<tr>
<td class="item column-id">{{ transaction.id }}</td>
<td class="item column-bill">{{ transaction.bill.number }}</td>
<td class="item column-billcontant">{{ transaction.bill.buyer.get_name }}</td>
<td class="item column-iban">{{ transaction.source.data.iban }}</td>
<td class="item column-amount">{{ transaction.amount }}</td>
<td class="item column-state">{{ transaction.get_state_display }}</td>
<td class="item column-state">{{ transaction.created_at|date }}</td>
<td class="item column-state">{{ transaction.modified_at|date }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>