from django.contrib import admin
from django.utils.translation import gettext_lazy as _
+from django.utils.timezone import now
+from fnpdjango.actions import export_as_csv_action
+from . import bank
from . import models
@admin.register(models.DirectDebit)
class DirectDebitAdmin(admin.ModelAdmin):
- list_display = ['acquisition_date', 'amount', 'first_name', 'last_name']
+ list_display = [
+ 'payment_id', 'acquisition_date',
+ 'iban_valid',
+ 'bank_submission_date',
+ 'bank_acceptance_date',
+ 'amount', 'first_name', 'last_name',
+ ]
+ date_hierarchy = 'acquisition_date'
+ search_fields = [
+ 'payment_id', 'first_name', 'last_name', 'street', 'building', 'town', 'flat',
+ 'phone', 'email', 'iban',
+ 'notes',
+ 'fundraiser_bill',
+ ]
+ list_filter = [
+ 'iban_valid',
+ 'agree_fundraising',
+ 'agree_newsletter',
+ 'fundraiser',
+ 'campaign',
+ 'is_cancelled',
+ 'needs_redo',
+ 'optout',
+ 'amount',
+ 'sex',
+ 'is_consumer',
+ ]
fieldsets = [
(None, {
"fields": [
('town', 'flat'),
('postal_code', 'phone'),
'email',
- 'iban',
+ ('iban', 'iban_valid', 'iban_warning'),
'payment_id',
'agree_contact',
'agree_fundraising',
]
})
]
- readonly_fields = ['agree_contact']
+ readonly_fields = ['agree_contact', 'iban_valid', 'iban_warning']
+
+ def set_bank_submission(m,r,q):
+ q.update(bank_submission_date=now())
+ actions = [
+ bank.bank_export,
+ set_bank_submission,
+ export_as_csv_action(),
+ ]
def agree_contact(self, obj):
return _('obligatory')
--- /dev/null
+import csv
+from django.http import HttpResponse
+from django.utils.translation import ugettext_lazy as _
+
+
+def bank_export(modeladmin, request, queryset):
+ response = HttpResponse(content_type='text/csv; charset=cp1250')
+ response['Content-Disposition'] = 'attachment; filename=export.csv'
+ writer = csv.writer(response)
+ writer.writerow([
+ 'Identyfikator płatności (IDP)',
+ 'Nazwa Płatnika',
+ 'Adres Płatnika Ulica + numer domu',
+ 'Adres Płatnika kod+miejscowość',
+ 'Numer kierunkowy banku Płatnika',
+ 'Numer rachunku bankowego Płatnika',
+ 'Identyfikator Odbiorcy (NIP Odbiorcy)',
+ 'Osobowość prawna Płatnika (Osoba fizyczna)'
+ ])
+
+ # TODO: ansi encoding
+
+ for obj in queryset:
+ street_addr = obj.street
+ if obj.building:
+ street_addr += ' ' + obj.building
+ if obj.flat:
+ street_addr += ' m. ' + obj.flat
+ street_addr = street_addr.strip()
+ writer.writerow([
+ obj.payment_id,
+ ' '.join([obj.first_name, obj.last_name]).strip(),
+ street_addr,
+ ' '.join([obj.postal_code, obj.town]).strip(),
+ obj.iban[2:10],
+ obj.iban,
+ '9521877087',
+ 'OF'
+ ])
+ return response
--- /dev/null
+# Generated by Django 2.2.19 on 2021-09-28 19:16
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pz', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='directdebit',
+ name='acquisition_date',
+ field=models.DateField(blank=True, help_text='Date from the form', null=True, verbose_name='acquisition date'),
+ ),
+ migrations.AlterField(
+ model_name='directdebit',
+ name='agree_fundraising',
+ field=models.BooleanField(default=False, verbose_name='agree fundraising'),
+ ),
+ migrations.AlterField(
+ model_name='directdebit',
+ name='agree_newsletter',
+ field=models.BooleanField(default=False, verbose_name='agree newsletter'),
+ ),
+ migrations.AlterField(
+ model_name='directdebit',
+ name='amount',
+ field=models.IntegerField(blank=True, null=True, verbose_name='amount'),
+ ),
+ migrations.AlterField(
+ model_name='directdebit',
+ name='campaign',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='pz.Campaign', verbose_name='campaign'),
+ ),
+ migrations.AlterField(
+ model_name='directdebit',
+ name='fundraiser',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='pz.Fundraiser', verbose_name='fundraiser'),
+ ),
+ ]
--- /dev/null
+# Generated by Django 2.2.19 on 2021-09-29 17:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pz', '0002_auto_20210928_2116'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='directdebit',
+ name='iban_valid',
+ field=models.BooleanField(default=False, verbose_name='IBAN valid'),
+ ),
+ ]
--- /dev/null
+# Generated by Django 2.2.19 on 2021-09-29 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pz', '0003_directdebit_iban_valid'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='directdebit',
+ name='iban_valid',
+ field=models.NullBooleanField(default=False, verbose_name='IBAN valid'),
+ ),
+ ]
phone = models.CharField(_('phone'), max_length=255, blank=True)
email = models.CharField(_('e-mail'), max_length=255, blank=True)
iban = models.CharField(_('IBAN'), max_length=255, blank=True)
+ iban_valid = models.NullBooleanField(_('IBAN valid'), default=False)
is_consumer = models.BooleanField(_('is a consumer'), default=True)
payment_id = models.CharField(_('payment identifier'), max_length=255, blank=True, unique=True)
- agree_fundraising = models.BooleanField(_('agree fundraising'))
- agree_newsletter = models.BooleanField(_('agree newsletter'))
+ agree_fundraising = models.BooleanField(_('agree fundraising'), default=False)
+ agree_newsletter = models.BooleanField(_('agree newsletter'), default=False)
- acquisition_date = models.DateField(_('acquisition date'), help_text=_('Date from the form'))
+ acquisition_date = models.DateField(_('acquisition date'), help_text=_('Date from the form'), null=True, blank=True)
submission_date = models.DateField(_('submission date'), null=True, blank=True, help_text=_('Date the fundaiser submitted the form'))
bank_submission_date = models.DateField(_('bank submission date'), null=True, blank=True, help_text=_('Date when the form data is submitted to the bank'))
bank_acceptance_date = models.DateField(_('bank accepted date'), null=True, blank=True, help_text=_('Date when bank accepted the form'))
fundraiser_commission = models.IntegerField(_('fundraiser commission'), null=True, blank=True)
fundraiser_bill = models.CharField(_('fundaiser bill number'), max_length=255, blank=True)
- amount = models.IntegerField(_('amount'))
+ amount = models.IntegerField(_('amount'), null=True, blank=True)
notes = models.TextField(_('notes'), blank=True)
verbose_name = _('direct debit')
verbose_name_plural = _('direct debits')
+ def save(self, **kwargs):
+ self.iban_valid = not self.iban_warning() if self.iban else None
+ super().save(**kwargs)
+
@classmethod
def get_next_payment_id(cls):
# Find the last object added.
break
return payment_id
+ def iban_warning(self):
+ if not self.iban:
+ return 'No IBAN'
+ if len(self.iban) != 26:
+ return 'Bad IBAN length'
+ if int(self.iban[2:] + '2521' + self.iban[:2]) % 97 != 1:
+ return 'This IBAN number looks invalid'
+ return ''
+ iban_warning.short_description = ''