New data model for default tax rule and new options for cancellation fees (#4962)

* New data model for default tax rule

* Remove misleading empty label when field is not optional

* Allow to split cancellation fee

* Fix API and tests

* Update migration

* Update src/tests/api/test_taxrules.py

Co-authored-by: luelista <weller@rami.io>

* Update src/tests/api/test_taxrules.py

Co-authored-by: luelista <weller@rami.io>

* Review note

* Update src/pretix/base/models/tax.py

Co-authored-by: luelista <weller@rami.io>

* Flip API behaviour for default

* Fix failing tests

* Fix failing test

* Split migration

---------

Co-authored-by: luelista <weller@rami.io>
This commit is contained in:
Raphael Michel
2025-06-30 16:47:09 +02:00
committed by GitHub
parent 090358833d
commit 14ed6982a5
34 changed files with 615 additions and 104 deletions

View File

@@ -0,0 +1,24 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0281_event_is_remote"),
]
operations = [
migrations.AddField(
model_name="taxrule",
name="default",
field=models.BooleanField(default=False),
),
migrations.AddConstraint(
model_name="taxrule",
constraint=models.UniqueConstraint(
condition=models.Q(("default", True)),
fields=("event",),
name="one_default_per_event",
),
),
]

View File

@@ -0,0 +1,60 @@
# Generated by Django 4.2.17 on 2025-03-28 09:19
from django.core.cache import cache
from django.db import migrations, models
from django.db.models import Count, Exists, OuterRef
def set_default_tax_rate(app, schema_editor):
Event = app.get_model('pretixbase', 'Event')
Event_SettingsStore = app.get_model('pretixbase', 'Event_SettingsStore')
TaxRule = app.get_model('pretixbase', 'TaxRule')
# Handling of events with tax_rate_default set
for s in Event_SettingsStore.objects.filter(key="tax_rate_default"):
updated = TaxRule.objects.filter(pk=s.value, event_id=s.object_id).update(default=True)
if updated:
# Delete deprecated settings key
s.delete()
# The default for new events is tax_rule_cancellation=none, but since we do not change behaviour
# for existing events without warning, we create a settings entry that matches the old behaviour.
Event_SettingsStore.objects.get_or_create(
object_id=s.object_id,
key="tax_rule_cancellation",
defaults={"value": "default"},
)
# We do not need to set tax_rule_payment here since "default" is the default
cache.delete('hierarkey_{}_{}'.format('event', s.object_id))
# Handling of events with tax_rate_default not set
for e in Event.objects.only("pk").exclude(Exists(TaxRule.objects.filter(default=True, event_id=OuterRef("pk")))):
fav_tax_rules = e.tax_rules.annotate(c=Count("item")).order_by("-c", "pk")[:1]
if fav_tax_rules:
fav_tax_rules[0].default = True
fav_tax_rules[0].save()
# Previously, no tax rule was set for payments, so keep it this way
Event_SettingsStore.objects.get_or_create(
object=e,
key="tax_rule_payment",
defaults={"value": "none"},
)
cache.delete('hierarkey_{}_{}'.format('event', e.pk))
# We do not need to set tax_rule_cancellation, as "none" is the new system default
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0282_taxrule_default"),
]
operations = [
migrations.RunPython(
set_default_tax_rate,
migrations.RunPython.noop,
),
]