Provisions-Manager 95: Import, Händler-DB, Auszahlungsregeln, Excel-Export, Win95-Oberfläche, Wine-Build
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
da2e3c9ba1
25 files changed
+3366
No files matched your search
@@ -0,0 +1,71 @@
|
||||
"""Geldbeträge werden intern immer als ganze Cent (int) geführt – keine Float-Rundungsfehler."""
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
|
||||
|
||||
|
||||
def parse_cent(value) -> int:
|
||||
"""Wandelt '1.234,56', '-8', '30', 12.5, '12.50 €' usw. in Cent um."""
|
||||
if value is None:
|
||||
return 0
|
||||
if isinstance(value, bool):
|
||||
raise ValueError("Ungültiger Betrag")
|
||||
if isinstance(value, int):
|
||||
return value * 100
|
||||
if isinstance(value, float):
|
||||
return int(Decimal(str(value)).scaleb(2).quantize(Decimal(1), ROUND_HALF_UP))
|
||||
s = str(value).strip().replace("€", "").replace("EUR", "").replace(" ", "").replace("\xa0", "")
|
||||
if not s:
|
||||
return 0
|
||||
neg = False
|
||||
if s.endswith("-"): # SAP-Stil: '30,00-'
|
||||
neg, s = True, s[:-1]
|
||||
if "," in s and "." in s:
|
||||
if s.rfind(",") > s.rfind("."):
|
||||
s = s.replace(".", "").replace(",", ".") # 1.234,56
|
||||
else:
|
||||
s = s.replace(",", "") # 1,234.56
|
||||
elif "," in s:
|
||||
s = s.replace(",", ".")
|
||||
try:
|
||||
d = Decimal(s)
|
||||
except InvalidOperation as exc:
|
||||
raise ValueError(f"Ungültiger Betrag: {value!r}") from exc
|
||||
cent = int(d.scaleb(2).quantize(Decimal(1), ROUND_HALF_UP))
|
||||
return -cent if neg else cent
|
||||
|
||||
|
||||
def apply_percent(cent: int, prozent: float) -> int:
|
||||
d = Decimal(cent) * Decimal(str(prozent)) / Decimal(100)
|
||||
return int(d.quantize(Decimal(1), ROUND_HALF_UP))
|
||||
|
||||
|
||||
def fmt(cent: int | None, symbol: bool = True) -> str:
|
||||
if cent is None:
|
||||
return ""
|
||||
neg = cent < 0
|
||||
cent = abs(cent)
|
||||
euro, rest = divmod(cent, 100)
|
||||
s = f"{euro:,}".replace(",", ".") + f",{rest:02d}"
|
||||
if neg:
|
||||
s = "-" + s
|
||||
return s + (" €" if symbol else "")
|
||||
|
||||
|
||||
def to_euro(cent: int) -> float:
|
||||
return float(Decimal(cent) / Decimal(100))
|
||||
|
||||
|
||||
def fmt_percent(p: float | None) -> str:
|
||||
if p is None:
|
||||
return ""
|
||||
s = f"{p:.2f}".rstrip("0").rstrip(".")
|
||||
return s.replace(".", ",") + " %"
|
||||
|
||||
|
||||
def parse_percent(text: str) -> float:
|
||||
s = str(text).strip().replace("%", "").replace(" ", "").replace(",", ".")
|
||||
p = float(s)
|
||||
if p < 0 or p > 1000:
|
||||
raise ValueError("Prozentwert außerhalb des gültigen Bereichs")
|
||||
return p
|
||||
Reference in new issue
Block a user