fix(kontrolle): Abbruch löscht bereits nachgefüllten Fehlbestand nicht mehr
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:
@@ -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():
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user