lingo: allow requiring individual payment for regie (#46503)
This commit is contained in:
parent
3faa37405b
commit
4ff5f921c1
|
@ -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',
|
||||
'can_pay_only_one_basket_item']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RegieForm, self).__init__(*args, **kwargs)
|
||||
|
@ -107,6 +108,12 @@ class RegieForm(forms.ModelForm):
|
|||
instance.save()
|
||||
return instance
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
if cleaned_data['webservice_url'] and cleaned_data['can_pay_only_one_basket_item']:
|
||||
raise ValidationError('Individual item payment is incompatible with remote regie.')
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class PaymentBackendForm(forms.ModelForm):
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.18 on 2020-10-01 11:53
|
||||
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='can_pay_only_one_basket_item',
|
||||
field=models.BooleanField(default=False, verbose_name='Basket items must be paid individually'),
|
||||
),
|
||||
]
|
|
@ -145,6 +145,9 @@ 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'))
|
||||
can_pay_only_one_basket_item = models.BooleanField(
|
||||
default=False, verbose_name=_('Basket items must be paid individually')
|
||||
)
|
||||
|
||||
def is_remote(self):
|
||||
return self.webservice_url != ''
|
||||
|
|
|
@ -4,22 +4,31 @@
|
|||
<h2>{% trans "Basket" %}</h2>
|
||||
{% for regie_info in regies %}
|
||||
{% if regies|length != 1 %}<h3 class="regie-name">{{regie_info.regie.label}}</h3>{% endif %}
|
||||
<form action="{% url 'lingo-pay' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next_url" value="{{ cell.page.get_online_url }}" />
|
||||
<input type="hidden" name="regie" value="{{regie_info.regie.id}}" />
|
||||
<ul>
|
||||
<ul class="payment-items">
|
||||
{% for item in regie_info.items %}
|
||||
<li><a {% if item.source_url %}href="{{ item.source_url }}{% endif %}">{{ item.subject }}</a>: {{ item.amount }} €
|
||||
{% if item.user_cancellable %}
|
||||
<a rel="popup" href="{% url 'lingo-cancel-item' pk=item.id %}">({% trans 'remove' %})</a>
|
||||
{% endif %}
|
||||
{% if regie_info.regie.can_pay_only_one_basket_item %}
|
||||
<a id="{{ item.pk }}" class="button individual-item" href="{{ item.payment_url }}?next_url={{ cell.page.get_online_url }}">{% trans "Pay" %}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if not regie_info.regie.can_pay_only_one_basket_item %}
|
||||
<li><strong>{% trans "Total:" %}</strong> {{ regie_info.total }} €</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
{% if not regie_info.regie.can_pay_only_one_basket_item %}
|
||||
<form action="{% url 'lingo-pay' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next_url" value="{{ cell.page.get_online_url }}" />
|
||||
<input type="hidden" name="regie" value="{{regie_info.regie.id}}" />
|
||||
<button>{% trans "Pay" %}</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -457,6 +457,10 @@ class PayView(PayMixin, View):
|
|||
regie.compute_extra_fees(user=user)
|
||||
items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
|
||||
|
||||
if regie.can_pay_only_one_basket_item 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
|
||||
for item in items:
|
||||
|
|
|
@ -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_can_pay_only_one_basket_item(regie, user):
|
||||
regie.can_pay_only_one_basket_item = 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 item.payment_url 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()
|
||||
|
|
|
@ -1531,3 +1531,26 @@ 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_can_pay_only_one_basket_item(app, basket_page, regie, user):
|
||||
regie.can_pay_only_one_basket_item = 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
|
||||
|
||||
resp = resp.click('Pay', href=item.payment_url)
|
||||
|
||||
# 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
|
||||
|
|
Loading…
Reference in New Issue