From 5c85c69b3d483877c4a2b2e7b803acb5a47de4fc Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sun, 22 Nov 2020 13:45:45 +0100 Subject: [PATCH] Brexit --- src/pretix/base/forms/questions.py | 10 ++++++---- src/pretix/base/models/tax.py | 15 ++++++++++++--- src/pretix/base/services/invoices.py | 4 ++-- src/pretix/control/views/orders.py | 4 ++-- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py index 0cbcf8e563..551a667a32 100644 --- a/src/pretix/base/forms/questions.py +++ b/src/pretix/base/forms/questions.py @@ -34,7 +34,9 @@ from pretix.base.forms.widgets import ( ) from pretix.base.i18n import language from pretix.base.models import InvoiceAddress, Question, QuestionOption -from pretix.base.models.tax import EU_COUNTRIES, cc_to_vat_prefix +from pretix.base.models.tax import ( + EU_COUNTRIES, cc_to_vat_prefix, is_eu_country, +) from pretix.base.settings import ( COUNTRIES_WITH_STATE_IN_ADDRESS, PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS, @@ -648,7 +650,7 @@ class BaseInvoiceAddressForm(forms.ModelForm): self.fields['state'].widget.is_required = True # Without JavaScript the VAT ID field is not hidden, so we empty the field if a country outside the EU is selected. - if cc and cc not in EU_COUNTRIES and fprefix + 'vat_id' in self.data: + if cc and not is_eu_country(cc) and fprefix + 'vat_id' in self.data: self.data = self.data.copy() del self.data[fprefix + 'vat_id'] @@ -698,7 +700,7 @@ class BaseInvoiceAddressForm(forms.ModelForm): if not data.get('is_business'): data['company'] = '' data['vat_id'] = '' - if data.get('is_business') and not data.get('country') in EU_COUNTRIES: + if data.get('is_business') and not is_eu_country(data.get('country')): data['vat_id'] = '' if self.event.settings.invoice_address_required: if data.get('is_business') and not data.get('company'): @@ -722,7 +724,7 @@ class BaseInvoiceAddressForm(forms.ModelForm): self.cleaned_data['country'] = '' if self.validate_vat_id and self.instance.vat_id_validated and 'vat_id' not in self.changed_data: pass - elif self.validate_vat_id and data.get('is_business') and data.get('country') in EU_COUNTRIES and data.get('vat_id'): + elif self.validate_vat_id and data.get('is_business') and is_eu_country(data.get('country')) and data.get('vat_id'): if data.get('vat_id')[:2] != cc_to_vat_prefix(str(data.get('country'))): raise ValidationError(_('Your VAT ID does not match the selected country.')) try: diff --git a/src/pretix/base/models/tax.py b/src/pretix/base/models/tax.py index 1b0c6cbd46..04906d586e 100644 --- a/src/pretix/base/models/tax.py +++ b/src/pretix/base/models/tax.py @@ -4,6 +4,7 @@ from decimal import Decimal from django.core.exceptions import ValidationError from django.db import models from django.utils.formats import localize +from django.utils.timezone import get_current_timezone, now from django.utils.translation import gettext_lazy as _ from i18nfield.fields import I18nCharField @@ -85,6 +86,14 @@ EU_CURRENCIES = { } +def is_eu_country(cc): + cc = str(cc) + if cc == 'GB': + return now().astimezone(get_current_timezone()).year <= 2020 + else: + return cc in EU_COUNTRIES + + def cc_to_vat_prefix(country_code): if country_code == 'GR': return 'EL' @@ -246,7 +255,7 @@ class TaxRule(LoggedModel): rules = self._custom_rules if invoice_address: for r in rules: - if r['country'] == 'EU' and str(invoice_address.country) not in EU_COUNTRIES: + if r['country'] == 'EU' and not is_eu_country(invoice_address.country): continue if r['country'] not in ('ZZ', 'EU') and r['country'] != str(invoice_address.country): continue @@ -270,7 +279,7 @@ class TaxRule(LoggedModel): if not invoice_address or not invoice_address.country: return False - if str(invoice_address.country) not in EU_COUNTRIES: + if not is_eu_country(invoice_address.country): return False if invoice_address.country == self.home_country: @@ -296,7 +305,7 @@ class TaxRule(LoggedModel): # No country specified? Always apply VAT! return True - if str(invoice_address.country) not in EU_COUNTRIES: + if not is_eu_country(invoice_address.country): # Non-EU country? Never apply VAT! return False diff --git a/src/pretix/base/services/invoices.py b/src/pretix/base/services/invoices.py index 128fb66c17..1de867a60a 100644 --- a/src/pretix/base/services/invoices.py +++ b/src/pretix/base/services/invoices.py @@ -24,7 +24,7 @@ from pretix.base.i18n import language from pretix.base.models import ( Invoice, InvoiceAddress, InvoiceLine, Order, OrderFee, ) -from pretix.base.models.tax import EU_COUNTRIES, EU_CURRENCIES +from pretix.base.models.tax import EU_CURRENCIES, is_eu_country from pretix.base.services.tasks import TransactionAwareTask from pretix.base.settings import GlobalSettingsObject from pretix.base.signals import invoice_line_text, periodic_task @@ -181,7 +181,7 @@ def build_invoice(invoice: Invoice) -> Invoice: if reverse_charge: if invoice.additional_text: invoice.additional_text += "

" - if str(invoice.invoice_to_country) in EU_COUNTRIES: + if is_eu_country(invoice.invoice_to_country): invoice.additional_text += pgettext( "invoice", "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/EEC, VAT liability " diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index 953b5c2979..929c4dce35 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -45,7 +45,7 @@ from pretix.base.models import ( from pretix.base.models.orders import ( CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund, ) -from pretix.base.models.tax import EU_COUNTRIES, cc_to_vat_prefix +from pretix.base.models.tax import cc_to_vat_prefix, is_eu_country from pretix.base.payment import PaymentException from pretix.base.secrets import assign_ticket_secret from pretix.base.services import tickets @@ -1166,7 +1166,7 @@ class OrderCheckVATID(OrderView): messages.error(self.request, _('No country specified.')) return redirect(self.get_order_url()) - if str(ia.country) not in EU_COUNTRIES: + if not is_eu_country(ia.country): messages.error(self.request, _('VAT ID could not be checked since a non-EU country has been ' 'specified.')) return redirect(self.get_order_url())