mirror of
https://github.com/pretix/pretix.git
synced 2026-05-13 16:33:59 +00:00
Invoices: Allow to use currency rates from National Bank of Poland (#6100)
This commit is contained in:
@@ -38,6 +38,7 @@ SOURCE_NAMES = {
|
|||||||
None: _('European Central Bank'), # backwards-compatibility
|
None: _('European Central Bank'), # backwards-compatibility
|
||||||
'eu:ecb:eurofxref-daily': _('European Central Bank'),
|
'eu:ecb:eurofxref-daily': _('European Central Bank'),
|
||||||
'cz:cnb:rate-fixing-daily': _('Czech National Bank'),
|
'cz:cnb:rate-fixing-daily': _('Czech National Bank'),
|
||||||
|
'pl:nbp:table-a': _('National Bank of Poland'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ def fetch_rates(sender, **kwargs):
|
|||||||
source_tasks = {
|
source_tasks = {
|
||||||
'eu:ecb:eurofxref-daily': fetch_ecb_rates,
|
'eu:ecb:eurofxref-daily': fetch_ecb_rates,
|
||||||
'cz:cnb:rate-fixing-daily': fetch_cnb_cz_rates,
|
'cz:cnb:rate-fixing-daily': fetch_cnb_cz_rates,
|
||||||
|
'pl:nbp:table-a': fetch_nbp_pl_rates,
|
||||||
}
|
}
|
||||||
|
|
||||||
for source_name, task in source_tasks.items():
|
for source_name, task in source_tasks.items():
|
||||||
@@ -144,3 +146,29 @@ def fetch_cnb_cz_rates():
|
|||||||
rate=rate,
|
rate=rate,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.task()
|
||||||
|
def fetch_nbp_pl_rates():
|
||||||
|
"""
|
||||||
|
Fetches currency rates from the Polish National Bank.
|
||||||
|
"""
|
||||||
|
r = requests.get("https://api.nbp.pl/api/exchangerates/tables/A/", headers={
|
||||||
|
"Accept": "application/json",
|
||||||
|
})
|
||||||
|
r.raise_for_status()
|
||||||
|
data = r.json()[0]
|
||||||
|
|
||||||
|
source_date = datetime.strptime(data["effectiveDate"], "%Y-%m-%d").date()
|
||||||
|
|
||||||
|
for r in data["rates"]:
|
||||||
|
rate = Decimal(r["mid"]).quantize(Decimal('0.000001'))
|
||||||
|
ExchangeRate.objects.update_or_create(
|
||||||
|
source='pl:nbp:table-a',
|
||||||
|
source_currency=r["code"],
|
||||||
|
other_currency='PLN',
|
||||||
|
defaults=dict(
|
||||||
|
source_date=source_date,
|
||||||
|
rate=rate,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|||||||
@@ -205,6 +205,19 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP)
|
invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP)
|
||||||
invoice.foreign_currency_rate_date = rate.source_date
|
invoice.foreign_currency_rate_date = rate.source_date
|
||||||
invoice.foreign_currency_source = 'cz:cnb:rate-fixing-daily'
|
invoice.foreign_currency_source = 'cz:cnb:rate-fixing-daily'
|
||||||
|
elif invoice.event.settings.invoice_eu_currencies == 'PLN' and invoice.event.currency != 'PLN':
|
||||||
|
invoice.foreign_currency_display = 'PLN'
|
||||||
|
if settings.FETCH_ECB_RATES:
|
||||||
|
rate = ExchangeRate.objects.filter(
|
||||||
|
source='pl:nbp:table-a',
|
||||||
|
source_currency=invoice.event.currency,
|
||||||
|
other_currency=invoice.foreign_currency_display,
|
||||||
|
source_date__gt=now().date() - timedelta(days=7)
|
||||||
|
).first()
|
||||||
|
if rate:
|
||||||
|
invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP)
|
||||||
|
invoice.foreign_currency_rate_date = rate.source_date
|
||||||
|
invoice.foreign_currency_source = 'pl:nbp:table-a'
|
||||||
|
|
||||||
except InvoiceAddress.DoesNotExist:
|
except InvoiceAddress.DoesNotExist:
|
||||||
ia = None
|
ia = None
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ DEFAULTS = {
|
|||||||
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
|
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
|
||||||
'country that uses a different currency.')),
|
'country that uses a different currency.')),
|
||||||
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
|
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
|
||||||
|
('PLN', _('Based on National Bank of Poland daily rates, whenever the invoice amount is not in PLN.')),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'serializer_kwargs': dict(
|
'serializer_kwargs': dict(
|
||||||
@@ -582,6 +583,7 @@ DEFAULTS = {
|
|||||||
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
|
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
|
||||||
'country that uses a different currency.')),
|
'country that uses a different currency.')),
|
||||||
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
|
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
|
||||||
|
('PLN', _('Based on National Bank of Poland daily rates, whenever the invoice amount is not in PLN.')),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ def env():
|
|||||||
ExchangeRate.objects.create(source_date=date.today(), source='eu:ecb:eurofxref-daily', source_currency='EUR', other_currency=currency, rate=rate)
|
ExchangeRate.objects.create(source_date=date.today(), source='eu:ecb:eurofxref-daily', source_currency='EUR', other_currency=currency, rate=rate)
|
||||||
ExchangeRate.objects.create(source_date=date.today(), source='cz:cnb:rate-fixing-daily', source_currency='EUR',
|
ExchangeRate.objects.create(source_date=date.today(), source='cz:cnb:rate-fixing-daily', source_currency='EUR',
|
||||||
other_currency='CZK', rate=Decimal('25.0000'))
|
other_currency='CZK', rate=Decimal('25.0000'))
|
||||||
|
ExchangeRate.objects.create(source_date=date.today(), source='pl:nbp:table-a', source_currency='EUR',
|
||||||
|
other_currency='PLN', rate=Decimal('4.2355'))
|
||||||
yield event, o
|
yield event, o
|
||||||
|
|
||||||
|
|
||||||
@@ -347,6 +349,23 @@ def test_invoice_indirect_currency_conversion(env):
|
|||||||
assert inv.foreign_currency_source == 'eu:ecb:eurofxref-daily'
|
assert inv.foreign_currency_source == 'eu:ecb:eurofxref-daily'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_invoice_pln_currency_conversion(env):
|
||||||
|
event, order = env
|
||||||
|
event.settings.invoice_eu_currencies = 'PLN'
|
||||||
|
|
||||||
|
event.settings.set('invoice_language', 'en')
|
||||||
|
InvoiceAddress.objects.create(company='Acme Company', street='221B Baker Street', zipcode='12345', city='Warsaw',
|
||||||
|
country=Country('PL'), vat_id='PL123456780', vat_id_validated=True, order=order,
|
||||||
|
is_business=True)
|
||||||
|
|
||||||
|
inv = generate_invoice(order)
|
||||||
|
assert inv.foreign_currency_display == "PLN"
|
||||||
|
assert inv.foreign_currency_rate == Decimal("4.2355")
|
||||||
|
assert inv.foreign_currency_rate_date == date.today()
|
||||||
|
assert inv.foreign_currency_source == 'pl:nbp:table-a'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_invoice_czk_currency_conversion(env):
|
def test_invoice_czk_currency_conversion(env):
|
||||||
event, order = env
|
event, order = env
|
||||||
|
|||||||
Reference in New Issue
Block a user