diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 52f200d442..23ea2954a8 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -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 diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index 147810a437..6cdec4b960 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -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(): diff --git a/src/tests/api/test_order_create.py b/src/tests/api/test_order_create.py index 9e3185c725..fc510eefd3 100644 --- a/src/tests/api/test_order_create.py +++ b/src/tests/api/test_order_create.py @@ -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)