From 550d0eae32cab01b49a85270b0bece1c45f71eda Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Wed, 2 Dec 2015 11:07:49 +0100 Subject: [PATCH] compute item amount from payload and its optional extra attribute (#9174) --- README | 21 +++++++++++++++++++++ lingo/views.py | 19 ++++++++++++++++--- tests/test_payment.py | 26 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/README b/README index c328a20..d092a68 100644 --- a/README +++ b/README @@ -19,3 +19,24 @@ details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . + +API +--- + +Items amount can be added to basket through API by posting to +*/api/lingo/add-basket-item* endpoint a json payload containing *amount* and/or +*"extra": {"amount": ...}* attribute. + +For example: + + {"display_name": "", + "url": "http://", + "amount": "42.42", + "extra": {"amount": "10.42", ...}, + ... + } + +The "amount" attribute should be float or decimal or a list of +floats/decimals. For example: + + {"amount": [14.12], "extra": {"amount": ["10.42", "5", "10"], ... }, ...} diff --git a/lingo/views.py b/lingo/views.py index 52a73d5..67282f6 100644 --- a/lingo/views.py +++ b/lingo/views.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from decimal import Decimal +from decimal import Decimal, ROUND_HALF_UP import json from django.contrib.auth.models import User @@ -55,13 +55,26 @@ class AddBasketItemApiView(View): def dispatch(self, *args, **kwargs): return super(AddBasketItemApiView, self).dispatch(*args, **kwargs) + def get_amount(self, amount): + if isinstance(amount, list): + d = sum([Decimal(a) for a in amount]) + else: + d = Decimal(amount) + return d.quantize(Decimal('0.01'), ROUND_HALF_UP) + def post(self, request, *args, **kwargs): # XXX: check request signature request_body = json.loads(self.request.body) + extra = request_body.get('extra', {}) - item = BasketItem() - item.amount = sum([Decimal(x) for x in request.GET.getlist('amount')]) + item = BasketItem(amount=0) + + if request_body.get('amount'): + item.amount += self.get_amount(request_body['amount']) + + if extra.get('amount'): + item.amount += self.get_amount(extra['amount']) try: if request.GET.get('NameId'): diff --git a/tests/test_payment.py b/tests/test_payment.py index 529929f..df91a39 100644 --- a/tests/test_payment.py +++ b/tests/test_payment.py @@ -2,6 +2,7 @@ import pytest from datetime import datetime, timedelta import urlparse from decimal import Decimal +import json from django.contrib.auth.models import User from django.core.urlresolvers import reverse @@ -80,3 +81,28 @@ def test_successfull_items_payment(regie, user): # simulate backend callback call resp = client.get(qs['return_url'][0], args) assert resp.status_code == 200 + +def test_add_amount_to_basket(regie, user): + user_email = 'foo@example.com' + User.objects.get_or_create(email=user_email) + amount = 42 + data = {'amount': amount, 'display_name': 'test amount', + 'url': 'http://example.com'} + url = '%s?email=%s' % (reverse('api-add-basket-item'), user_email) + resp = client.post(url, json.dumps(data), content_type='application/json') + assert resp.status_code == 200 + assert json.loads(resp.content) == {'result': 'success'} + assert BasketItem.objects.filter(amount=amount).exists() + + data['extra'] = {'amount': '22.22'} + resp = client.post(url, json.dumps(data), content_type='application/json') + assert resp.status_code == 200 + assert json.loads(resp.content) == {'result': 'success'} + assert BasketItem.objects.filter(amount=Decimal('64.22')).exists() + + data['amount'] = [amount] + data['extra'] = {'amount': ['22.22', '12']} + resp = client.post(url, json.dumps(data), content_type='application/json') + assert resp.status_code == 200 + assert json.loads(resp.content) == {'result': 'success'} + assert BasketItem.objects.filter(amount=Decimal('76.22')).exists()