feat(wartung): MAINT-005 Ersatzteile/Kosten je Wartungsauftrag
CI / backend-tests (push) Successful in 2m22s
CI / frontend-build (push) Successful in 25s

Neue Tabelle wartungsauftrag_teil (Migration 0033), CRUD-Endpunkte
/wartungsauftraege/{id}/teile, UI-Panel in WartungSection.tsx mit
Summenanzeige. Backlog Epic 22 (UI-Redesign Runde 2, Kacheln UI2-001..005)
als geplant ergänzt, Umsetzung folgt separat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
2026-09-08 22:06:02 +02:00
co-authored by Claude Sonnet 5
parent 3b5cf8feab
commit 847c303a97
14 changed files with 5232 additions and 6 deletions
+70
View File
@@ -212,3 +212,73 @@ async def test_ad_hoc_reparatur_ohne_wartungsplan_mit_externer_werkstatt(
historie = await client.get(f"/api/v1/wartungsauftraege?objekt_id={objekt_id}", headers=auth_header(token))
assert len(historie.json()) == 1
@pytest.mark.anyio
async def test_wartungsauftrag_teile_erfassen_und_summieren(
client, admin_user, standort_factory, objekt_factory
):
token = await login(client, "admin1")
standort = await standort_factory("Standort-W6")
await objekt_factory(name="RTW W6", code="RTW-W6", standort=standort)
objekte = await client.get("/api/v1/objekte", headers=auth_header(token))
objekt_id = [o for o in objekte.json() if o["code"] == "RTW-W6"][0]["id"]
auftrag = await client.post(
"/api/v1/wartungsauftraege",
json={"objekt_id": objekt_id, "wartungsart": "Ölwechsel"},
headers=auth_header(token),
)
auftrag_id = auftrag.json()["id"]
teil1 = await client.post(
f"/api/v1/wartungsauftraege/{auftrag_id}/teile",
json={"bezeichnung": "Ölfilter", "menge": "1", "kosten": "12.50"},
headers=auth_header(token),
)
assert teil1.status_code == 201
teil2 = await client.post(
f"/api/v1/wartungsauftraege/{auftrag_id}/teile",
json={"bezeichnung": "Motoröl 5L", "menge": "2", "kosten": "45.00"},
headers=auth_header(token),
)
assert teil2.status_code == 201
liste = await client.get(f"/api/v1/wartungsauftraege/{auftrag_id}/teile", headers=auth_header(token))
positionen = liste.json()
assert len(positionen) == 2
gesamt = sum(float(p["kosten"]) for p in positionen)
assert gesamt == 57.50
loeschen = await client.delete(
f"/api/v1/wartungsauftraege/{auftrag_id}/teile/{teil1.json()['id']}", headers=auth_header(token)
)
assert loeschen.status_code == 204
liste_danach = await client.get(f"/api/v1/wartungsauftraege/{auftrag_id}/teile", headers=auth_header(token))
assert len(liste_danach.json()) == 1
@pytest.mark.anyio
async def test_mitarbeiter_darf_wartungsauftrag_teil_nicht_anlegen(
client, admin_user, mitarbeiter_user, standort_factory, objekt_factory
):
admin_token = await login(client, "admin1")
standort = await standort_factory("Standort-W7")
await objekt_factory(name="RTW W7", code="RTW-W7", standort=standort)
objekte = await client.get("/api/v1/objekte", headers=auth_header(admin_token))
objekt_id = [o for o in objekte.json() if o["code"] == "RTW-W7"][0]["id"]
auftrag = await client.post(
"/api/v1/wartungsauftraege",
json={"objekt_id": objekt_id, "wartungsart": "Ölwechsel"},
headers=auth_header(admin_token),
)
auftrag_id = auftrag.json()["id"]
mitarbeiter_token = await login(client, "mitarbeiter1")
antwort = await client.post(
f"/api/v1/wartungsauftraege/{auftrag_id}/teile",
json={"bezeichnung": "Ölfilter", "menge": "1", "kosten": "12.50"},
headers=auth_header(mitarbeiter_token),
)
assert antwort.status_code == 403