API: Fix crash on distributing a fee over tax rates with zero value (Z#23196669) (#5226)

This commit is contained in:
Raphael Michel
2025-06-12 14:03:25 +02:00
committed by GitHub
parent 7d30ecf527
commit eba5c1b36d
3 changed files with 41 additions and 4 deletions
+4 -3
View File
@@ -1059,9 +1059,10 @@ Creating orders
prices. Note that this will not include other fees and is calculated once during order generation and will not
be respected automatically when the order changes later.)
* ``_split_taxes_like_products`` (Optional convenience flag. If set to ``true``, your ``tax_rule`` will be ignored
and the fee will be taxed like the products in the order. If the products have multiple tax rates, multiple fees
will be generated with weights adjusted to the net price of the products. Note that this will be calculated once
during order generation and is not respected automatically when the order changes later.)
and the fee will be taxed like the products in the order *unless* the total amount of the positions is zero.
If the products have multiple tax rates, multiple fees will be generated with weights adjusted to the net price
of the products. Note that this will be calculated once during order generation and is not respected automatically
when the order changes later.)
* ``force`` (optional). If set to ``true``, quotas will be ignored.
* ``send_email`` (optional). If set to ``true``, the same emails will be sent as for a regular order, regardless of
+1 -1
View File
@@ -1600,7 +1600,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
self.context['event'].currency)
is_split_taxes = fee_data.pop('_split_taxes_like_products', False)
if is_split_taxes:
if is_split_taxes and order.total:
d = defaultdict(lambda: Decimal('0.00'))
trz = TaxRule.zero()
for p in pos_map.values():
+36
View File
@@ -961,6 +961,42 @@ def test_order_create_fee_as_percentage(token_client, organizer, event, item, qu
assert o.total == Decimal('25.30')
@pytest.mark.django_db
def test_order_create_fee_as_percentage_with_zero(token_client, organizer, event, item, quota, question):
with scopes_disabled():
voucher = event.vouchers.create(price_mode="set", value=Decimal("0.00"))
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
res['fees'][0]['_treat_value_as_percentage'] = True
res['fees'][0]['_split_taxes_like_products'] = True
res['fees'][0]['value'] = '10.00'
res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk
res['positions'][0]['voucher'] = voucher.code
del res['positions'][0]['price']
res['simulate'] = True
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 201
assert resp.data["total"] == "0.00"
res['simulate'] = False
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code'])
fee = o.fees.first()
assert fee.value == Decimal('0.00')
assert o.total == Decimal('0.00')
@pytest.mark.django_db
def test_order_create_fee_with_auto_tax(token_client, organizer, event, item, quota, question, taxrule):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)