lingo: support can_pay_only_one on remote regie (#50067)
This commit is contained in:
parent
fb4f5fd33d
commit
71aa546fec
|
@ -109,12 +109,6 @@ class RegieForm(forms.ModelForm):
|
||||||
instance.save()
|
instance.save()
|
||||||
return instance
|
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):
|
class PaymentBackendForm(forms.ModelForm):
|
||||||
|
|
||||||
|
|
|
@ -360,13 +360,12 @@ class PayMixin(object):
|
||||||
self, request, regie, items, remote_items, next_url='/', email='', firstname='',
|
self, request, regie, items, remote_items, next_url='/', email='', firstname='',
|
||||||
lastname=''):
|
lastname=''):
|
||||||
# check contract
|
# check contract
|
||||||
assert bool(len(items)) != bool(len(remote_items)), (
|
if bool(len(items)) == bool(len(remote_items)):
|
||||||
'there should be at least one item or remote item to pay and not both items'
|
messages.error(request, _('Items to pay are missing or are not of the same type (local/remote).'))
|
||||||
)
|
return HttpResponseRedirect(next_url)
|
||||||
assert not regie.can_pay_only_one_basket_item or len(items) == 1, (
|
if regie.can_pay_only_one_basket_item and (len(items) > 1 or len(remote_items) > 1):
|
||||||
'regie can only pay one basket item, but handle_payment() '
|
messages.error(request, _('This regie allows to pay only one item.'))
|
||||||
'did not receive one item: len(items) = %d' % len(items)
|
return HttpResponseRedirect(next_url)
|
||||||
)
|
|
||||||
|
|
||||||
total_amount = sum([x.amount for x in remote_items or items])
|
total_amount = sum([x.amount for x in remote_items or items])
|
||||||
|
|
||||||
|
@ -418,14 +417,14 @@ class PayMixin(object):
|
||||||
# copy command reference / invoice number
|
# copy command reference / invoice number
|
||||||
if item.reference_id:
|
if item.reference_id:
|
||||||
kwargs['orderid'] = item.reference_id
|
kwargs['orderid'] = item.reference_id
|
||||||
# PayFiP/TIPI specific
|
if getattr(item, 'request_data', None):
|
||||||
if regie.payment_backend.service in ('payfip_ws', 'tipi'):
|
# PayFiP/TIPI specific
|
||||||
if item.request_data and item.request_data.get('exer') and item.request_data.get('refdet'):
|
if regie.payment_backend.service in ('payfip_ws', 'tipi'):
|
||||||
kwargs['exer'] = item.request_data['exer']
|
if item.request_data.get('exer') and item.request_data.get('refdet'):
|
||||||
kwargs['refdet'] = item.request_data['refdet']
|
kwargs['exer'] = item.request_data['exer']
|
||||||
# allow easy testing/use of backend specific keyword arguments
|
kwargs['refdet'] = item.request_data['refdet']
|
||||||
EOPAYMENT_REQUEST_KWARGS_PREFIX = 'eopayment_request_kwargs_'
|
# allow easy testing/use of backend specific keyword arguments
|
||||||
if hasattr(item, 'request_data'):
|
EOPAYMENT_REQUEST_KWARGS_PREFIX = 'eopayment_request_kwargs_'
|
||||||
for key in item.request_data:
|
for key in item.request_data:
|
||||||
if key.startswith(EOPAYMENT_REQUEST_KWARGS_PREFIX):
|
if key.startswith(EOPAYMENT_REQUEST_KWARGS_PREFIX):
|
||||||
arg_name = key[len(EOPAYMENT_REQUEST_KWARGS_PREFIX):]
|
arg_name = key[len(EOPAYMENT_REQUEST_KWARGS_PREFIX):]
|
||||||
|
@ -495,11 +494,11 @@ class PayView(PayMixin, View):
|
||||||
regie.compute_extra_fees(user=user)
|
regie.compute_extra_fees(user=user)
|
||||||
items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
|
items = BasketItem.get_items_to_be_paid(user=user).filter(regie=regie)
|
||||||
|
|
||||||
if regie.can_pay_only_one_basket_item and len(items) > 1:
|
if regie.can_pay_only_one_basket_item and (len(items) > 1 or len(remote_items) > 1):
|
||||||
messages.error(request, _('Grouping basket items is not allowed.'))
|
messages.error(request, _('Grouping basket items is not allowed.'))
|
||||||
logger.error('lingo: regie can only pay one basket item, but handle_payment() received',
|
logger.error('lingo: regie can only pay one basket item, but handle_payment() received',
|
||||||
extra={'regie': str(regie), 'items': items, 'remote_items': remote_items})
|
extra={'regie': str(regie), 'items': items, 'remote_items': remote_items})
|
||||||
return HttpResponseRedirect(next_url)
|
return HttpResponseRedirect(next_url)
|
||||||
|
|
||||||
if items:
|
if items:
|
||||||
capture_date = items[0].capture_date
|
capture_date = items[0].capture_date
|
||||||
|
|
|
@ -42,6 +42,23 @@ INVOICES = [
|
||||||
'paid': False,
|
'paid': False,
|
||||||
'payment_date': '1970-01-01',
|
'payment_date': '1970-01-01',
|
||||||
'no_online_payment_reason': '',
|
'no_online_payment_reason': '',
|
||||||
|
'reference_id': 'order-id-1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'F201602',
|
||||||
|
'display_id': 'F-2016-Two',
|
||||||
|
'label': 'invoice-two',
|
||||||
|
'regie': 'remote',
|
||||||
|
'created': '2016-02-02',
|
||||||
|
'pay_limit_date': '2999-12-31',
|
||||||
|
'total_amount': '543.21',
|
||||||
|
'amount': '543.21',
|
||||||
|
'has_pdf': True,
|
||||||
|
'online_payment': True,
|
||||||
|
'paid': False,
|
||||||
|
'payment_date': '1970-01-01',
|
||||||
|
'no_online_payment_reason': '',
|
||||||
|
'reference_id': 'order-id-2',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -87,6 +104,7 @@ class MockUser(object):
|
||||||
@mock.patch('combo.utils.requests_wrapper.RequestsSession.send')
|
@mock.patch('combo.utils.requests_wrapper.RequestsSession.send')
|
||||||
def test_remote_regie_active_invoices_cell(mock_send, remote_regie):
|
def test_remote_regie_active_invoices_cell(mock_send, remote_regie):
|
||||||
assert remote_regie.is_remote() == True
|
assert remote_regie.is_remote() == True
|
||||||
|
assert remote_regie.can_pay_only_one_basket_item is False
|
||||||
|
|
||||||
page = Page(title='xxx', slug='test_basket_cell', template_name='standard')
|
page = Page(title='xxx', slug='test_basket_cell', template_name='standard')
|
||||||
page.save()
|
page.save()
|
||||||
|
@ -108,6 +126,8 @@ def test_remote_regie_active_invoices_cell(mock_send, remote_regie):
|
||||||
content = cell.render(context)
|
content = cell.render(context)
|
||||||
assert 'F-2016-One' in content
|
assert 'F-2016-One' in content
|
||||||
assert '123.45' in content
|
assert '123.45' in content
|
||||||
|
assert 'F-2016-Two' in content
|
||||||
|
assert '543.21' in content
|
||||||
|
|
||||||
assert '?page=%s' % page.pk in content
|
assert '?page=%s' % page.pk in content
|
||||||
# check if regie webservice has been correctly called
|
# check if regie webservice has been correctly called
|
||||||
|
@ -199,11 +219,14 @@ def test_remote_regie_past_invoices_cell(mock_send, remote_regie):
|
||||||
content = cell.render(context)
|
content = cell.render(context)
|
||||||
assert 'F-2016-One' in content
|
assert 'F-2016-One' in content
|
||||||
assert '123.45' in content
|
assert '123.45' in content
|
||||||
|
assert 'F-2016-Two' in content
|
||||||
|
assert '543.21' in content
|
||||||
assert 'class="invoice-payment-limit-date"' in content
|
assert 'class="invoice-payment-limit-date"' in content
|
||||||
|
|
||||||
# invoice without limit date
|
# invoice without limit date
|
||||||
invoices = copy.deepcopy(INVOICES)
|
invoices = copy.deepcopy(INVOICES)
|
||||||
invoices[0]['pay_limit_date'] = ''
|
invoices[0]['pay_limit_date'] = ''
|
||||||
|
invoices[1]['pay_limit_date'] = ''
|
||||||
ws_invoices = {'err': 0, 'data': invoices}
|
ws_invoices = {'err': 0, 'data': invoices}
|
||||||
mock_response = mock.Mock(status_code=200, content=json.dumps(ws_invoices))
|
mock_response = mock.Mock(status_code=200, content=json.dumps(ws_invoices))
|
||||||
mock_response.json.return_value = ws_invoices
|
mock_response.json.return_value = ws_invoices
|
||||||
|
@ -592,9 +615,12 @@ def test_remote_item_payment_failure(mock_post, mock_get, mock_pay_invoice, app,
|
||||||
@mock.patch('combo.apps.lingo.models.Regie.pay_invoice')
|
@mock.patch('combo.apps.lingo.models.Regie.pay_invoice')
|
||||||
@mock.patch('combo.apps.lingo.models.requests.get')
|
@mock.patch('combo.apps.lingo.models.requests.get')
|
||||||
def test_remote_invoice_successfull_payment_redirect(mock_get, mock_pay_invoice, app, remote_regie):
|
def test_remote_invoice_successfull_payment_redirect(mock_get, mock_pay_invoice, app, remote_regie):
|
||||||
|
assert remote_regie.is_remote()
|
||||||
|
assert remote_regie.can_pay_only_one_basket_item is False
|
||||||
|
remote_regie.save()
|
||||||
|
|
||||||
page = Page(title='xxx', slug='active-remote-invoices-page', template_name='standard')
|
page = Page(title='xxx', slug='active-remote-invoices-page', template_name='standard')
|
||||||
page.save()
|
page.save()
|
||||||
assert remote_regie.is_remote()
|
|
||||||
encrypt_id = aes_hex_encrypt(settings.SECRET_KEY, force_bytes('F201601'))
|
encrypt_id = aes_hex_encrypt(settings.SECRET_KEY, force_bytes('F201601'))
|
||||||
mock_json = mock.Mock()
|
mock_json = mock.Mock()
|
||||||
mock_json.json.return_value = {'err': 0, 'data': INVOICES[0]}
|
mock_json.json.return_value = {'err': 0, 'data': INVOICES[0]}
|
||||||
|
@ -612,6 +638,8 @@ def test_remote_invoice_successfull_payment_redirect(mock_get, mock_pay_invoice,
|
||||||
parsed = urlparse.urlparse(location)
|
parsed = urlparse.urlparse(location)
|
||||||
# get return_url and transaction id from location
|
# get return_url and transaction id from location
|
||||||
qs = urlparse.parse_qs(parsed.query)
|
qs = urlparse.parse_qs(parsed.query)
|
||||||
|
assert 'orderid' not in qs
|
||||||
|
assert 'subject' not in qs
|
||||||
args = {'transaction_id': qs['transaction_id'][0], 'signed': True,
|
args = {'transaction_id': qs['transaction_id'][0], 'signed': True,
|
||||||
'ok': True, 'reason': 'Paid'}
|
'ok': True, 'reason': 'Paid'}
|
||||||
resp = app.get(qs['return_url'][0], params=args)
|
resp = app.get(qs['return_url'][0], params=args)
|
||||||
|
@ -622,6 +650,18 @@ def test_remote_invoice_successfull_payment_redirect(mock_get, mock_pay_invoice,
|
||||||
assert urlparse.urlparse(resp.html.find('a', {'id': 'next-url'})['href']).path == \
|
assert urlparse.urlparse(resp.html.find('a', {'id': 'next-url'})['href']).path == \
|
||||||
'/active-remote-invoices-page/'
|
'/active-remote-invoices-page/'
|
||||||
|
|
||||||
|
# one item limitation: send orderid to eopayment
|
||||||
|
remote_regie.can_pay_only_one_basket_item = True
|
||||||
|
remote_regie.save()
|
||||||
|
resp = form.submit()
|
||||||
|
assert resp.status_code == 302
|
||||||
|
location = resp.location
|
||||||
|
assert 'dummy-payment' in location
|
||||||
|
parsed = urlparse.urlparse(location)
|
||||||
|
qs = urlparse.parse_qs(parsed.query)
|
||||||
|
assert qs['orderid'] == ['order-id-1']
|
||||||
|
assert qs['subject'] == ['invoice-one']
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('combo.apps.lingo.models.UserSAMLIdentifier')
|
@mock.patch('combo.apps.lingo.models.UserSAMLIdentifier')
|
||||||
@mock.patch('combo.apps.lingo.models.requests.get')
|
@mock.patch('combo.apps.lingo.models.requests.get')
|
||||||
|
|
Loading…
Reference in New Issue