Added support for reissue rejected transactions
This commit is contained in:
parent
fdd84b7e74
commit
e804a1d102
|
@ -122,7 +122,7 @@ class AccountAdmin(ChangePasswordAdminMixin, auth.UserAdmin, ExtendedModelAdmin)
|
|||
return views
|
||||
|
||||
def get_actions(self, request):
|
||||
actions = super(AccountAdmin, self).get_actions(request)
|
||||
actions = super().get_actions(request)
|
||||
if 'delete_selected' in actions:
|
||||
del actions['delete_selected']
|
||||
return actions
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import redirect
|
||||
|
||||
|
||||
def last(modeladmin, request, queryset):
|
||||
last_id = queryset.order_by('id').values_list('id', flat=True).first()
|
||||
url = reverse('admin:mailer_message_change', args=(last_id,))
|
||||
print(url)
|
||||
return redirect(url)
|
|
@ -8,9 +8,11 @@ from django.db.models import Count
|
|||
from django.shortcuts import redirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_link, admin_colored, admin_date, wrap_admin_view
|
||||
from orchestra.contrib.tasks import task
|
||||
|
||||
from .actions import last
|
||||
from .engine import send_pending
|
||||
from .models import Message, SMTPLog
|
||||
|
||||
|
@ -25,13 +27,13 @@ COLORS = {
|
|||
}
|
||||
|
||||
|
||||
class MessageAdmin(admin.ModelAdmin):
|
||||
class MessageAdmin(ExtendedModelAdmin):
|
||||
list_display = (
|
||||
'display_subject', 'colored_state', 'priority', 'to_address', 'from_address',
|
||||
'created_at_delta', 'display_retries', 'last_try_delta',
|
||||
)
|
||||
list_filter = ('state', 'priority', 'retries')
|
||||
list_prefetch_related = ('logs__id')
|
||||
list_prefetch_related = ('logs',)
|
||||
search_fields = ('to_address', 'from_address', 'subject',)
|
||||
fieldsets = (
|
||||
(None, {
|
||||
|
@ -49,6 +51,7 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
'display_to', 'display_from', 'display_content',
|
||||
)
|
||||
date_hierarchy = 'created_at'
|
||||
change_view_actions = (last,)
|
||||
|
||||
colored_state = admin_colored('state', colors=COLORS)
|
||||
created_at_delta = admin_date('created_at')
|
||||
|
@ -114,7 +117,7 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
|
||||
def get_urls(self):
|
||||
from django.conf.urls import url
|
||||
urls = super(MessageAdmin, self).get_urls()
|
||||
urls = super().get_urls()
|
||||
info = self.model._meta.app_label, self.model._meta.model_name
|
||||
urls.insert(0,
|
||||
url(r'^send-pending/$',
|
||||
|
@ -124,8 +127,8 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
return urls
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super(MessageAdmin, self).get_queryset(request)
|
||||
return qs.annotate(Count('logs')).prefetch_related('logs').defer('content')
|
||||
qs = super().get_queryset(request)
|
||||
return qs.annotate(Count('logs')).defer('content')
|
||||
|
||||
def send_pending_view(self, request):
|
||||
task(send_pending).apply_async()
|
||||
|
@ -135,7 +138,7 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||
if db_field.name == 'subject':
|
||||
kwargs['widget'] = forms.TextInput(attrs={'size':'100'})
|
||||
return super(MessageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
return super().formfield_for_dbfield(db_field, **kwargs)
|
||||
|
||||
|
||||
class SMTPLogAdmin(admin.ModelAdmin):
|
||||
|
|
|
@ -2,8 +2,9 @@ from functools import partial
|
|||
|
||||
from django.contrib import messages
|
||||
from django.contrib.admin import actions
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import transaction
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import ungettext, ugettext_lazy as _
|
||||
|
@ -205,3 +206,19 @@ def report(modeladmin, request, queryset):
|
|||
'transactions': transactions,
|
||||
}
|
||||
return render(request, 'admin/payments/transaction/report.html', context)
|
||||
|
||||
|
||||
def reissue(modeladmin, request, queryset):
|
||||
if len(queryset) != 1:
|
||||
messages.error(request, _("One transaction should be selected."))
|
||||
return
|
||||
trans = queryset[0]
|
||||
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)
|
||||
|
|
|
@ -105,9 +105,10 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
)
|
||||
change_view_actions = (
|
||||
actions.process_transactions, actions.mark_as_executed, actions.mark_as_secured,
|
||||
actions.mark_as_rejected,
|
||||
actions.mark_as_rejected, actions.reissue
|
||||
)
|
||||
actions = change_view_actions + (actions.report, list_accounts)
|
||||
search_fields = ('bill__number', 'bill__account__username', 'id')
|
||||
actions = change_view_actions + (actions.report, list_accounts,)
|
||||
filter_by_account_fields = ('bill', 'source')
|
||||
change_readonly_fields = ('amount', 'currency')
|
||||
readonly_fields = (
|
||||
|
@ -124,17 +125,28 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
display_created_at = admin_date('created_at', short_description=_("Created"))
|
||||
display_modified_at = admin_date('modified_at', short_description=_("Modified"))
|
||||
|
||||
def has_delete_permission(self, *args, **kwargs):
|
||||
return False
|
||||
|
||||
def get_actions(self, request):
|
||||
actions = super().get_actions(request)
|
||||
if 'delete_selected' in actions:
|
||||
del actions['delete_selected']
|
||||
return actions
|
||||
|
||||
def get_change_view_actions(self, obj=None):
|
||||
actions = super(TransactionAdmin, self).get_change_view_actions()
|
||||
exclude = []
|
||||
if obj:
|
||||
if obj.state == Transaction.WAITTING_PROCESSING:
|
||||
exclude = ['mark_as_executed', 'mark_as_secured']
|
||||
exclude = ['mark_as_executed', 'mark_as_secured', 'reissue']
|
||||
elif obj.state == Transaction.WAITTING_EXECUTION:
|
||||
exclude = ['process_transactions', 'mark_as_secured']
|
||||
exclude = ['process_transactions', 'mark_as_secured', 'reissue']
|
||||
if obj.state == Transaction.EXECUTED:
|
||||
exclude = ['process_transactions', 'mark_as_executed']
|
||||
elif obj.state in [Transaction.REJECTED, Transaction.SECURED]:
|
||||
exclude = ['process_transactions', 'mark_as_executed', 'reissue']
|
||||
elif obj.state == Transaction.REJECTED:
|
||||
exclude = ['process_transactions', 'mark_as_executed', 'mark_as_secured', 'mark_as_rejected']
|
||||
elif obj.state == Transaction.SECURED:
|
||||
return []
|
||||
return [action for action in actions if action.__name__ not in exclude]
|
||||
|
||||
|
@ -154,6 +166,7 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin):
|
|||
)
|
||||
list_filter = ('state',)
|
||||
fields = ('data', 'file_url', 'created_at')
|
||||
search_fields = ('transactions__bill__number', 'transactions__bill__account__username', 'id')
|
||||
readonly_fields = ('data', 'file_url', 'display_transactions', 'created_at')
|
||||
list_prefetch_related = ('transactions',)
|
||||
inlines = [TransactionInline]
|
||||
|
|
|
@ -135,7 +135,12 @@ class Transaction(models.Model):
|
|||
if not self.pk:
|
||||
amount = self.bill.transactions.exclude(state=self.REJECTED).amount()
|
||||
if amount >= self.bill.total:
|
||||
raise ValidationError(_("New transactions can not be allocated for this bill."))
|
||||
raise ValidationError(
|
||||
_("Bill %(number)s already has valid transactions that cover bill total amount (%(amount)s).") % {
|
||||
'number': self.bill.number,
|
||||
'amount': amount,
|
||||
}
|
||||
)
|
||||
|
||||
def get_state_help(self):
|
||||
if self.source:
|
||||
|
|
Loading…
Reference in New Issue