1 from django.contrib import admin
 
   2 from django.contrib.admin.filters import FieldListFilter, SimpleListFilter
 
   3 from django.contrib import messages
 
   4 from django.db.models import Q
 
   5 from django.shortcuts import get_object_or_404, redirect
 
   6 from django.urls import path, reverse
 
   7 from django.utils.safestring import mark_safe
 
   8 from django.utils.translation import gettext_lazy as _
 
   9 from django.utils.timezone import now
 
  10 from fnpdjango.actions import export_as_csv_action
 
  15 admin.site.register(models.Fundraiser)
 
  16 admin.site.register(models.Campaign)
 
  19 # Backport from Django 3.1.
 
  20 class EmptyFieldListFilter(FieldListFilter):
 
  21     with_empty_str = False
 
  23     def __init__(self, field, request, params, model, model_admin, field_path):
 
  24         self.lookup_kwarg = '%s__isempty' % field_path
 
  25         self.lookup_val = params.get(self.lookup_kwarg)
 
  26         super().__init__(field, request, params, model, model_admin, field_path)
 
  28     def queryset(self, request, queryset):
 
  29         if self.lookup_kwarg not in self.used_parameters:
 
  31         if self.lookup_val not in ('0', '1'):
 
  32             raise IncorrectLookupParameters
 
  34         lookup_condition = Q(**{'%s__isnull' % self.field_path: True})
 
  35         if self.with_empty_str:
 
  36             lookup_condition |= Q(**{self.field_path: ''})
 
  37         if self.lookup_val == '1':
 
  38             return queryset.filter(lookup_condition)
 
  39         return queryset.exclude(lookup_condition)
 
  41     def expected_parameters(self):
 
  42         return [self.lookup_kwarg]
 
  44     def choices(self, changelist):
 
  45         for lookup, title in (
 
  48             ('0', _('Not empty')),
 
  51                 'selected': self.lookup_val == lookup,
 
  52                 'query_string': changelist.get_query_string({self.lookup_kwarg: lookup}),
 
  57 class PayedListFilter(SimpleListFilter):
 
  59     parameter_name = 'payed'
 
  60     def lookups(self, request, model_admin):
 
  66     def queryset(self, request, queryset):
 
  67         if self.value() == 'yes':
 
  68             return queryset.filter(payment__is_dd=True, payment__realised=True).distinct()
 
  69         if self.value() == 'no':
 
  70             return queryset.exclude(payment__is_dd=True, payment__realised=True).distinct()
 
  74 class BankExportFeedbackLineInline(admin.TabularInline):
 
  75     model = models.BankExportFeedbackLine
 
  78 class BankPaymentInline(admin.TabularInline):
 
  79     model = models.Payment
 
  82 @admin.register(models.DirectDebit)
 
  83 class DirectDebitAdmin(admin.ModelAdmin):
 
  85         'payment_id', 'acquisition_date',
 
  88         'bank_submission_date',
 
  89         'bank_acceptance_date',
 
  90         'amount', 'first_name', 'last_name',
 
  92     date_hierarchy = 'acquisition_date'
 
  94         'payment_id', 'first_name', 'last_name', 'street', 'building', 'town', 'flat',
 
  95         'phone', 'email', 'iban',
 
 105         ('cancelled_at', EmptyFieldListFilter),
 
 112         ('fundraiser_commission', EmptyFieldListFilter),
 
 113         ('fundraiser_bonus', EmptyFieldListFilter),
 
 119                 ('first_name', 'sex', 'date_of_birth'),
 
 121                 ('street', 'building'),
 
 123                 ('postal_code', 'phone'),
 
 125                 ('iban', 'iban_valid', 'iban_warning'),
 
 126                 ('payment_id', 'latest_status'),
 
 130                 ('acquisition_date', 'amount'),
 
 136         (_('Processing'), {"fields": [
 
 137             ('cancelled_at', 'needs_redo', 'optout'),
 
 139             'fundraiser_commission',
 
 142             'bank_submission_date',
 
 143             'bank_acceptance_date',
 
 148     readonly_fields = ['agree_contact', 'iban_valid', 'iban_warning', 'latest_status']
 
 149     inlines = [BankExportFeedbackLineInline, BankPaymentInline]
 
 151     def set_bank_submission(m, r, q):
 
 152         q.update(bank_submission_date=now())
 
 154     def create_bank_order(m, request, queryset):
 
 155         bo = models.BankOrder.objects.create()
 
 156         bo.debits.set(queryset)
 
 157         messages.info(request, mark_safe(
 
 158             '<a href="{}">Bank order</a> created.'.format(
 
 159                 reverse('admin:pz_bankorder_change', args=[bo.pk])
 
 168         export_as_csv_action(),
 
 171     def agree_contact(self, obj):
 
 172         return _('obligatory')
 
 173     agree_contact.short_description = _('agree contact')
 
 175     def get_changeform_initial_data(self, request):
 
 177             'payment_id': models.DirectDebit.get_next_payment_id(),
 
 181 @admin.register(models.BankExportFeedback)
 
 182 class BankExportFeedbackAdmin(admin.ModelAdmin):
 
 183     inlines = [BankExportFeedbackLineInline, BankPaymentInline]
 
 187 @admin.register(models.BankOrder)
 
 188 class BankOrderAdmin(admin.ModelAdmin):
 
 189     fields = ['payment_date', 'debits', 'sent', 'download']
 
 190     filter_horizontal = ['debits']
 
 192     def get_readonly_fields(self, request, obj=None):
 
 193         fields = ['download']
 
 194         if obj is not None and obj.sent:
 
 195             fields += ['debits', 'payment_date']
 
 198     def download(self, obj):
 
 199         if obj is not None and obj.pk:
 
 200             return mark_safe('<a href="{}">Download</a>'.format(
 
 201                 reverse('admin:pz_bankorder_download', args=[obj.pk])
 
 207         urls = super().get_urls()
 
 210                 '<int:pk>/download/',
 
 211                 self.admin_site.admin_view(self.download_view),
 
 212                 name='pz_bankorder_download',
 
 215         return my_urls + urls
 
 217     def download_view(self, request, pk):
 
 218         order = get_object_or_404(
 
 219             models.BankOrder, pk=pk)
 
 221             return bank.bank_order(
 
 226         except Exception as e:
 
 227             messages.error(request, str(e))
 
 228             return redirect('admin:pz_bankorder_change', pk)