From 6503beb92abe4913f1fbca74c5f1687d4209e982 Mon Sep 17 00:00:00 2001 From: patrick Date: Fri, 4 Sep 2026 00:27:42 +0200 Subject: [PATCH] =?UTF-8?q?fix(import):=20Mengen=20zusammenf=C3=BChren=20b?= =?UTF-8?q?ei=20Mehrfach-Fach=20desselben=20Materials?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Realer Fund beim ersten Import-Lauf gegen den Zielserver: vorlagenposition erlaubt nur eine Zeile pro Material+Vorlage, Excel-Listen führen aber manches Material in mehreren Fächern - UniqueViolationError. Fix: Mengen addieren, Fächer als Liste zusammenführen statt zweite Zeile einzufügen. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt --- backend/scripts/import_excel.py | 26 +++++++++++++++++++------- ergebnisse/testphasen.md | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/backend/scripts/import_excel.py b/backend/scripts/import_excel.py index 85f11bd..331415d 100644 --- a/backend/scripts/import_excel.py +++ b/backend/scripts/import_excel.py @@ -178,16 +178,28 @@ async def importiere_datei(db: AsyncSession, datei: ImportDatei, objekttyp: Obje db.add(vorlage) await db.flush() + positionen_je_material: dict[int, Vorlagenposition] = {} for zeile in datei.zeilen: material = await _hole_oder_erstelle_material(db, zeile) - db.add( - Vorlagenposition( - vorlage_id=vorlage.id, - material_id=material.id, - fach=zeile.fach, - sollmenge=zeile.menge, - ) + bestehende_position = positionen_je_material.get(material.id) + if bestehende_position is not None: + # Gleiches Material in mehreren Fächern derselben Liste (z. B. Verbandsmaterial + # in mehreren Taschen) - Schema erlaubt nur eine Zeile pro Material+Vorlage, + # daher Mengen zusammenführen statt zweite Zeile einzufügen (führt sonst zu + # UniqueViolationError auf vorlage_id+material_id). + bestehende_position.sollmenge += zeile.menge + if zeile.fach and zeile.fach not in (bestehende_position.fach or ""): + bestehende_position.fach = f"{bestehende_position.fach}, {zeile.fach}" if bestehende_position.fach else zeile.fach + continue + + position = Vorlagenposition( + vorlage_id=vorlage.id, + material_id=material.id, + fach=zeile.fach, + sollmenge=zeile.menge, ) + db.add(position) + positionen_je_material[material.id] = position return vorlage diff --git a/ergebnisse/testphasen.md b/ergebnisse/testphasen.md index c8b60fd..64baedb 100644 --- a/ergebnisse/testphasen.md +++ b/ergebnisse/testphasen.md @@ -126,6 +126,7 @@ Grundlage: die drei bestehenden Listen im Repo (`Handball Rucksack.xlsx`, `Rettu - Uneindeutige/fehlende Artikelnummern in den Quell-Listen (falls vorhanden) verhindern automatischen Abgleich – in diesen Fällen manuelle Zuordnung beim Import nötig. - Import-Skript selbst ist Code (Prompt-19-Deployment-Regel gilt: bei Umsetzung nur Skript-Datei erzeugen, Ausführung gegen Test-DB erst auf Zielsystem/Test-Deployment, nicht lokal). - Spalte D ist in den xlsx-Rohdaten teils als Datum formatiert (Excel-Zellformat, nicht Inhalt) - Werte wie 12754 sind aber kein plausibles Datum (Jahr ~1934), Mapping D=Artikelnummer bleibt daher wie oben bestätigt. Skript (`backend/scripts/import_excel.py`) liest den Rohwert unabhängig vom Zellformat. +- Gleiches Material kommt in einer Liste teils in mehreren Fächern vor (z. B. Verbandsmaterial in mehreren Taschen) - da `vorlagenposition` nur eine Zeile pro Material+Vorlage zulässt (Prompt 20-Schema), führt das Importskript solche Duplikate zusammen (Mengen addiert, Fächer als Liste), erste Erkenntnis erst beim echten Import-Lauf gegen den Zielserver, nicht vorher erkannt. ## Regeln übergreifend