mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
Allow to charge a cancellation fee on unpaid orders (#2845)
This commit is contained in:
@@ -1107,11 +1107,23 @@ def test_order_mark_canceled_pending_fee_not_allowed(token_client, organizer, ev
|
||||
'/api/v1/organizers/{}/events/{}/orders/{}/mark_canceled/'.format(
|
||||
organizer.slug, event.slug, order.code
|
||||
), data={
|
||||
'cancellation_fee': '7.00'
|
||||
'cancellation_fee': '700.00'
|
||||
}
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {'detail': 'The cancellation fee cannot be higher than the payment credit of this order.'}
|
||||
assert resp.data == {'detail': 'The cancellation fee cannot be higher than the total amount of this order.'}
|
||||
assert len(djmail.outbox) == 0
|
||||
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/events/{}/orders/{}/mark_canceled/'.format(
|
||||
organizer.slug, event.slug, order.code
|
||||
), data={
|
||||
'cancellation_fee': '7.00'
|
||||
}
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.data['status'] == Order.STATUS_PENDING
|
||||
assert len(djmail.outbox) == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -1403,6 +1403,8 @@ class OrderTestCase(BaseQuotaTestCase):
|
||||
self.order.total = 48
|
||||
self.order.save()
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
self.order.status = Order.STATUS_PAID
|
||||
self.order.save()
|
||||
assert self.order.user_cancel_fee == Decimal('0.00')
|
||||
|
||||
self.event.settings.cancel_allow_user_paid_keep = Decimal('2.50')
|
||||
@@ -1421,6 +1423,27 @@ class OrderTestCase(BaseQuotaTestCase):
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('48.00')
|
||||
|
||||
self.order.status = Order.STATUS_PENDING
|
||||
self.order.save()
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('0.00')
|
||||
|
||||
self.event.settings.cancel_allow_user_unpaid_keep = Decimal('2.50')
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('2.50')
|
||||
|
||||
self.event.settings.cancel_allow_user_unpaid_keep_percentage = Decimal('5.0')
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('4.90')
|
||||
|
||||
self.event.settings.cancel_allow_user_unpaid_keep_fees = True
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('6.80')
|
||||
|
||||
self.event.settings.cancel_allow_user_unpaid_keep = Decimal('100.00')
|
||||
self.order = Order.objects.get(pk=self.order.pk)
|
||||
assert self.order.user_cancel_fee == Decimal('48.00')
|
||||
|
||||
@classscope(attr='o')
|
||||
def test_paid_order_underpaid(self):
|
||||
self.order.status = Order.STATUS_PAID
|
||||
|
||||
@@ -285,6 +285,21 @@ def test_expire_twice(event):
|
||||
assert o2.invoices.count() == 2
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_expire_skipped_if_canceled_with_fee(event):
|
||||
o2 = Order.objects.create(
|
||||
code='FO2', event=event, email='dummy@dummy.test',
|
||||
status=Order.STATUS_PENDING, locale='en',
|
||||
datetime=now(), expires=now() - timedelta(days=10),
|
||||
total=12,
|
||||
)
|
||||
o2.fees.create(fee_type=OrderFee.FEE_TYPE_CANCELLATION, value=12)
|
||||
generate_invoice(o2)
|
||||
expire_orders(None)
|
||||
o2 = Order.objects.get(id=o2.id)
|
||||
assert o2.status == Order.STATUS_PENDING
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_expiring_auto_disabled(event):
|
||||
event.settings.set('payment_term_expire_automatically', False)
|
||||
|
||||
@@ -496,7 +496,7 @@ def test_order_cancel_pending_fee_too_high(client, env):
|
||||
client.get('/control/event/dummy/dummy/orders/FOO/transition?status=c')
|
||||
client.post('/control/event/dummy/dummy/orders/FOO/transition', {
|
||||
'status': 'c',
|
||||
'cancellation_fee': '6.00'
|
||||
'cancellation_fee': '26.00'
|
||||
})
|
||||
with scopes_disabled():
|
||||
o = Order.objects.get(id=env[2].id)
|
||||
@@ -507,7 +507,7 @@ def test_order_cancel_pending_fee_too_high(client, env):
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_order_cancel_unpaid_no_fees_allowed(client, env):
|
||||
def test_order_cancel_unpaid_fees_allowed(client, env):
|
||||
client.login(email='dummy@dummy.dummy', password='dummy')
|
||||
client.get('/control/event/dummy/dummy/orders/FOO/transition?status=c')
|
||||
client.post('/control/event/dummy/dummy/orders/FOO/transition', {
|
||||
@@ -516,10 +516,10 @@ def test_order_cancel_unpaid_no_fees_allowed(client, env):
|
||||
})
|
||||
with scopes_disabled():
|
||||
o = Order.objects.get(id=env[2].id)
|
||||
assert o.positions.exists()
|
||||
assert not o.fees.exists()
|
||||
assert o.status == Order.STATUS_CANCELED
|
||||
assert o.total == Decimal('14.00')
|
||||
assert not o.positions.exists()
|
||||
assert o.fees.exists()
|
||||
assert o.status == Order.STATUS_PENDING
|
||||
assert o.total == Decimal('6.00')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -460,30 +460,19 @@ class OrdersTest(BaseOrdersTest):
|
||||
r = self.order.cancellation_requests.get()
|
||||
assert r.cancellation_fee == Decimal('3.00')
|
||||
|
||||
def test_orders_cancel_unpaid_no_request(self):
|
||||
def test_orders_cancel_partially_paid_no_selfservice(self):
|
||||
self.order.status = Order.STATUS_PENDING
|
||||
self.order.save()
|
||||
with scopes_disabled():
|
||||
self.order.payments.create(provider='testdummy_partialrefund', amount=self.order.total, state=OrderPayment.PAYMENT_STATE_CONFIRMED)
|
||||
self.order.payments.create(provider='testdummy_partialrefund', amount=self.order.total - Decimal("1.00"),
|
||||
state=OrderPayment.PAYMENT_STATE_CONFIRMED)
|
||||
self.event.settings.cancel_allow_user_paid = True
|
||||
self.event.settings.cancel_allow_user_paid_keep = Decimal('3.00')
|
||||
self.event.settings.cancel_allow_user_paid_require_approval = True
|
||||
response = self.client.get(
|
||||
'/%s/%s/order/%s/%s/cancel' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret)
|
||||
)
|
||||
assert response.status_code == 200
|
||||
response = self.client.post(
|
||||
'/%s/%s/order/%s/%s/cancel/do' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret), {
|
||||
}, follow=True)
|
||||
self.assertRedirects(response,
|
||||
'/%s/%s/order/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,
|
||||
self.order.secret),
|
||||
target_status_code=200)
|
||||
self.order.refresh_from_db()
|
||||
assert self.order.status == Order.STATUS_CANCELED
|
||||
with scopes_disabled():
|
||||
assert not self.order.refunds.exists()
|
||||
assert not self.order.cancellation_requests.exists()
|
||||
assert response.status_code == 302
|
||||
|
||||
def test_orders_cancel_free_no_request(self):
|
||||
self.order.status = Order.STATUS_PAID
|
||||
@@ -601,6 +590,33 @@ class OrdersTest(BaseOrdersTest):
|
||||
assert r.provider == "giftcard"
|
||||
assert r.amount == Decimal('20.00')
|
||||
|
||||
def test_orders_cancel_unpaid_fee(self):
|
||||
self.order.status = Order.STATUS_PENDING
|
||||
self.order.save()
|
||||
with scopes_disabled():
|
||||
self.order.payments.create(provider='testdummy_partialrefund', amount=self.order.total, state=OrderPayment.PAYMENT_STATE_CREATED)
|
||||
self.event.settings.cancel_allow_user = True
|
||||
self.event.settings.cancel_allow_user_paid = False
|
||||
self.event.settings.cancel_allow_user_unpaid_keep = Decimal('3.00')
|
||||
self.event.settings.cancel_allow_user_paid_keep = Decimal('7.00')
|
||||
response = self.client.get(
|
||||
'/%s/%s/order/%s/%s/cancel' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret)
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert 'manually' not in response.content.decode()
|
||||
response = self.client.post(
|
||||
'/%s/%s/order/%s/%s/cancel/do' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret), {
|
||||
}, follow=True)
|
||||
self.assertRedirects(response,
|
||||
'/%s/%s/order/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,
|
||||
self.order.secret),
|
||||
target_status_code=200)
|
||||
self.order.refresh_from_db()
|
||||
assert self.order.status == Order.STATUS_PENDING
|
||||
assert self.order.total == Decimal('3.00')
|
||||
with scopes_disabled():
|
||||
assert self.order.refunds.count() == 0
|
||||
|
||||
def test_orders_cancel_paid_fee_autorefund(self):
|
||||
self.order.status = Order.STATUS_PAID
|
||||
self.order.save()
|
||||
|
||||
Reference in New Issue
Block a user