fix(kontrolle): Abbruch löscht bereits nachgefüllten Fehlbestand nicht mehr
CI / backend-tests (push) Successful in 57s
CI / frontend-build (push) Successful in 5m12s

Beim Testen des neuen Inline-Nachfüll-Dialogs (Karte 07) gefunden: Sofort-
Nachfüllung während laufender Kontrolle + anschließender Abbruch führte zu
IntegrityError (FK-Verweis aus nachfuellung), da _verwirf_kontrolldaten
jeden Fehlbestand der Kontrolle unbedingt löschte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
This commit is contained in:
2026-09-04 09:14:41 +02:00
co-authored by Claude Sonnet 5
parent d70558f124
commit 032126c605
2 changed files with 47 additions and 1 deletions
+7 -1
View File
@@ -3,7 +3,7 @@ from datetime import datetime, timezone
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.fehlbestand import Fehlbestand
from app.models.fehlbestand import Fehlbestand, FehlbestandStatus
from app.models.kontrolle import Kontrolle, KontrollStatus, Kontrollposition
from app.models.mindermenge import MindermengeStatus, MindermengenGenehmigung
from app.models.objektposition import Objektposition, ObjektpositionStatus
@@ -110,6 +110,12 @@ async def _lasse_mindermengen_ablaufen(
async def _verwirf_kontrolldaten(db: AsyncSession, kontrolle_id) -> None:
fehlbestaende = await db.execute(select(Fehlbestand).where(Fehlbestand.kontrolle_id == kontrolle_id))
for fehlbestand in fehlbestaende.scalars().all():
if fehlbestand.status != FehlbestandStatus.offen:
# Bereits (teilweise) nachgefüllt (Karte 07 Sofort-Nachfüllung während
# der Kontrolle) - das ist eine echte, dokumentierte Bestandsbewegung
# und darf beim Verwerfen/Abbruch der Kontrolle NICHT gelöscht werden
# (FK-Verweis aus nachfuellung + Historie müssen erhalten bleiben).
continue
await db.delete(fehlbestand)
positionen = await db.execute(select(Kontrollposition).where(Kontrollposition.kontrolle_id == kontrolle_id))
for position in positionen.scalars().all():
+40
View File
@@ -157,6 +157,46 @@ async def test_abbruch_verwirft_fehlbestand_und_positionen(
assert kontrolle.status == KontrollStatus.abgebrochen
@pytest.mark.asyncio
async def test_abbruch_nach_sofort_nachfuellung_loescht_fehlbestand_nicht(
client, db_session, objekt_mit_position, mitarbeiter_user
):
"""Karte 07: wird während der laufenden Kontrolle sofort nachgefüllt und die
Kontrolle danach abgebrochen (z. B. Einsatzalarmierung), darf der bereits
nachgefüllte Fehlbestand NICHT gelöscht werden - er ist eine echte
dokumentierte Bestandsbewegung, kein reiner Kontroll-Zwischenstand."""
objekt, material = objekt_mit_position
token = await login(client, "mitarbeiter1")
start = await _starte(client, token, objekt.id)
kontrolle_id = start.json()["id"]
erfassung = await client.put(
f"/api/v1/kontrollen/{kontrolle_id}/positionen/{material.id}",
json={"istmenge": "8"},
headers=auth_header(token),
)
fehlbestand_id = erfassung.json()["fehlbestand_id"]
assert fehlbestand_id is not None
nf = await client.post(
f"/api/v1/fehlbestaende/{fehlbestand_id}/nachfuellungen",
json={"menge": "2"},
headers=auth_header(token),
)
assert nf.status_code == 201
response = await client.post(
f"/api/v1/kontrollen/{kontrolle_id}/abbrechen",
json={"grund": "Einsatzalarmierung"},
headers=auth_header(token),
)
assert response.status_code == 200
fehlbestand = await db_session.get(Fehlbestand, fehlbestand_id)
assert fehlbestand is not None
assert fehlbestand.status.value == "erledigt"
@pytest.mark.asyncio
async def test_objekt_sperre_zweiter_zugriff_ist_409(
client, objekt_mit_position, mitarbeiter_user, mitarbeiter2_user