From d6293dbfd11125a6153b411b1bdff0e9608e42a9 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 23 Sep 2020 14:29:19 +0200 Subject: [PATCH 2/2] lingo: allow requiring individual payment for regie (#46503) --- combo/apps/lingo/forms.py | 3 ++- .../0041_regie_individual_payment.py | 20 ++++++++++++++ combo/apps/lingo/models.py | 1 + .../lingo/templates/lingo/combo/basket.html | 7 ++++- combo/apps/lingo/urls.py | 1 + combo/apps/lingo/views.py | 6 +++++ tests/test_lingo_cells.py | 19 ++++++++++++++ tests/test_lingo_payment.py | 26 +++++++++++++++++++ tox.ini | 1 + 9 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 combo/apps/lingo/migrations/0041_regie_individual_payment.py diff --git a/combo/apps/lingo/forms.py b/combo/apps/lingo/forms.py index fe50a253..aa6a7775 100644 --- a/combo/apps/lingo/forms.py +++ b/combo/apps/lingo/forms.py @@ -87,7 +87,8 @@ class RegieForm(forms.ModelForm): class Meta: model = Regie fields = ['label', 'slug', 'description', 'payment_backend', 'is_default', - 'webservice_url', 'extra_fees_ws_url', 'payment_min_amount', 'text_on_success'] + 'webservice_url', 'extra_fees_ws_url', 'payment_min_amount', 'text_on_success', + 'individual_payment'] def __init__(self, *args, **kwargs): super(RegieForm, self).__init__(*args, **kwargs) diff --git a/combo/apps/lingo/migrations/0041_regie_individual_payment.py b/combo/apps/lingo/migrations/0041_regie_individual_payment.py new file mode 100644 index 00000000..f42d65d4 --- /dev/null +++ b/combo/apps/lingo/migrations/0041_regie_individual_payment.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.18 on 2020-09-23 12:46 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lingo', '0040_auto_20200608_1222'), + ] + + operations = [ + migrations.AddField( + model_name='regie', + name='individual_payment', + field=models.BooleanField(default=False, verbose_name='Indiviual payment'), + ), + ] diff --git a/combo/apps/lingo/models.py b/combo/apps/lingo/models.py index 07def1de..c8f0bbc6 100644 --- a/combo/apps/lingo/models.py +++ b/combo/apps/lingo/models.py @@ -143,6 +143,7 @@ class Regie(models.Model): payment_backend = models.ForeignKey( PaymentBackend, on_delete=models.CASCADE, verbose_name=_('Payment backend')) transaction_options = JSONField(blank=True, verbose_name=_('Transaction Options')) + individual_payment = models.BooleanField(default=False, verbose_name=_('Indiviual payment')) def is_remote(self): return self.webservice_url != '' diff --git a/combo/apps/lingo/templates/lingo/combo/basket.html b/combo/apps/lingo/templates/lingo/combo/basket.html index ae0fd1b9..58f96d35 100644 --- a/combo/apps/lingo/templates/lingo/combo/basket.html +++ b/combo/apps/lingo/templates/lingo/combo/basket.html @@ -14,11 +14,16 @@ {% if item.user_cancellable %} ({% trans 'remove' %}) {% endif %} + {% if regie_info.regie.individual_payment %} + + {% endif %} {% endfor %} -
  • {% trans "Total:" %} {{ regie_info.total }} €
  • +{% if not regie_info.regie.individual_payment %} +

    {% trans "Total:" %} {{ regie_info.total }} €

    +{% endif %} {% endfor %} {% endif %} diff --git a/combo/apps/lingo/urls.py b/combo/apps/lingo/urls.py index e69d1b75..c0867595 100644 --- a/combo/apps/lingo/urls.py +++ b/combo/apps/lingo/urls.py @@ -66,6 +66,7 @@ urlpatterns = [ name='api-transaction-status' ), url(r'^lingo/pay$', PayView.as_view(), name='lingo-pay'), + url(r'^lingo/pay/(?P\w+)/$$', PayView.as_view(), name='lingo-pay'), url(r'^lingo/cancel/(?P\w+)/$', CancelItemView.as_view(), name='lingo-cancel-item'), url(r'^lingo/callback/(?P\w+)/$', CallbackView.as_view(), name='lingo-callback'), url(r'^lingo/callback-payment-backend/(?P\w+)/$', diff --git a/combo/apps/lingo/views.py b/combo/apps/lingo/views.py index 924788ba..4236d30e 100644 --- a/combo/apps/lingo/views.py +++ b/combo/apps/lingo/views.py @@ -470,6 +470,12 @@ class PayView(PayMixin, View): regie = Regie.objects.get(id=regie_id) regie.compute_extra_fees(user=user) items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie) + if 'item_pk' in kwargs: + items = items.filter(pk=kwargs['item_pk']) + + if regie.individual_payment and len(items) > 1: + messages.error(request, _('Grouping basket items is not allowed.')) + return HttpResponseRedirect(next_url) if items: capture_date = items[0].capture_date diff --git a/tests/test_lingo_cells.py b/tests/test_lingo_cells.py index 744fecbe..3734cc57 100644 --- a/tests/test_lingo_cells.py +++ b/tests/test_lingo_cells.py @@ -95,6 +95,25 @@ def test_basket_cell(regie, user): item.save() assert cell.get_badge(context) == {'badge': u'123.45€'} +def test_basket_cell_individual_payment(regie, user): + regie.individual_payment = True + regie.save() + page = Page(title='xxx', slug='test_basket_cell', template_name='standard') + page.save() + cell = LingoBasketCell(page=page, placeholder='content', order=0) + + item = BasketItem.objects.create(user=user, regie=regie, subject='foo', amount=123) + item2 = BasketItem.objects.create(user=user, regie=regie, subject='bar', amount=123) + + context = {'request': RequestFactory(user=user).get('/')} + context['request'].user = user + assert cell.is_relevant(context) + + content = cell.render(context) + assert content.count('Pay') == 2 + assert '/lingo/pay/%s/' % item.pk in content + assert not 'Total' in content + def test_recent_transaction_cell(regie, user): page = Page(title='xxx', slug='test_basket_cell', template_name='standard') page.save() diff --git a/tests/test_lingo_payment.py b/tests/test_lingo_payment.py index 3f12ac9f..0f49a0d8 100644 --- a/tests/test_lingo_payment.py +++ b/tests/test_lingo_payment.py @@ -1531,3 +1531,29 @@ def test_bank_transaction_date(app, key, regie, user, john_doe, caplog, transact else: assert transaction.bank_transaction_date == transaction_date assert 'new transaction_date for transaction' in caplog.text + + +def test_successfull_items_individual_payment(app, basket_page, regie, user): + regie.individual_payment = True + regie.save() + item = BasketItem.objects.create(user=user, regie=regie, amount=42, subject='foo item') + item2 = BasketItem.objects.create(user=user, regie=regie, amount=84, subject='bar item') + + resp = login(app).get('/test_basket_cell/') + assert 'foo item' in resp.text + assert 'bar item' in resp.text + + # webtest does not support html5 forms, need to do submit by hand + form_data = dict(resp.form.submit_fields()) + submit_url = resp.pyquery.find('#%s' % item.pk).attr('formaction') + resp = app.post(submit_url, params=form_data) + + # successful payment + qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query) + args = {'transaction_id': qs['transaction_id'][0], 'signed': True, 'ok': True, 'reason': 'Paid'} + with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request: + resp = app.get(get_url(True, 'lingo-callback', regie), params=args) + + resp = app.get('/test_basket_cell/') + assert 'foo item' not in resp.text + assert 'bar item' in resp.text diff --git a/tox.ini b/tox.ini index 95ae13dc..b0624ec1 100644 --- a/tox.ini +++ b/tox.ini @@ -32,6 +32,7 @@ deps = vobject django-ratelimit<3 git+http://git.entrouvert.org/debian/django-ckeditor.git + pyquery commands = ./getlasso3.sh python manage.py compilemessages -- 2.20.1