Projet

Général

Profil

0002-lingo-allow-requiring-individual-payment-for-regie-4.patch

Valentin Deniaud, 23 septembre 2020 18:00

Télécharger (8,31 ko)

Voir les différences:

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
combo/apps/lingo/forms.py
87 87
    class Meta:
88 88
        model = Regie
89 89
        fields = ['label', 'slug', 'description', 'payment_backend', 'is_default',
90
                  'webservice_url', 'extra_fees_ws_url', 'payment_min_amount', 'text_on_success']
90
                  'webservice_url', 'extra_fees_ws_url', 'payment_min_amount', 'text_on_success',
91
                  'individual_payment']
91 92

  
92 93
    def __init__(self, *args, **kwargs):
93 94
        super(RegieForm, self).__init__(*args, **kwargs)
combo/apps/lingo/migrations/0041_regie_individual_payment.py
1
# -*- coding: utf-8 -*-
2
# Generated by Django 1.11.18 on 2020-09-23 12:46
3
from __future__ import unicode_literals
4

  
5
from django.db import migrations, models
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('lingo', '0040_auto_20200608_1222'),
12
    ]
13

  
14
    operations = [
15
        migrations.AddField(
16
            model_name='regie',
17
            name='individual_payment',
18
            field=models.BooleanField(default=False, verbose_name='Indiviual payment'),
19
        ),
20
    ]
combo/apps/lingo/models.py
143 143
    payment_backend = models.ForeignKey(
144 144
        PaymentBackend, on_delete=models.CASCADE, verbose_name=_('Payment backend'))
145 145
    transaction_options = JSONField(blank=True, verbose_name=_('Transaction Options'))
146
    individual_payment = models.BooleanField(default=False, verbose_name=_('Indiviual payment'))
146 147

  
147 148
    def is_remote(self):
148 149
        return self.webservice_url != ''
combo/apps/lingo/templates/lingo/combo/basket.html
14 14
          {% if item.user_cancellable %}
15 15
          <a rel="popup" href="{% url 'lingo-cancel-item' pk=item.id %}">({% trans 'remove' %})</a>
16 16
          {% endif %}
17
          {% if regie_info.regie.individual_payment %}
18
          <button id="{{ item.pk }}" formaction="{% url 'lingo-pay' item_pk=item.pk %}">{% trans "Pay" %}</button>
19
          {% endif %}
17 20
  </li>
18 21
  {% endfor %}
19
  <li><strong>{% trans "Total:" %}</strong> {{ regie_info.total }} €</li>
20 22
</ul>
23
{% if not regie_info.regie.individual_payment %}
24
<p class="lingo-total"><strong>{% trans "Total:" %}</strong> {{ regie_info.total }} €</p>
21 25
<button>{% trans "Pay" %}</button>
26
{% endif %}
22 27
</form>
23 28
{% endfor %}
24 29
{% endif %}
combo/apps/lingo/urls.py
66 66
        name='api-transaction-status'
67 67
    ),
68 68
    url(r'^lingo/pay$', PayView.as_view(), name='lingo-pay'),
69
    url(r'^lingo/pay/(?P<item_pk>\w+)/$$', PayView.as_view(), name='lingo-pay'),
69 70
    url(r'^lingo/cancel/(?P<pk>\w+)/$', CancelItemView.as_view(), name='lingo-cancel-item'),
70 71
    url(r'^lingo/callback/(?P<regie_pk>\w+)/$', CallbackView.as_view(), name='lingo-callback'),
71 72
    url(r'^lingo/callback-payment-backend/(?P<payment_backend_pk>\w+)/$',
combo/apps/lingo/views.py
470 470
            regie = Regie.objects.get(id=regie_id)
471 471
            regie.compute_extra_fees(user=user)
472 472
            items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
473
            if 'item_pk' in kwargs:
474
                items = items.filter(pk=kwargs['item_pk'])
475

  
476
            if regie.individual_payment and len(items) > 1:
477
                messages.error(request, _('Grouping basket items is not allowed.'))
478
                return HttpResponseRedirect(next_url)
473 479

  
474 480
        if items:
475 481
            capture_date = items[0].capture_date
tests/test_lingo_cells.py
95 95
    item.save()
96 96
    assert cell.get_badge(context) == {'badge': u'123.45€'}
97 97

  
98
def test_basket_cell_individual_payment(regie, user):
99
    regie.individual_payment = True
100
    regie.save()
101
    page = Page(title='xxx', slug='test_basket_cell', template_name='standard')
102
    page.save()
103
    cell = LingoBasketCell(page=page, placeholder='content', order=0)
104

  
105
    item  = BasketItem.objects.create(user=user, regie=regie, subject='foo', amount=123)
106
    item2  = BasketItem.objects.create(user=user, regie=regie, subject='bar', amount=123)
107

  
108
    context = {'request': RequestFactory(user=user).get('/')}
109
    context['request'].user = user
110
    assert cell.is_relevant(context)
111

  
112
    content = cell.render(context)
113
    assert content.count('Pay') == 2
114
    assert '/lingo/pay/%s/' % item.pk in content
115
    assert not 'Total' in content
116

  
98 117
def test_recent_transaction_cell(regie, user):
99 118
    page = Page(title='xxx', slug='test_basket_cell', template_name='standard')
100 119
    page.save()
tests/test_lingo_payment.py
1531 1531
    else:
1532 1532
        assert transaction.bank_transaction_date == transaction_date
1533 1533
        assert 'new transaction_date for transaction' in caplog.text
1534

  
1535

  
1536
def test_successfull_items_individual_payment(app, basket_page, regie, user):
1537
    regie.individual_payment = True
1538
    regie.save()
1539
    item = BasketItem.objects.create(user=user, regie=regie, amount=42, subject='foo item')
1540
    item2 = BasketItem.objects.create(user=user, regie=regie, amount=84, subject='bar item')
1541

  
1542
    resp = login(app).get('/test_basket_cell/')
1543
    assert 'foo item' in resp.text
1544
    assert 'bar item' in resp.text
1545

  
1546
    # webtest does not support html5 forms, need to do submit by hand
1547
    form_data = dict(resp.form.submit_fields())
1548
    submit_url = resp.pyquery.find('#%s' % item.pk).attr('formaction')
1549
    resp = app.post(submit_url, params=form_data)
1550

  
1551
    # successful payment
1552
    qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query)
1553
    args = {'transaction_id': qs['transaction_id'][0], 'signed': True, 'ok': True, 'reason': 'Paid'}
1554
    with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
1555
        resp = app.get(get_url(True, 'lingo-callback', regie), params=args)
1556

  
1557
    resp = app.get('/test_basket_cell/')
1558
    assert 'foo item' not in resp.text
1559
    assert 'bar item' in resp.text
tox.ini
32 32
  vobject
33 33
  django-ratelimit<3
34 34
  git+http://git.entrouvert.org/debian/django-ckeditor.git
35
  pyquery
35 36
commands =
36 37
  ./getlasso3.sh
37 38
  python manage.py compilemessages
38
-