Compare commits

...

1 Commits

Author SHA1 Message Date
Raphael Michel
2b07d00d90 Remove eu_reverse_charge rule 2020-10-30 22:24:55 +01:00
5 changed files with 55 additions and 71 deletions

View File

@@ -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):

View File

@@ -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',
),
]

View File

@@ -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):

View File

@@ -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):

View File

@@ -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 %}
</div>
{% bootstrap_field form.eu_reverse_charge layout="control" %}
{% bootstrap_field form.home_country layout="control" %}
<h3>{% trans "Custom taxation rules" %}</h3>
<div class="alert alert-warning">
<br>
{% blocktrans trimmed %}
These settings are intended for professional users with very specific taxation situations.
If you create any rule here, the reverse charge settings above will be ignored. The rules will be
checked in order and once the first rule matches the order, it will be used and all further rules will
The rules will be checked in order and once the first rule matches the order, it will be used and all further rules will
be ignored. If no rule matches, tax will be charged.
{% endblocktrans %}
{% trans "All of these rules will only apply if an invoice address is set." %}