From 56473ff16fbbc5bea6460fe357cf9b264cbea700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sun, 28 May 2017 12:47:24 +0200 Subject: [PATCH] lingo: add possibility to compute extra fees (#16065) --- .../lingo/migrations/0029_auto_20170528_1334.py | 34 ++++++++++ combo/apps/lingo/models.py | 44 +++++++++++++ combo/apps/lingo/templates/lingo/combo/basket.html | 2 +- combo/apps/lingo/views.py | 8 +++ tests/test_lingo_payment.py | 74 +++++++++++++++++++++- 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 combo/apps/lingo/migrations/0029_auto_20170528_1334.py diff --git a/combo/apps/lingo/migrations/0029_auto_20170528_1334.py b/combo/apps/lingo/migrations/0029_auto_20170528_1334.py new file mode 100644 index 0000000..92e0531 --- /dev/null +++ b/combo/apps/lingo/migrations/0029_auto_20170528_1334.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import jsonfield.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('lingo', '0028_tipipaymentformcell'), + ] + + operations = [ + migrations.AlterModelOptions( + name='basketitem', + options={'ordering': ['regie', 'extra_fee', 'subject']}, + ), + migrations.AddField( + model_name='basketitem', + name='extra_fee', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='basketitem', + name='request_data', + field=jsonfield.fields.JSONField(default=dict, blank=True), + ), + migrations.AddField( + model_name='regie', + name='extra_fees_ws_url', + field=models.URLField(verbose_name='Webservice URL to compute extra fees', blank=True), + ), + ] diff --git a/combo/apps/lingo/models.py b/combo/apps/lingo/models.py index 5b6549a..d616e05 100644 --- a/combo/apps/lingo/models.py +++ b/combo/apps/lingo/models.py @@ -83,6 +83,8 @@ class Regie(models.Model): is_default = models.BooleanField(verbose_name=_('Default Regie'), default=False) webservice_url = models.URLField(_('Webservice URL to retrieve remote items'), blank=True) + extra_fees_ws_url = models.URLField(_('Webservice URL to compute extra fees'), + blank=True) payment_min_amount = models.DecimalField(_('Minimal payment amount'), max_digits=7, decimal_places=2, default=0) @@ -167,6 +169,39 @@ class Regie(models.Model): 'text': self.label, 'description': self.description} + def compute_extra_fees(self, user): + if not self.extra_fees_ws_url: + return + post_data = {'data': []} + basketitems = BasketItem.objects.filter( + user=user, regie=self, + cancellation_date__isnull=True, + payment_date__isnull=True) + for basketitem in basketitems.filter(extra_fee=False): + basketitem_data = { + 'subject': basketitem.subject, + 'source_url': basketitem.source_url, + 'details': basketitem.details, + 'amount': basketitem.amount, + 'request_data': basketitem.request_data + } + post_data['data'].append(basketitem_data) + if not post_data['data']: + basketitems.filter(extra_fee=True).delete() + return + response = requests.post(self.extra_fees_ws_url, remote_service='auto') + if response.status_code != 200 or response.json().get('err'): + logger = logging.getLogger(__name__) + logger.error('failed to compute extra frees (user: %r)', user) + return + basketitems.filter(extra_fee=True).delete() + for extra_fee in response.json().get('data'): + BasketItem(user=user, regie=self, + subject=extra_fee.get('subject'), + amount=extra_fee.get('amount'), + extra_fee=True, + user_cancellable=False).save() + class BasketItem(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True) @@ -176,13 +211,20 @@ class BasketItem(models.Model): details = models.TextField(verbose_name=_('Details'), blank=True) amount = models.DecimalField(verbose_name=_('Amount'), decimal_places=2, max_digits=8) + request_data = JSONField(blank=True) + extra_fee = models.BooleanField(default=False) user_cancellable = models.BooleanField(default=True) creation_date = models.DateTimeField(auto_now_add=True) cancellation_date = models.DateTimeField(null=True) payment_date = models.DateTimeField(null=True) notification_date = models.DateTimeField(null=True) + class Meta: + ordering = ['regie', 'extra_fee', 'subject'] + def notify(self, status): + if not self.source_url: + return url = self.source_url + 'jump/trigger/%s' % status message = {'result': 'ok'} if status == 'paid': @@ -200,12 +242,14 @@ class BasketItem(models.Model): self.notify('paid') self.notification_date = timezone.now() self.save() + self.regie.compute_extra_fees(user=self.user) def notify_cancellation(self, notify_origin=False): if notify_origin: self.notify('cancelled') self.cancellation_date = timezone.now() self.save() + self.regie.compute_extra_fees(user=self.user) @property def total_amount(self): diff --git a/combo/apps/lingo/templates/lingo/combo/basket.html b/combo/apps/lingo/templates/lingo/combo/basket.html index 1098f6d..4e34dc7 100644 --- a/combo/apps/lingo/templates/lingo/combo/basket.html +++ b/combo/apps/lingo/templates/lingo/combo/basket.html @@ -8,7 +8,7 @@