88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from datetime import date, datetime
|
||
from decimal import Decimal, InvalidOperation
|
||
from .extensions import db
|
||
from .models import AppSetting
|
||
|
||
KEYS = {
|
||
"enabled": "global_vat_override_enabled",
|
||
"name": "global_vat_override_name",
|
||
"rate": "global_vat_override_rate",
|
||
"start": "global_vat_override_start",
|
||
"end": "global_vat_override_end",
|
||
}
|
||
|
||
|
||
def _value(key, default=""):
|
||
setting = db.session.get(AppSetting, KEYS[key])
|
||
return setting.value if setting else default
|
||
|
||
|
||
def global_vat_override():
|
||
rate_raw = _value("rate")
|
||
try:
|
||
rate = Decimal(rate_raw) if rate_raw != "" else None
|
||
except InvalidOperation:
|
||
rate = None
|
||
return {
|
||
"enabled": _value("enabled", "0") == "1",
|
||
"name": _value("name", "Projekt rządowy"),
|
||
"rate": rate,
|
||
"start": _parse_date(_value("start")),
|
||
"end": _parse_date(_value("end")),
|
||
}
|
||
|
||
|
||
def _parse_date(value):
|
||
if not value:
|
||
return None
|
||
try:
|
||
return date.fromisoformat(value)
|
||
except ValueError:
|
||
return None
|
||
|
||
|
||
def effective_vat_rate(nominal_rate, on_date=None):
|
||
override = global_vat_override()
|
||
if not override["enabled"] or override["rate"] is None:
|
||
return Decimal(str(nominal_rate))
|
||
if isinstance(on_date, datetime):
|
||
on_date = on_date.date()
|
||
on_date = on_date or date.today()
|
||
if override["start"] and on_date < override["start"]:
|
||
return Decimal(str(nominal_rate))
|
||
if override["end"] and on_date > override["end"]:
|
||
return Decimal(str(nominal_rate))
|
||
return override["rate"]
|
||
|
||
|
||
def save_global_vat_override(form):
|
||
enabled = "enabled" in form
|
||
name = (form.get("name") or "Projekt rządowy").strip()
|
||
rate_raw = (form.get("rate") or "").strip()
|
||
start_raw = (form.get("start") or "").strip()
|
||
end_raw = (form.get("end") or "").strip()
|
||
|
||
if enabled:
|
||
try:
|
||
rate = Decimal(rate_raw)
|
||
except InvalidOperation as exc:
|
||
raise ValueError("Podaj prawidłową globalną stawkę VAT.") from exc
|
||
if rate < 0 or rate > 100:
|
||
raise ValueError("Globalna stawka VAT musi mieścić się w zakresie 0–100%.")
|
||
if start_raw and not _parse_date(start_raw):
|
||
raise ValueError("Nieprawidłowa data rozpoczęcia.")
|
||
if end_raw and not _parse_date(end_raw):
|
||
raise ValueError("Nieprawidłowa data zakończenia.")
|
||
if start_raw and end_raw and start_raw > end_raw:
|
||
raise ValueError("Data zakończenia nie może być wcześniejsza niż rozpoczęcia.")
|
||
|
||
values = {
|
||
KEYS["enabled"]: "1" if enabled else "0",
|
||
KEYS["name"]: name,
|
||
KEYS["rate"]: rate_raw,
|
||
KEYS["start"]: start_raw,
|
||
KEYS["end"]: end_raw,
|
||
}
|
||
for key, value in values.items():
|
||
db.session.merge(AppSetting(key=key, value=value))
|