2014-09-04 15:55:43 +00:00
|
|
|
from django import forms
|
2014-09-05 14:27:30 +00:00
|
|
|
from django.conf.urls import patterns, url
|
2014-07-23 16:24:56 +00:00
|
|
|
from django.contrib import admin
|
2014-07-29 20:10:37 +00:00
|
|
|
from django.core.urlresolvers import reverse
|
2014-09-05 14:27:30 +00:00
|
|
|
from django.shortcuts import render, redirect
|
2014-07-29 20:10:37 +00:00
|
|
|
from django.utils.translation import ugettext_lazy as _
|
2014-07-23 16:24:56 +00:00
|
|
|
|
2014-09-16 17:14:24 +00:00
|
|
|
from orchestra.admin import ChangeViewActionsMixin
|
2014-09-08 15:10:16 +00:00
|
|
|
from orchestra.admin.utils import admin_colored, admin_link, wrap_admin_view
|
2014-07-28 17:28:00 +00:00
|
|
|
from orchestra.apps.accounts.admin import AccountAdminMixin
|
2014-07-24 09:53:34 +00:00
|
|
|
|
2014-09-16 17:14:24 +00:00
|
|
|
from . import actions
|
2014-09-05 14:27:30 +00:00
|
|
|
from .methods import PaymentMethod
|
|
|
|
from .models import PaymentSource, Transaction, TransactionProcess
|
2014-07-23 16:24:56 +00:00
|
|
|
|
|
|
|
|
2014-07-24 09:53:34 +00:00
|
|
|
STATE_COLORS = {
|
|
|
|
Transaction.WAITTING_PROCESSING: 'darkorange',
|
2014-09-18 15:07:39 +00:00
|
|
|
Transaction.WAITTING_EXECUTION: 'magenta',
|
2014-09-16 17:14:24 +00:00
|
|
|
Transaction.EXECUTED: 'olive',
|
2014-09-05 14:27:30 +00:00
|
|
|
Transaction.SECURED: 'green',
|
2014-07-24 09:53:34 +00:00
|
|
|
Transaction.REJECTED: 'red',
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-18 15:07:39 +00:00
|
|
|
class PaymentSourceAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|
|
|
list_display = ('label', 'method', 'number', 'account_link', 'is_active')
|
|
|
|
list_filter = ('method', 'is_active')
|
|
|
|
|
|
|
|
def get_form(self, request, obj=None, **kwargs):
|
|
|
|
if obj:
|
|
|
|
self.form = obj.method_class().get_form()
|
|
|
|
else:
|
|
|
|
self.form = PaymentMethod.get_plugin(self.method)().get_form()
|
|
|
|
return super(PaymentSourceAdmin, self).get_form(request, obj=obj, **kwargs)
|
|
|
|
|
|
|
|
def get_urls(self):
|
|
|
|
""" Hooks select account url """
|
|
|
|
urls = super(PaymentSourceAdmin, self).get_urls()
|
|
|
|
admin_site = self.admin_site
|
|
|
|
opts = self.model._meta
|
|
|
|
info = opts.app_label, opts.model_name
|
|
|
|
select_urls = patterns("",
|
|
|
|
url("/select-method/$",
|
|
|
|
wrap_admin_view(self, self.select_method_view),
|
|
|
|
name='%s_%s_select_method' % info),
|
|
|
|
)
|
|
|
|
return select_urls + urls
|
|
|
|
|
|
|
|
def select_method_view(self, request):
|
|
|
|
opts = self.model._meta
|
|
|
|
context = {
|
|
|
|
'opts': opts,
|
|
|
|
'app_label': opts.app_label,
|
|
|
|
'methods': PaymentMethod.get_plugin_choices(),
|
|
|
|
}
|
|
|
|
template = 'admin/payments/payment_source/select_method.html'
|
|
|
|
return render(request, template, context)
|
|
|
|
|
|
|
|
def add_view(self, request, form_url='', extra_context=None):
|
|
|
|
""" Redirects to select account view if required """
|
|
|
|
if request.user.is_superuser:
|
|
|
|
method = request.GET.get('method')
|
|
|
|
if method or PaymentMethod.get_plugins() == 1:
|
|
|
|
self.method = method
|
|
|
|
if not method:
|
|
|
|
self.method = PaymentMethod.get_plugins()[0]
|
|
|
|
return super(PaymentSourceAdmin, self).add_view(request,
|
|
|
|
form_url=form_url, extra_context=extra_context)
|
|
|
|
return redirect('./select-method/?%s' % request.META['QUERY_STRING'])
|
|
|
|
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
|
|
if not change:
|
|
|
|
obj.method = self.method
|
|
|
|
obj.save()
|
|
|
|
|
|
|
|
|
2014-09-05 14:27:30 +00:00
|
|
|
class TransactionInline(admin.TabularInline):
|
|
|
|
model = Transaction
|
|
|
|
can_delete = False
|
|
|
|
extra = 0
|
2014-09-16 17:14:24 +00:00
|
|
|
fields = (
|
|
|
|
'transaction_link', 'bill_link', 'source_link', 'display_state',
|
|
|
|
'amount', 'currency'
|
|
|
|
)
|
2014-09-05 14:27:30 +00:00
|
|
|
readonly_fields = fields
|
|
|
|
|
|
|
|
transaction_link = admin_link('__unicode__', short_description=_("ID"))
|
|
|
|
bill_link = admin_link('bill')
|
|
|
|
source_link = admin_link('source')
|
|
|
|
display_state = admin_colored('state', colors=STATE_COLORS)
|
|
|
|
|
|
|
|
class Media:
|
|
|
|
css = {
|
|
|
|
'all': ('orchestra/css/hide-inline-id.css',)
|
|
|
|
}
|
|
|
|
|
|
|
|
def has_add_permission(self, *args, **kwargs):
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2014-09-16 17:14:24 +00:00
|
|
|
class TransactionAdmin(ChangeViewActionsMixin, AccountAdminMixin, admin.ModelAdmin):
|
2014-07-24 09:53:34 +00:00
|
|
|
list_display = (
|
2014-09-16 17:14:24 +00:00
|
|
|
'id', 'bill_link', 'account_link', 'source_link', 'display_state',
|
|
|
|
'amount', 'process_link'
|
2014-07-24 09:53:34 +00:00
|
|
|
)
|
2014-07-28 17:28:00 +00:00
|
|
|
list_filter = ('source__method', 'state')
|
2014-09-16 17:14:24 +00:00
|
|
|
actions = (
|
|
|
|
actions.process_transactions, actions.mark_as_executed,
|
|
|
|
actions.mark_as_secured, actions.mark_as_rejected
|
|
|
|
)
|
|
|
|
change_view_actions = actions
|
2014-09-04 15:55:43 +00:00
|
|
|
filter_by_account_fields = ['source']
|
2014-09-16 17:14:24 +00:00
|
|
|
readonly_fields = ('bill_link', 'display_state', 'process_link', 'account_link')
|
2014-07-24 09:53:34 +00:00
|
|
|
|
|
|
|
bill_link = admin_link('bill')
|
2014-09-04 15:55:43 +00:00
|
|
|
source_link = admin_link('source')
|
2014-09-05 14:27:30 +00:00
|
|
|
process_link = admin_link('process', short_description=_("proc"))
|
2014-07-24 09:53:34 +00:00
|
|
|
account_link = admin_link('bill__account')
|
|
|
|
display_state = admin_colored('state', colors=STATE_COLORS)
|
2014-08-19 18:59:23 +00:00
|
|
|
|
|
|
|
def get_queryset(self, request):
|
|
|
|
qs = super(TransactionAdmin, self).get_queryset(request)
|
|
|
|
return qs.select_related('source', 'bill__account__user')
|
2014-09-16 17:14:24 +00:00
|
|
|
|
|
|
|
def get_change_view_actions(self, obj=None):
|
|
|
|
actions = super(TransactionAdmin, self).get_change_view_actions()
|
2014-09-18 15:07:39 +00:00
|
|
|
exclude = []
|
2014-09-16 17:14:24 +00:00
|
|
|
if obj:
|
2014-09-19 14:47:25 +00:00
|
|
|
if obj.state == Transaction.WAITTING_PROCESSING:
|
|
|
|
exclude = ['mark_as_executed', 'mark_as_secured', 'mark_as_rejected']
|
|
|
|
elif obj.state == Transaction.WAITTING_EXECUTION:
|
|
|
|
exclude = ['process_transactions', 'mark_as_secured', 'mark_as_rejected']
|
2014-09-16 17:14:24 +00:00
|
|
|
if obj.state == Transaction.EXECUTED:
|
2014-09-19 14:47:25 +00:00
|
|
|
exclude = ['process_transactions', 'mark_as_executed']
|
|
|
|
elif obj.state in [Transaction.REJECTED, Transaction.SECURED]:
|
|
|
|
return []
|
2014-09-18 15:07:39 +00:00
|
|
|
return [action for action in actions if action.__name__ not in exclude]
|
2014-07-28 17:28:00 +00:00
|
|
|
|
|
|
|
|
2014-09-18 15:07:39 +00:00
|
|
|
class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin):
|
2014-07-29 20:10:37 +00:00
|
|
|
list_display = ('id', 'file_url', 'display_transactions', 'created_at')
|
|
|
|
fields = ('data', 'file_url', 'display_transactions', 'created_at')
|
|
|
|
readonly_fields = ('file_url', 'display_transactions', 'created_at')
|
2014-09-05 14:27:30 +00:00
|
|
|
inlines = [TransactionInline]
|
2014-09-18 15:07:39 +00:00
|
|
|
actions = (actions.mark_process_as_executed, actions.abort, actions.commit)
|
|
|
|
change_view_actions = actions
|
2014-07-29 20:10:37 +00:00
|
|
|
|
|
|
|
def file_url(self, process):
|
|
|
|
if process.file:
|
|
|
|
return '<a href="%s">%s</a>' % (process.file.url, process.file.name)
|
|
|
|
file_url.allow_tags = True
|
|
|
|
file_url.admin_order_field = 'file'
|
|
|
|
|
|
|
|
def display_transactions(self, process):
|
2014-07-30 12:55:33 +00:00
|
|
|
ids = []
|
|
|
|
lines = []
|
|
|
|
counter = 0
|
2014-08-19 18:59:23 +00:00
|
|
|
# Because of values_list this query doesn't benefit from prefetch_related
|
|
|
|
tx_ids = process.transactions.values_list('id', flat=True)
|
2014-07-30 12:55:33 +00:00
|
|
|
for tx_id in tx_ids:
|
|
|
|
ids.append(str(tx_id))
|
|
|
|
counter += 1
|
|
|
|
if counter > 10:
|
|
|
|
counter = 0
|
|
|
|
lines.append(','.join(ids))
|
|
|
|
ids = []
|
|
|
|
lines.append(','.join(ids))
|
|
|
|
url = reverse('admin:payments_transaction_changelist')
|
|
|
|
url += '?processes=%i' % process.id
|
|
|
|
return '<a href="%s">%s</a>' % (url, '<br>'.join(lines))
|
2014-07-29 20:10:37 +00:00
|
|
|
display_transactions.short_description = _("Transactions")
|
|
|
|
display_transactions.allow_tags = True
|
2014-09-18 15:07:39 +00:00
|
|
|
|
2014-09-22 15:59:53 +00:00
|
|
|
def has_add_permission(self, *args, **kwargs):
|
|
|
|
return False
|
|
|
|
|
2014-09-18 15:07:39 +00:00
|
|
|
def get_change_view_actions(self, obj=None):
|
|
|
|
actions = super(TransactionProcessAdmin, self).get_change_view_actions()
|
|
|
|
exclude = []
|
|
|
|
if obj:
|
|
|
|
if obj.state == TransactionProcess.EXECUTED:
|
|
|
|
exclude.append('mark_process_as_executed')
|
|
|
|
elif obj.state == TransactionProcess.COMMITED:
|
|
|
|
exclude = ['mark_process_as_executed', 'abort', 'commit']
|
|
|
|
elif obj.state == TransactionProcess.ABORTED:
|
|
|
|
exclude = ['mark_process_as_executed', 'abort', 'commit']
|
|
|
|
return [action for action in actions if action.__name__ not in exclude]
|
2014-07-29 20:10:37 +00:00
|
|
|
|
|
|
|
|
2014-07-28 17:28:00 +00:00
|
|
|
admin.site.register(PaymentSource, PaymentSourceAdmin)
|
2014-07-24 09:53:34 +00:00
|
|
|
admin.site.register(Transaction, TransactionAdmin)
|
2014-09-05 14:27:30 +00:00
|
|
|
admin.site.register(TransactionProcess, TransactionProcessAdmin)
|