lingo: allow arbitrary date for deferred payment (#27045)
This commit is contained in:
parent
9a0b497f7a
commit
d40cb57e27
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.15 on 2018-10-05 15:33
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('lingo', '0031_basketitem_waiting_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='basketitem',
|
||||
name='capture_date',
|
||||
field=models.DateField(null=True),
|
||||
),
|
||||
]
|
|
@ -327,6 +327,7 @@ class BasketItem(models.Model):
|
|||
waiting_date = models.DateTimeField(null=True)
|
||||
payment_date = models.DateTimeField(null=True)
|
||||
notification_date = models.DateTimeField(null=True)
|
||||
capture_date = models.DateField(null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ['regie', 'extra_fee', 'subject']
|
||||
|
|
|
@ -26,7 +26,7 @@ from django.core.urlresolvers import reverse
|
|||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.http import HttpResponseForbidden, Http404, JsonResponse
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils import timezone
|
||||
from django.utils import timezone, dateparse
|
||||
from django.utils.encoding import force_text
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import View, DetailView, ListView, TemplateView
|
||||
|
@ -161,6 +161,17 @@ class AddBasketItemApiView(View):
|
|||
item.subject = request_body.get('display_name')
|
||||
item.source_url = request_body.get('url') or ''
|
||||
|
||||
if 'capture_date' in request_body:
|
||||
try:
|
||||
# parse_date returns None when the string format is invalid
|
||||
capture_date_err = False
|
||||
item.capture_date = dateparse.parse_date(request_body['capture_date'])
|
||||
except TypeError:
|
||||
capture_date_err = True
|
||||
if item.capture_date is None or capture_date_err:
|
||||
return HttpResponseBadRequest(
|
||||
'Bad format for capture date, it should be yyyy-mm-dd.')
|
||||
|
||||
item.save()
|
||||
item.regie.compute_extra_fees(user=item.user)
|
||||
|
||||
|
@ -328,10 +339,14 @@ class PayMixin(object):
|
|||
transaction.amount = total_amount
|
||||
|
||||
payment = get_eopayment_object(request, regie)
|
||||
|
||||
(order_id, kind, data) = payment.request(total_amount, email=email,
|
||||
first_name=firstname,
|
||||
last_name=lastname)
|
||||
kwargs = {
|
||||
'email': email, 'first_name': firstname, 'last_name': lastname
|
||||
}
|
||||
if items:
|
||||
capture_date = items[0].capture_date
|
||||
if capture_date:
|
||||
kwargs['capture_date'] = capture_date
|
||||
(order_id, kind, data) = payment.request(total_amount, **kwargs)
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info(u'emitted payment request with id %s', smart_text(order_id), extra={
|
||||
'eopayment_order_id': smart_text(order_id), 'eopayment_data': repr(data)})
|
||||
|
@ -382,6 +397,15 @@ class PayView(PayMixin, View):
|
|||
regie.compute_extra_fees(user=user)
|
||||
items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
|
||||
|
||||
if items:
|
||||
capture_date = items[0].capture_date
|
||||
for item in items:
|
||||
if item.capture_date != capture_date:
|
||||
messages.error(
|
||||
request,
|
||||
_(u'Invalid grouping for basket items: different capture dates.'))
|
||||
return HttpResponseRedirect(next_url)
|
||||
|
||||
if not user and not request.POST.get('email'):
|
||||
messages.warning(request, _(u'You must give an email address.'))
|
||||
return HttpResponseRedirect(request.POST.get('item_url'))
|
||||
|
|
|
@ -233,6 +233,71 @@ def test_add_amount_to_basket(app, key, regie, user):
|
|||
resp = app.post_json(url, params=data, status=400)
|
||||
assert resp.text == 'Unknown regie'
|
||||
|
||||
|
||||
def test_basket_item_with_capture_date(app, user, regie, basket_page, monkeypatch):
|
||||
User.objects.get_or_create(email=user.email)
|
||||
url = '%s?email=%s' % (reverse('api-add-basket-item'), user.email)
|
||||
capture_date = timezone.now().date()
|
||||
data = {
|
||||
'amount': 10, 'capture_date': capture_date.isoformat(),
|
||||
'display_name': 'test item'
|
||||
}
|
||||
url = sign_url(url, settings.LINGO_API_SIGN_KEY)
|
||||
resp = app.post_json(url, params=data)
|
||||
assert resp.status_code == 200
|
||||
assert BasketItem.objects.all()[0].capture_date == capture_date
|
||||
|
||||
resp = login(app).get('/test_basket_cell/')
|
||||
import eopayment
|
||||
eopayment_mock = mock.Mock(
|
||||
return_value=('orderid', eopayment.URL, 'http://dummy-payment.demo.entrouvert.com/'))
|
||||
monkeypatch.setattr(eopayment.Payment, 'request', eopayment_mock)
|
||||
resp = resp.form.submit()
|
||||
assert resp.status_code == 302
|
||||
location = urlparse.urlparse(resp.location)
|
||||
assert location.path == '/'
|
||||
assert location.hostname == 'dummy-payment.demo.entrouvert.com'
|
||||
eopayment_mock.assert_called_once_with(
|
||||
Decimal(10), email=user.email, first_name=user.first_name, last_name=user.last_name,
|
||||
capture_date=capture_date)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("invalid_capture_date", [8, '', 'not-a-date'])
|
||||
def test_add_basket_capture_date_format(app, user, regie, invalid_capture_date):
|
||||
url = '%s?email=%s' % (reverse('api-add-basket-item'), user.email)
|
||||
data = {'amount': 10, 'display_name': 'test item'}
|
||||
data['capture_date'] = invalid_capture_date
|
||||
url = sign_url(url, settings.LINGO_API_SIGN_KEY)
|
||||
resp = app.post_json(url, params=data, status=400)
|
||||
assert 'Bad format for capture date, it should be yyyy-mm-dd.' in resp.content
|
||||
|
||||
|
||||
def test_cant_pay_if_different_capture_date(app, basket_page, regie, user):
|
||||
capture1 = (timezone.now() + timedelta(days=1)).date()
|
||||
capture2 = (timezone.now() + timedelta(days=2)).date()
|
||||
items = {
|
||||
'item1': {
|
||||
'amount': '10.5', 'capture_date': capture1.isoformat(),
|
||||
'source_url': 'http://example.org/item/1'
|
||||
},
|
||||
'item2': {
|
||||
'amount': '42', 'capture_date': capture2.isoformat(),
|
||||
'source_url': 'http://example.org/item/2'},
|
||||
}
|
||||
b_items = []
|
||||
for subject, details in items.items():
|
||||
b_item = BasketItem.objects.create(
|
||||
user=user, regie=regie, subject=subject, **details)
|
||||
b_items.append(b_item.pk)
|
||||
|
||||
resp = login(app).get('/test_basket_cell/')
|
||||
resp = resp.form.submit()
|
||||
assert resp.status_code == 302
|
||||
assert urlparse.urlparse(resp.location).path == '/test_basket_cell/'
|
||||
resp = resp.follow()
|
||||
assert "Invalid grouping for basket items: different capture dates." in resp.content
|
||||
|
||||
|
||||
def test_pay_single_basket_item(app, key, regie, user, john_doe):
|
||||
page = Page(title='xxx', slug='index', template_name='standard')
|
||||
page.save()
|
||||
|
|
Loading…
Reference in New Issue