mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Add codification of tax rates (#4372)
* draft * . * Rebase migration * Update src/pretix/base/models/tax.py Co-authored-by: Mira <weller@rami.io> * Test, isort, flake, migration rebase * carry data & API * Fix failing tests * docs fixes * Improve validation * Tests * More fixes --------- Co-authored-by: Mira <weller@rami.io>
This commit is contained in:
@@ -62,9 +62,10 @@ from django.db.models.signals import post_delete
|
||||
from django.dispatch import receiver
|
||||
from django.urls import reverse
|
||||
from django.utils.crypto import get_random_string, salted_hmac
|
||||
from django.utils.encoding import escape_uri_path
|
||||
from django.utils.encoding import escape_uri_path, force_str
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.hashable import make_hashable
|
||||
from django.utils.timezone import get_current_timezone, make_aware, now
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_countries.fields import Country
|
||||
@@ -1256,7 +1257,7 @@ class Order(LockModel, LoggedModel):
|
||||
keys = set(target_transaction_count.keys()) | set(current_transaction_count.keys())
|
||||
create = []
|
||||
for k in keys:
|
||||
positionid, itemid, variationid, subeventid, price, taxrate, taxruleid, taxvalue, feetype, internaltype = k
|
||||
positionid, itemid, variationid, subeventid, price, taxrate, taxruleid, taxvalue, feetype, internaltype, taxcode = k
|
||||
d = target_transaction_count[k] - current_transaction_count[k]
|
||||
if d:
|
||||
create.append(Transaction(
|
||||
@@ -1272,6 +1273,7 @@ class Order(LockModel, LoggedModel):
|
||||
tax_rate=taxrate,
|
||||
tax_rule_id=taxruleid,
|
||||
tax_value=taxvalue,
|
||||
tax_code=taxcode,
|
||||
fee_type=feetype,
|
||||
internal_type=internaltype,
|
||||
))
|
||||
@@ -2313,6 +2315,10 @@ class OrderFee(models.Model):
|
||||
on_delete=models.PROTECT,
|
||||
null=True, blank=True
|
||||
)
|
||||
tax_code = models.CharField(
|
||||
max_length=190,
|
||||
null=True, blank=True,
|
||||
)
|
||||
tax_value = models.DecimalField(
|
||||
max_digits=13, decimal_places=2,
|
||||
verbose_name=_('Tax value')
|
||||
@@ -2340,6 +2346,16 @@ class OrderFee(models.Model):
|
||||
self._transaction_key_reset()
|
||||
return super().refresh_from_db(using, fields)
|
||||
|
||||
def get_tax_code_display(self):
|
||||
from pretix.base.models.tax import get_tax_code_labels
|
||||
|
||||
if self.tax_code:
|
||||
choices_dict = get_tax_code_labels()
|
||||
return force_str(
|
||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
||||
)
|
||||
return ""
|
||||
|
||||
def _transaction_key_reset(self):
|
||||
self.__initial_transaction_key = Transaction.key(self)
|
||||
self.__initial_canceled = self.canceled
|
||||
@@ -2370,9 +2386,11 @@ class OrderFee(models.Model):
|
||||
if self.tax_rule:
|
||||
tax = self.tax_rule.tax(self.value, base_price_is='gross', invoice_address=ia, force_fixed_gross_price=True)
|
||||
self.tax_rate = tax.rate
|
||||
self.tax_code = tax.code
|
||||
self.tax_value = tax.tax
|
||||
else:
|
||||
self.tax_value = Decimal('0.00')
|
||||
self.tax_code = None
|
||||
self.tax_rate = Decimal('0.00')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
@@ -2381,6 +2399,7 @@ class OrderFee(models.Model):
|
||||
|
||||
if self.tax_rate is None:
|
||||
self._calculate_tax()
|
||||
|
||||
self.order.touch()
|
||||
|
||||
if not self.get_deferred_fields():
|
||||
@@ -2468,6 +2487,10 @@ class OrderPosition(AbstractPosition):
|
||||
on_delete=models.PROTECT,
|
||||
null=True, blank=True
|
||||
)
|
||||
tax_code = models.CharField(
|
||||
max_length=190,
|
||||
null=True, blank=True,
|
||||
)
|
||||
tax_value = models.DecimalField(
|
||||
max_digits=13, decimal_places=2,
|
||||
verbose_name=_('Tax value')
|
||||
@@ -2525,6 +2548,16 @@ class OrderPosition(AbstractPosition):
|
||||
models.UniqueConstraint("organizer", "secret", name="orderposition_organizer_secret_uniq")
|
||||
]
|
||||
|
||||
def get_tax_code_display(self):
|
||||
from pretix.base.models.tax import get_tax_code_labels
|
||||
|
||||
if self.tax_code:
|
||||
choices_dict = get_tax_code_labels()
|
||||
return force_str(
|
||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
||||
)
|
||||
return ""
|
||||
|
||||
@cached_property
|
||||
def sort_key(self):
|
||||
return self.addon_to.positionid if self.addon_to else self.positionid, self.addon_to_id or 0, self.positionid
|
||||
@@ -2697,11 +2730,13 @@ class OrderPosition(AbstractPosition):
|
||||
if self.tax_rule:
|
||||
tax = self.tax_rule.tax(self.price, invoice_address=ia, base_price_is='gross', force_fixed_gross_price=True)
|
||||
self.tax_rate = tax.rate
|
||||
self.tax_code = tax.code
|
||||
self.tax_value = tax.tax
|
||||
if tax.gross != self.price:
|
||||
raise ValueError('Invalid tax calculation')
|
||||
else:
|
||||
self.tax_value = Decimal('0.00')
|
||||
self.tax_code = None
|
||||
self.tax_rate = Decimal('0.00')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
@@ -2972,6 +3007,10 @@ class Transaction(models.Model):
|
||||
on_delete=models.PROTECT,
|
||||
null=True, blank=True
|
||||
)
|
||||
tax_code = models.CharField(
|
||||
max_length=190,
|
||||
null=True, blank=True,
|
||||
)
|
||||
tax_value = models.DecimalField(
|
||||
max_digits=13, decimal_places=2,
|
||||
verbose_name=_('Tax value')
|
||||
@@ -2992,17 +3031,27 @@ class Transaction(models.Model):
|
||||
raise ValidationError('Should set either item or fee type')
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def get_tax_code_display(self):
|
||||
from pretix.base.models.tax import get_tax_code_labels
|
||||
|
||||
if self.tax_code:
|
||||
choices_dict = get_tax_code_labels()
|
||||
return force_str(
|
||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
||||
)
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def key(obj):
|
||||
if isinstance(obj, Transaction):
|
||||
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type)
|
||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type, obj.tax_code)
|
||||
elif isinstance(obj, OrderPosition):
|
||||
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
||||
obj.tax_rule_id, obj.tax_value, None, None)
|
||||
obj.tax_rule_id, obj.tax_value, None, None, obj.tax_code)
|
||||
elif isinstance(obj, OrderFee):
|
||||
return (None, None, None, None, obj.value, obj.tax_rate,
|
||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type)
|
||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type, obj.tax_code)
|
||||
raise ValueError('invalid state') # noqa
|
||||
|
||||
@property
|
||||
@@ -3166,6 +3215,7 @@ class CartPosition(AbstractPosition):
|
||||
if line_price.gross != self.line_price_gross or line_price.rate != self.tax_rate:
|
||||
self.line_price_gross = line_price.gross
|
||||
self.tax_rate = line_price.rate
|
||||
self.tax_code = line_price.code
|
||||
self.save(update_fields=['line_price_gross', 'tax_rate'])
|
||||
|
||||
@property
|
||||
|
||||
Reference in New Issue
Block a user