2014-09-18 15:07:39 +00:00
|
|
|
from functools import partial
|
|
|
|
|
2014-09-10 16:53:09 +00:00
|
|
|
from django.contrib import messages
|
2015-05-30 14:44:05 +00:00
|
|
|
from django.contrib.admin import actions
|
2016-05-09 12:02:10 +00:00
|
|
|
from django.core.urlresolvers import reverse
|
2014-09-16 17:14:24 +00:00
|
|
|
from django.db import transaction
|
2016-05-09 12:02:10 +00:00
|
|
|
from django.shortcuts import render, redirect
|
2014-09-18 15:07:39 +00:00
|
|
|
from django.utils.safestring import mark_safe
|
|
|
|
from django.utils.text import capfirst
|
2014-10-21 15:29:36 +00:00
|
|
|
from django.utils.translation import ungettext, ugettext_lazy as _
|
2014-09-10 16:53:09 +00:00
|
|
|
|
2014-09-16 17:14:24 +00:00
|
|
|
from orchestra.admin.decorators import action_with_confirmation
|
2014-09-18 15:07:39 +00:00
|
|
|
from orchestra.admin.utils import change_url
|
2014-09-16 17:14:24 +00:00
|
|
|
|
2015-06-02 12:59:49 +00:00
|
|
|
from . import helpers
|
2014-09-08 10:03:42 +00:00
|
|
|
from .methods import PaymentMethod
|
2014-09-10 16:53:09 +00:00
|
|
|
from .models import Transaction
|
|
|
|
|
2014-09-16 17:14:24 +00:00
|
|
|
|
|
|
|
@transaction.atomic
|
2014-07-30 12:55:33 +00:00
|
|
|
def process_transactions(modeladmin, request, queryset):
|
2014-09-10 16:53:09 +00:00
|
|
|
processes = []
|
|
|
|
if queryset.exclude(state=Transaction.WAITTING_PROCESSING).exists():
|
2015-05-30 14:44:05 +00:00
|
|
|
messages.error(request,
|
|
|
|
_("Selected transactions must be on '{state}' state").format(
|
|
|
|
state=Transaction.WAITTING_PROCESSING)
|
|
|
|
)
|
2014-09-10 16:53:09 +00:00
|
|
|
return
|
2015-04-02 16:14:55 +00:00
|
|
|
for method, transactions in queryset.group_by('source__method').items():
|
2014-09-08 10:03:42 +00:00
|
|
|
if method is not None:
|
2015-03-31 12:39:08 +00:00
|
|
|
method = PaymentMethod.get(method)
|
2014-09-10 16:53:09 +00:00
|
|
|
procs = method.process(transactions)
|
|
|
|
processes += procs
|
2015-05-30 14:44:05 +00:00
|
|
|
for transaction in transactions:
|
|
|
|
modeladmin.log_change(request, transaction, _("Processed"))
|
2014-09-10 16:53:09 +00:00
|
|
|
if not processes:
|
|
|
|
return
|
|
|
|
opts = modeladmin.model._meta
|
2014-10-23 15:38:46 +00:00
|
|
|
num = len(queryset)
|
2014-09-10 16:53:09 +00:00
|
|
|
context = {
|
2014-10-23 15:38:46 +00:00
|
|
|
'title': ungettext(
|
2015-05-30 14:44:05 +00:00
|
|
|
_("One selected transaction has been processed."),
|
2014-10-23 15:38:46 +00:00
|
|
|
_("%s Selected transactions have been processed.") % num,
|
|
|
|
num),
|
|
|
|
'content_message': ungettext(
|
|
|
|
_("The following transaction process has been generated, "
|
|
|
|
"you may want to save it on your computer now."),
|
|
|
|
_("The following %s transaction processes have been generated, "
|
|
|
|
"you may want to save it on your computer now.") % len(processes),
|
|
|
|
len(processes)),
|
2014-09-10 16:53:09 +00:00
|
|
|
'action_name': _("Process"),
|
|
|
|
'processes': processes,
|
|
|
|
'opts': opts,
|
|
|
|
'app_label': opts.app_label,
|
|
|
|
}
|
|
|
|
return render(request, 'admin/payments/transaction/get_processes.html', context)
|
2014-09-16 17:14:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation()
|
2014-11-11 16:59:13 +00:00
|
|
|
def mark_as_executed(modeladmin, request, queryset):
|
2015-05-30 14:44:05 +00:00
|
|
|
for transaction in queryset:
|
|
|
|
transaction.mark_as_executed()
|
|
|
|
modeladmin.log_change(request, transaction, _("Executed"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected transaction has been marked as executed."),
|
|
|
|
_("%s selected transactions have been marked as executed.") % num,
|
|
|
|
num)
|
2014-09-16 17:14:24 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
mark_as_executed.url_name = 'execute'
|
2015-07-20 12:51:30 +00:00
|
|
|
mark_as_executed.short_description = _("Mark as executed")
|
2014-09-16 17:14:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation()
|
|
|
|
def mark_as_secured(modeladmin, request, queryset):
|
2015-05-30 14:44:05 +00:00
|
|
|
for transaction in queryset:
|
|
|
|
transaction.mark_as_secured()
|
|
|
|
modeladmin.log_change(request, transaction, _("Secured"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected transaction has been marked as secured."),
|
|
|
|
_("%s selected transactions have been marked as secured.") % num,
|
|
|
|
num)
|
2014-09-16 17:14:24 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
mark_as_secured.url_name = 'secure'
|
2015-07-20 12:51:30 +00:00
|
|
|
mark_as_secured.short_description = _("Mark as secured")
|
2014-09-16 17:14:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation()
|
|
|
|
def mark_as_rejected(modeladmin, request, queryset):
|
2015-05-30 14:44:05 +00:00
|
|
|
for transaction in queryset:
|
|
|
|
transaction.mark_as_rejected()
|
|
|
|
modeladmin.log_change(request, transaction, _("Rejected"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected transaction has been marked as rejected."),
|
|
|
|
_("%s selected transactions have been marked as rejected.") % num,
|
|
|
|
num)
|
2014-09-16 17:14:24 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
mark_as_rejected.url_name = 'reject'
|
2015-07-20 12:51:30 +00:00
|
|
|
mark_as_rejected.short_description = _("Mark as rejected")
|
2014-09-18 15:07:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _format_display_objects(modeladmin, request, queryset, related):
|
|
|
|
objects = []
|
|
|
|
opts = modeladmin.model._meta
|
|
|
|
for obj in queryset:
|
|
|
|
objects.append(
|
|
|
|
mark_safe('{0}: <a href="{1}">{2}</a>'.format(
|
|
|
|
capfirst(opts.verbose_name), change_url(obj), obj))
|
|
|
|
)
|
|
|
|
subobjects = []
|
|
|
|
attr, verb = related
|
2015-12-09 14:52:46 +00:00
|
|
|
for trans in getattr(obj.transactions, attr)():
|
2014-09-18 15:07:39 +00:00
|
|
|
subobjects.append(
|
2014-10-21 15:29:36 +00:00
|
|
|
mark_safe('Transaction: <a href="{}">{}</a> will be marked as {}'.format(
|
2015-12-09 14:52:46 +00:00
|
|
|
change_url(trans), trans, verb))
|
2014-09-18 15:07:39 +00:00
|
|
|
)
|
|
|
|
objects.append(subobjects)
|
|
|
|
return {'display_objects': objects}
|
|
|
|
|
|
|
|
_format_executed = partial(_format_display_objects, related=('all', 'executed'))
|
|
|
|
_format_abort = partial(_format_display_objects, related=('processing', 'aborted'))
|
|
|
|
_format_commit = partial(_format_display_objects, related=('all', 'secured'))
|
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation(extra_context=_format_executed)
|
|
|
|
def mark_process_as_executed(modeladmin, request, queryset):
|
|
|
|
for process in queryset:
|
|
|
|
process.mark_as_executed()
|
2014-10-07 13:50:59 +00:00
|
|
|
modeladmin.log_change(request, process, _("Executed"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected process has been marked as executed."),
|
|
|
|
_("%s selected processes have been marked as executed.") % num,
|
|
|
|
num)
|
2014-09-18 15:07:39 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
mark_process_as_executed.url_name = 'executed'
|
2015-07-20 12:51:30 +00:00
|
|
|
mark_process_as_executed.short_description = _("Mark as executed")
|
2014-09-18 15:07:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation(extra_context=_format_abort)
|
|
|
|
def abort(modeladmin, request, queryset):
|
|
|
|
for process in queryset:
|
|
|
|
process.abort()
|
2014-10-07 13:50:59 +00:00
|
|
|
modeladmin.log_change(request, process, _("Aborted"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected process has been aborted."),
|
|
|
|
_("%s selected processes have been aborted.") % num,
|
|
|
|
num)
|
2014-09-18 15:07:39 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
abort.url_name = 'abort'
|
2015-07-20 12:51:30 +00:00
|
|
|
abort.short_description = _("Abort")
|
2014-09-18 15:07:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
@action_with_confirmation(extra_context=_format_commit)
|
|
|
|
def commit(modeladmin, request, queryset):
|
2015-05-30 14:44:05 +00:00
|
|
|
for transaction in queryset:
|
|
|
|
transaction.mark_as_rejected()
|
|
|
|
modeladmin.log_change(request, transaction, _("Rejected"))
|
2014-10-21 15:29:36 +00:00
|
|
|
num = len(queryset)
|
|
|
|
msg = ungettext(
|
|
|
|
_("One selected transaction has been marked as rejected."),
|
|
|
|
_("%s selected transactions have been marked as rejected.") % num,
|
|
|
|
num)
|
2014-09-18 15:07:39 +00:00
|
|
|
modeladmin.message_user(request, msg)
|
|
|
|
commit.url_name = 'commit'
|
2015-07-20 12:51:30 +00:00
|
|
|
commit.short_description = _("Commit")
|
2015-05-30 14:44:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
def delete_selected(modeladmin, request, queryset):
|
|
|
|
""" Has to have same name as admin.actions.delete_selected """
|
2015-07-14 10:19:45 +00:00
|
|
|
related_transactions = helpers.pre_delete_processes(modeladmin, request, queryset)
|
2015-05-30 14:44:05 +00:00
|
|
|
response = actions.delete_selected(modeladmin, request, queryset)
|
2015-06-02 12:59:49 +00:00
|
|
|
if response is None:
|
2015-07-14 10:19:45 +00:00
|
|
|
helpers.post_delete_processes(modeladmin, request, related_transactions)
|
2015-05-30 14:44:05 +00:00
|
|
|
return response
|
|
|
|
delete_selected.short_description = actions.delete_selected.short_description
|
2015-06-03 12:49:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
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)
|
2015-07-10 13:00:51 +00:00
|
|
|
states = {}
|
|
|
|
total = 0
|
2020-03-18 06:49:04 +00:00
|
|
|
transactions = transactions.order_by('bill__number')
|
2015-07-10 13:00:51 +00:00
|
|
|
for transaction in transactions:
|
|
|
|
state = transaction.get_state_display()
|
|
|
|
try:
|
|
|
|
states[state] += transaction.amount
|
|
|
|
except KeyError:
|
|
|
|
states[state] = transaction.amount
|
|
|
|
total += transaction.amount
|
2015-06-03 12:49:30 +00:00
|
|
|
context = {
|
2015-07-10 13:00:51 +00:00
|
|
|
'states': states,
|
|
|
|
'total': total,
|
|
|
|
'transactions': transactions,
|
2015-06-03 12:49:30 +00:00
|
|
|
}
|
|
|
|
return render(request, 'admin/payments/transaction/report.html', context)
|
2016-05-09 12:02:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
def reissue(modeladmin, request, queryset):
|
|
|
|
if len(queryset) != 1:
|
|
|
|
messages.error(request, _("One transaction should be selected."))
|
|
|
|
return
|
|
|
|
trans = queryset[0]
|
2016-05-11 12:56:10 +00:00
|
|
|
if trans.state != trans.REJECTED:
|
|
|
|
messages.error(request,
|
|
|
|
_("Only rejected transactions can be reissued, "
|
|
|
|
"please reject current transaction if necessary."))
|
|
|
|
return
|
2016-05-09 12:02:10 +00:00
|
|
|
url = reverse('admin:payments_transaction_add')
|
|
|
|
url += '?account=%i&bill=%i&source=%s&amount=%s¤cy=%s' % (
|
|
|
|
trans.bill.account_id,
|
|
|
|
trans.bill_id,
|
|
|
|
trans.source_id or '',
|
|
|
|
trans.amount,
|
|
|
|
trans.currency,
|
|
|
|
)
|
|
|
|
return redirect(url)
|