Projet

Général

Profil

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

Valentin Deniaud, 30 septembre 2020 18:19

Télécharger (7,85 ko)

Voir les différences:

Subject: [PATCH 4/4] 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                    |  3 +++
 .../lingo/templates/lingo/combo/basket.html   | 19 +++++++++++----
 combo/apps/lingo/views.py                     |  4 ++++
 tests/test_lingo_cells.py                     | 19 +++++++++++++++
 tests/test_lingo_payment.py                   | 23 +++++++++++++++++++
 7 files changed, 85 insertions(+), 6 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-30 16:10
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='Basket items must be paid individually'),
19
        ),
20
    ]
combo/apps/lingo/models.py
145 145
    payment_backend = models.ForeignKey(
146 146
        PaymentBackend, on_delete=models.CASCADE, verbose_name=_('Payment backend'))
147 147
    transaction_options = JSONField(blank=True, verbose_name=_('Transaction Options'))
148
    individual_payment = models.BooleanField(
149
        default=False, verbose_name=_('Basket items must be paid individually')
150
    )
148 151

  
149 152
    def is_remote(self):
150 153
        return self.webservice_url != ''
combo/apps/lingo/templates/lingo/combo/basket.html
4 4
<h2>{% trans "Basket" %}</h2>
5 5
{% for regie_info in regies %}
6 6
{% if regies|length != 1 %}<h3 class="regie-name">{{regie_info.regie.label}}</h3>{% endif %}
7
<form action="{% url 'lingo-pay' %}" method="POST">
8
{% csrf_token %}
9
<input type="hidden" name="next_url" value="{{ cell.page.get_online_url }}" />
10
<input type="hidden" name="regie" value="{{regie_info.regie.id}}" />
11
<ul>
7
<ul class="payment-items">
12 8
  {% for item in regie_info.items %}
13 9
  <li><a {% if item.source_url %}href="{{ item.source_url }}{% endif %}">{{ item.subject }}</a>: {{ item.amount }} €
14 10
          {% if item.user_cancellable %}
15 11
          <a rel="popup" href="{% url 'lingo-cancel-item' pk=item.id %}">({% trans 'remove' %})</a>
16 12
          {% endif %}
13
          {% if regie_info.regie.individual_payment %}
14
          <a id="{{ item.pk }}" class="button individual-item" href="{{ item.payment_url }}?next_url={{ cell.page.get_online_url }}">{% trans "Pay" %}</a>
15
          {% endif %}
17 16
  </li>
18 17
  {% endfor %}
18
  {% if not regie_info.regie.individual_payment %}
19 19
  <li><strong>{% trans "Total:" %}</strong> {{ regie_info.total }} €</li>
20
  {% endif %}
20 21
</ul>
22

  
23
{% if not regie_info.regie.individual_payment %}
24
<form action="{% url 'lingo-pay' %}" method="POST">
25
{% csrf_token %}
26
<input type="hidden" name="next_url" value="{{ cell.page.get_online_url }}" />
27
<input type="hidden" name="regie" value="{{regie_info.regie.id}}" />
21 28
<button>{% trans "Pay" %}</button>
22 29
</form>
30
{% endif %}
31

  
23 32
{% endfor %}
24 33
{% endif %}
25 34
{% endblock %}
combo/apps/lingo/views.py
457 457
            regie.compute_extra_fees(user=user)
458 458
            items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
459 459

  
460
            if regie.individual_payment and len(items) > 1:
461
                messages.error(request, _('Grouping basket items is not allowed.'))
462
                return HttpResponseRedirect(next_url)
463

  
460 464
        if items:
461 465
            capture_date = items[0].capture_date
462 466
            for item in items:
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 item.payment_url 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
    resp = resp.click('Pay', href=item.payment_url)
1547

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

  
1554
    resp = app.get('/test_basket_cell/')
1555
    assert 'foo item' not in resp.text
1556
    assert 'bar item' in resp.text
1534
-