diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index ba71833a88..da98d68a4c 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -554,7 +554,7 @@ class SubEventSerializer(I18nAwareModelSerializer): class TaxRuleSerializer(CountryFieldMixin, I18nAwareModelSerializer): class Meta: model = TaxRule - fields = ('id', 'name', 'rate', 'price_includes_tax', 'eu_reverse_charge', 'home_country') + fields = ('id', 'name', 'rate', 'price_includes_tax') class EventSettingsSerializer(serializers.Serializer): diff --git a/src/pretix/base/migrations/0170_auto_20201030_2109.py b/src/pretix/base/migrations/0170_auto_20201030_2109.py new file mode 100644 index 0000000000..5cc696eaa2 --- /dev/null +++ b/src/pretix/base/migrations/0170_auto_20201030_2109.py @@ -0,0 +1,49 @@ +# Generated by Django 3.0.10 on 2020-10-30 21:09 +import json + +from django.db import migrations + + +def migrate_tax_rules(apps, schema_editor): + TaxRule = apps.get_model('pretixbase', 'TaxRule') + for tr in TaxRule.objects.filter(eu_reverse_charge=True): + if tr.custom_rules and tr.custom_rules != '[]': + # Custom rules take precedence + continue + r = [{ + 'country': str(tr.home_country), + 'address_type': '', + 'action': 'vat' + }, { + 'country': 'EU', + 'address_type': 'business_vat_id', + 'action': 'reverse' + }, { + 'country': 'EU', + 'address_type': '', + 'action': 'vat' + }, { + 'country': 'ZZ', + 'address_type': '', + 'action': 'no' + }] + tr.custom_rules = json.dumps(r) + tr.save() + + +class Migration(migrations.Migration): + dependencies = [ + ('pretixbase', '0169_checkinlist_gates'), + ] + + operations = [ + migrations.RunPython(migrate_tax_rules, migrations.RunPython.noop), + migrations.RemoveField( + model_name='taxrule', + name='eu_reverse_charge', + ), + migrations.RemoveField( + model_name='taxrule', + name='home_country', + ), + ] diff --git a/src/pretix/base/models/tax.py b/src/pretix/base/models/tax.py index 4eedfb5aef..974167b7e8 100644 --- a/src/pretix/base/models/tax.py +++ b/src/pretix/base/models/tax.py @@ -1,7 +1,6 @@ import json from decimal import Decimal -from django.core.exceptions import ValidationError from django.db import models from django.utils.formats import localize from django.utils.translation import gettext_lazy as _ @@ -10,7 +9,6 @@ from i18nfield.fields import I18nCharField from pretix.base.decimal import round_decimal from pretix.base.models.base import LoggedModel from pretix.base.templatetags.money import money_filter -from pretix.helpers.countries import FastCountryField class TaxedPrice: @@ -107,21 +105,6 @@ class TaxRule(LoggedModel): verbose_name=_("The configured product prices include the tax amount"), default=True, ) - eu_reverse_charge = models.BooleanField( - verbose_name=_("Use EU reverse charge taxation rules"), - default=False, - help_text=_("Not recommended. Most events will NOT be qualified for reverse charge since the place of " - "taxation is the location of the event. This option disables charging VAT for all customers " - "outside the EU and for business customers in different EU countries who entered a valid EU VAT " - "ID. Only enable this option after consulting a tax counsel. No warranty given for correct tax " - "calculation. USE AT YOUR OWN RISK.") - ) - home_country = FastCountryField( - verbose_name=_('Merchant country'), - blank=True, - help_text=_('Your country of residence. This is the country the EU reverse charge rule will not apply in, ' - 'if configured above.'), - ) custom_rules = models.TextField(blank=True, null=True) class Meta: @@ -147,17 +130,13 @@ class TaxRule(LoggedModel): eu_reverse_charge=False ) - def clean(self): - if self.eu_reverse_charge and not self.home_country: - raise ValidationError(_('You need to set your home country to use the reverse charge feature.')) - def __str__(self): if self.price_includes_tax: s = _('incl. {rate}% {name}').format(rate=self.rate, name=self.name) else: s = _('plus {rate}% {name}').format(rate=self.rate, name=self.name) - if self.eu_reverse_charge: - s += ' ({})'.format(_('reverse charge enabled')) + if self.has_custom_rules: + s += ' ({})'.format(_('with custom rules')) return str(s) @property @@ -258,50 +237,12 @@ class TaxRule(LoggedModel): if self._custom_rules: rule = self.get_matching_rule(invoice_address) return rule['action'] == 'reverse' - - if not self.eu_reverse_charge: - return False - - if not invoice_address or not invoice_address.country: - return False - - if str(invoice_address.country) not in EU_COUNTRIES: - return False - - if invoice_address.country == self.home_country: - return False - - if invoice_address.is_business and invoice_address.vat_id and invoice_address.vat_id_validated: - return True - return False def _tax_applicable(self, invoice_address): if self._custom_rules: rule = self.get_matching_rule(invoice_address) return rule.get('action', 'vat') == 'vat' - - if not self.eu_reverse_charge: - # No reverse charge rules? Always apply VAT! - return True - - if not invoice_address or not invoice_address.country: - # No country specified? Always apply VAT! - return True - - if str(invoice_address.country) not in EU_COUNTRIES: - # Non-EU country? Never apply VAT! - return False - - if invoice_address.country == self.home_country: - # Within same EU country? Always apply VAT! - return True - - if invoice_address.is_business and invoice_address.vat_id and invoice_address.vat_id_validated: - # Reverse charge case - return False - - # Consumer in different EU country / invalid VAT return True def delete(self, *args, **kwargs): diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 56caa71d78..131f2909fb 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -1164,7 +1164,7 @@ TaxRuleLineFormSet = formset_factory( class TaxRuleForm(I18nModelForm): class Meta: model = TaxRule - fields = ['name', 'rate', 'price_includes_tax', 'eu_reverse_charge', 'home_country'] + fields = ['name', 'rate', 'price_includes_tax'] class WidgetCodeForm(forms.Form): diff --git a/src/pretix/control/templates/pretixcontrol/event/tax_edit.html b/src/pretix/control/templates/pretixcontrol/event/tax_edit.html index 2d06661fcc..c542f5822f 100644 --- a/src/pretix/control/templates/pretixcontrol/event/tax_edit.html +++ b/src/pretix/control/templates/pretixcontrol/event/tax_edit.html @@ -34,15 +34,9 @@ for more information. Note that we are not responsible for the correct handling of taxes in your ticket shop. If in doubt, please contact a lawyer or tax consultant. {% endblocktrans %} - - {% bootstrap_field form.eu_reverse_charge layout="control" %} - {% bootstrap_field form.home_country layout="control" %} -