Support for external gift cards (#2912)

This commit is contained in:
Raphael Michel
2022-11-23 14:52:56 +01:00
committed by GitHub
parent d3589696d7
commit 9624b1c505
24 changed files with 1521 additions and 523 deletions

View File

@@ -35,12 +35,14 @@ from tests.testdummy.signals import FoobazSalesChannel
from pretix.base.decimal import round_decimal
from pretix.base.models import (
CartPosition, Event, InvoiceAddress, Item, Order, OrderPosition, Organizer,
SeatingPlan,
CartPosition, Event, GiftCard, InvoiceAddress, Item, Order, OrderPosition,
Organizer, SeatingPlan,
)
from pretix.base.models.items import SubEventItem
from pretix.base.models.orders import OrderFee, OrderPayment, OrderRefund
from pretix.base.payment import FreeOrderProvider
from pretix.base.payment import (
FreeOrderProvider, GiftCardPayment, PaymentException,
)
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
from pretix.base.services.invoices import generate_invoice
from pretix.base.services.orders import (
@@ -76,7 +78,16 @@ def test_expiry_days(event):
event.settings.set('payment_term_days', 5)
event.settings.set('payment_term_weekdays', False)
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 5
@@ -87,14 +98,32 @@ def test_expiry_weekdays(event):
event.settings.set('payment_term_days', 5)
event.settings.set('payment_term_weekdays', True)
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 6
assert order.expires.weekday() == 0
today = make_aware(datetime(2016, 9, 19, 15, 0, 0, 0))
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 7
assert order.expires.weekday() == 0
@@ -108,7 +137,16 @@ def test_expiry_minutes(event):
event.settings.set('payment_term_minutes', 30)
event.settings.set('payment_term_weekdays', False)
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 0
assert (order.expires - today).seconds == 30 * 60
@@ -121,12 +159,30 @@ def test_expiry_last(event):
event.settings.set('payment_term_weekdays', False)
event.settings.set('payment_term_last', now() + timedelta(days=3))
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 3
event.settings.set('payment_term_last', now() + timedelta(days=7))
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 5
@@ -142,7 +198,16 @@ def test_expiry_last_relative(event):
RelativeDate(days_before=2, time=None, base_date_name='date_from', minutes_before=None)
))
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 3
@@ -173,7 +238,16 @@ def test_expiry_last_relative_subevents(event):
RelativeDate(days_before=2, time=None, base_date_name='date_from', minutes_before=None)
))
order = _create_order(event, email='dummy@example.org', positions=[cp1, cp2],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert (order.expires - today).days == 6
@@ -185,7 +259,16 @@ def test_expiry_dst(event):
utc = pytz.timezone('UTC')
today = tz.localize(datetime(2016, 10, 29, 12, 0, 0)).astimezone(utc)
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
localex = order.expires.astimezone(tz)
assert (localex.hour, localex.minute) == (23, 59)
@@ -2832,7 +2915,16 @@ def test_autocheckin(clist_autocheckin, event):
item=ticket, price=23, expires=now() + timedelta(days=1), event=event, cart_id="123"
)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert "web" in clist_autocheckin.auto_checkin_sales_channels
assert order.positions.first().checkins.first().auto_checked_in
@@ -2841,7 +2933,16 @@ def test_autocheckin(clist_autocheckin, event):
clist_autocheckin.save()
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de')[0]
assert clist_autocheckin.auto_checkin_sales_channels == []
assert order.positions.first().checkins.count() == 0
@@ -2858,23 +2959,59 @@ def test_saleschannel_testmode_restriction(event):
)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de', sales_channel='web')[0]
assert not order.testmode
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de', sales_channel=FoobazSalesChannel.identifier)[0]
assert not order.testmode
event.testmode = True
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de', sales_channel='web')[0]
assert order.testmode
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=today, payment_provider=FreeOrderProvider(event),
now_dt=today,
payment_requests=[{
"id": "test0",
"provider": "free",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": FreeOrderProvider(event),
}],
locale='de', sales_channel=FoobazSalesChannel.identifier)[0]
assert not order.testmode
@@ -2890,13 +3027,44 @@ def test_giftcard_multiple(event):
gc1.transactions.create(value=12)
gc2 = event.organizer.issued_gift_cards.create(currency="EUR")
gc2.transactions.create(value=12)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk, gc2.pk])[0]
assert order.payments.count() == 3
order = _create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc2.pk
},
"pprov": GiftCardPayment(event),
},
],
locale='de'
)[0]
assert order.payments.count() == 2
for p in order.payments.all():
p.payment_provider.execute_payment(None, p)
assert order.payments.get(info__icontains=gc1.pk).amount == Decimal('12.00')
assert order.payments.get(info__icontains=gc2.pk).amount == Decimal('11.00')
gc1 = GiftCard.objects.get(pk=gc1.pk)
assert gc1.value == 0
gc2 = GiftCard.objects.get(pk=gc2.pk)
assert gc2.value == 1
@@ -2909,12 +3077,39 @@ def test_giftcard_partial(event):
)
gc1 = event.organizer.issued_gift_cards.create(currency="EUR")
gc1.transactions.create(value=12)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
order = _create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
assert order.payments.count() == 2
for p in order.payments.all():
p.payment_provider.execute_payment(None, p)
assert order.payments.get(info__icontains=gc1.pk).amount == Decimal('12.00')
assert order.payments.get(provider='banktransfer').amount == Decimal('11.00')
gc1 = GiftCard.objects.get(pk=gc1.pk)
assert gc1.value == 0
@@ -2929,13 +3124,40 @@ def test_giftcard_payment_fee(event):
)
gc1 = event.organizer.issued_gift_cards.create(currency="EUR")
gc1.transactions.create(value=12)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
order = _create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
assert order.payments.count() == 2
assert order.payments.get(info__icontains=gc1.pk).amount == Decimal('12.00')
assert order.payments.get(provider='banktransfer').amount == Decimal('12.10')
for p in order.payments.all():
p.payment_provider.execute_payment(None, p)
assert order.fees.get().value == Decimal('1.10')
gc1 = GiftCard.objects.get(pk=gc1.pk)
assert gc1.value == 0
@@ -2948,10 +3170,36 @@ def test_giftcard_invalid_currency(event):
)
gc1 = event.organizer.issued_gift_cards.create(currency="USD")
gc1.transactions.create(value=12)
with pytest.raises(OrderError):
_create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
_create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
with pytest.raises(PaymentException):
for p in Order.objects.get().payments.all():
p.payment_provider.execute_payment(None, p)
@pytest.mark.django_db
@@ -2964,10 +3212,36 @@ def test_giftcard_invalid_organizer(event):
o2 = Organizer.objects.create(slug="foo", name="bar")
gc1 = o2.issued_gift_cards.create(currency="EUR")
gc1.transactions.create(value=12)
with pytest.raises(OrderError):
_create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
_create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
with pytest.raises(PaymentException):
for p in Order.objects.get().payments.all():
p.payment_provider.execute_payment(None, p)
@pytest.mark.django_db
@@ -2979,10 +3253,36 @@ def test_giftcard_test_mode_invalid(event):
)
gc1 = event.organizer.issued_gift_cards.create(currency="EUR", testmode=True)
gc1.transactions.create(value=12)
with pytest.raises(OrderError):
_create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
_create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
with pytest.raises(PaymentException):
for p in Order.objects.get().payments.all():
p.payment_provider.execute_payment(None, p)
@pytest.mark.django_db
@@ -2996,10 +3296,36 @@ def test_giftcard_test_mode_event(event):
event.save()
gc1 = event.organizer.issued_gift_cards.create(currency="EUR", testmode=False)
gc1.transactions.create(value=12)
with pytest.raises(OrderError):
_create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
_create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
with pytest.raises(PaymentException):
for p in Order.objects.get().payments.all():
p.payment_provider.execute_payment(None, p)
@pytest.mark.django_db
@@ -3011,10 +3337,36 @@ def test_giftcard_swap(event):
)
gc1 = event.organizer.issued_gift_cards.create(currency="EUR", testmode=False)
gc1.transactions.create(value=12)
with pytest.raises(OrderError):
_create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[gc1.pk])[0]
_create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test0",
"provider": "giftcard",
"max_value": "12.00",
"min_value": None,
"multi_use_supported": True,
"info_data": {
"gift_card": gc1.pk
},
"pprov": GiftCardPayment(event),
},
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
with pytest.raises(PaymentException):
for p in Order.objects.get().payments.all():
p.payment_provider.execute_payment(None, p)
@pytest.mark.django_db
@@ -3026,9 +3378,22 @@ def test_issue_when_paid_and_changed(event):
)
q = event.quotas.create(size=None, name="foo")
q.items.add(ticket)
order = _create_order(event, email='dummy@example.org', positions=[cp1],
now_dt=now(), payment_provider=BankTransfer(event),
locale='de', gift_cards=[])[0]
order = _create_order(
event, email='dummy@example.org', positions=[cp1],
now_dt=now(),
payment_requests=[
{
"id": "test1",
"provider": "banktransfer",
"max_value": None,
"min_value": None,
"multi_use_supported": False,
"info_data": {},
"pprov": BankTransfer(event),
},
],
locale='de'
)[0]
op = order.positions.first()
assert not op.issued_gift_cards.exists()
order.payments.first().confirm()