Fixes aus den Audits (Fable/Codex): Doppelte, Staffel, Export-Sperre, Netz-DB, atomare Einstellungen, Formeln, Wiederherstellung, Importgrenzen, schnellere Suche; toter Code entfernt; Version 1.8.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
72677ebed7
commit
968c68ac1a
12 files changed
+536
-178
No files matched your search
+13
-2
@@ -101,6 +101,8 @@ def schreibe_xlsx(ziel: str | Path, positionen: list[dict], *, kopfzeile: bool =
|
||||
]
|
||||
for c, v in enumerate(werte, start=1):
|
||||
cell = ws.cell(zeile, c, v)
|
||||
if isinstance(v, str) and v.startswith("="):
|
||||
cell.data_type = "s" # Text aus der Abrechnung bleibt Text – nie eine Formel
|
||||
cell.font = bold if p.get("_summe") and c in (2, 11) else font
|
||||
ws.cell(zeile, 4).number_format = "DD.MM.YYYY"
|
||||
if isinstance(werte[0], date):
|
||||
@@ -130,9 +132,11 @@ def schreibe_xlsx(ziel: str | Path, positionen: list[dict], *, kopfzeile: bool =
|
||||
|
||||
def exportiere_haendler(ordner: str | Path, haendler_name: str, positionen: list[dict], titel: str, *,
|
||||
pro_anbieter: bool = False, kopfzeile: bool = False, summe: bool = True,
|
||||
null_weglassen: bool = True) -> list[Path]:
|
||||
null_weglassen: bool = True, vergeben: set[str] | None = None) -> list[Path]:
|
||||
"""Schreibt die Abrechnung eines Händlers (bei pro_anbieter je Anbieter eine) und – falls es Airtime
|
||||
gibt – die Airtime-Liste. In der Abrechnung steht Airtime nur als eine Summenzeile.
|
||||
vergeben: Dateinamen (klein geschrieben), die in diesem Export schon geschrieben wurden – gleich
|
||||
lautende Namen (z. B. Händler „A/B“ und „A:B“) bekommen „ (2)“ statt die Datei zu überschreiben.
|
||||
Gibt die erzeugten Pfade zurück."""
|
||||
ordner = Path(ordner)
|
||||
if null_weglassen:
|
||||
@@ -142,9 +146,16 @@ def exportiere_haendler(ordner: str | Path, haendler_name: str, positionen: list
|
||||
gruppen: dict[str, list[dict]] = {}
|
||||
for p in positionen:
|
||||
gruppen.setdefault(p["anbieter"] if pro_anbieter else "", []).append(p)
|
||||
vergeben = set() if vergeben is None else vergeben
|
||||
|
||||
def name(*teile) -> str:
|
||||
return dateiname(" - ".join(t for t in (haendler_name,) + teile + (titel,) if t)) + ".xlsx"
|
||||
basis = dateiname(" - ".join(t for t in (haendler_name,) + teile + (titel,) if t))
|
||||
for n in range(1, 1000):
|
||||
kandidat = basis + (f" ({n})" if n > 1 else "") + ".xlsx"
|
||||
if kandidat.lower() not in vergeben:
|
||||
vergeben.add(kandidat.lower())
|
||||
return kandidat
|
||||
raise ValueError(f"Kein freier Dateiname für {basis}")
|
||||
|
||||
out = []
|
||||
for anbieter, pos in sorted(gruppen.items()):
|
||||
|
||||
Reference in new issue
Block a user