Files
patrickandClaude Sonnet 5 4a0d0fd5f1
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 22s
feat(verleih): Übergabeliste zum Unterschreiben (ASSET-013 Verleih-Teil)
Reines Druck-PDF (reportlab, kein digitaler Signatur-Workflow) mit
Objektpositionen (Soll/Ist), nach Fach gruppiert wo vorhanden, plus
Unterschriftsfelder für Übergeber/Übernehmer. Aussonderungs-Teil von
ASSET-013 bleibt offen (braucht erst neuen ObjektStatus).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:47:49 +02:00

140 lines
5.0 KiB
Python

from datetime import date, timedelta
from decimal import Decimal
import pytest
from app.models.objektposition import Objektposition
from tests.conftest import auth_header, login
@pytest.mark.asyncio
async def test_verleih_und_rueckgabe(client, db_session, admin_user, standort_factory, objekt_factory):
standort = await standort_factory("Wache-Verleih")
objekt = await objekt_factory(name="Notstromaggregat", code="VERLEIH-1", standort=standort)
token = await login(client, "admin1")
stelle = await client.post(
"/api/v1/externe-stellen",
json={"name": "Nachbar-Ortsverein", "kontakt": "kontakt@example.org"},
headers=auth_header(token),
)
assert stelle.status_code == 201
stelle_id = stelle.json()["id"]
verliehen = await client.post(
"/api/v1/verleihe",
json={
"objekt_id": objekt.id,
"externe_stelle_id": stelle_id,
"verliehen_am": date.today().isoformat(),
"voraussichtliche_rueckgabe_am": (date.today() + timedelta(days=7)).isoformat(),
},
headers=auth_header(token),
)
assert verliehen.status_code == 201
assert verliehen.json()["ueberfaellig"] is False
doppelt = await client.post(
"/api/v1/verleihe",
json={"objekt_id": objekt.id, "externe_stelle_id": stelle_id, "verliehen_am": date.today().isoformat()},
headers=auth_header(token),
)
assert doppelt.status_code == 409
rueckgabe = await client.post(f"/api/v1/objekte/{objekt.id}/verleih/rueckgabe", headers=auth_header(token))
assert rueckgabe.status_code == 200
assert rueckgabe.json()["tatsaechliche_rueckgabe_am"] == date.today().isoformat()
erneut = await client.post(f"/api/v1/objekte/{objekt.id}/verleih/rueckgabe", headers=auth_header(token))
assert erneut.status_code == 409
@pytest.mark.asyncio
async def test_verleih_ueberfaellig_erkennbar(client, db_session, admin_user, standort_factory, objekt_factory):
standort = await standort_factory("Wache-Verleih2")
objekt = await objekt_factory(name="Zelt", code="VERLEIH-2", standort=standort)
token = await login(client, "admin1")
stelle = await client.post(
"/api/v1/externe-stellen", json={"name": "Verein X"}, headers=auth_header(token)
)
stelle_id = stelle.json()["id"]
verliehen = await client.post(
"/api/v1/verleihe",
json={
"objekt_id": objekt.id,
"externe_stelle_id": stelle_id,
"verliehen_am": (date.today() - timedelta(days=10)).isoformat(),
"voraussichtliche_rueckgabe_am": (date.today() - timedelta(days=3)).isoformat(),
},
headers=auth_header(token),
)
assert verliehen.json()["ueberfaellig"] is True
liste = await client.get("/api/v1/verleihe?offen=true", headers=auth_header(token))
eintrag = next(v for v in liste.json() if v["objekt_id"] == objekt.id)
assert eintrag["ueberfaellig"] is True
@pytest.mark.asyncio
async def test_verleih_nur_materialverantwortliche(client, mitarbeiter_user):
token = await login(client, "mitarbeiter1")
response = await client.get("/api/v1/verleihe", headers=auth_header(token))
assert response.status_code == 403
@pytest.mark.asyncio
async def test_verleih_uebergabeliste_pdf(
client, db_session, admin_user, standort_factory, objekt_factory, material_factory
):
"""ASSET-013 (Verleih-Teil): Übergabeliste enthält den aktuellen
Ist-Bestand der Objektpositionen als PDF."""
standort = await standort_factory("Wache-Uebergabe")
objekt = await objekt_factory(name="Notstromaggregat", code="VERLEIH-PDF", standort=standort)
material = await material_factory("Verlängerungskabel")
db_session.add(
Objektposition(
objekt_id=objekt.id,
material_id=material.id,
sollmenge_vorlage=Decimal(2),
istmenge=Decimal(1),
)
)
await db_session.flush()
await db_session.commit()
token = await login(client, "admin1")
stelle = await client.post(
"/api/v1/externe-stellen", json={"name": "Nachbarwehr"}, headers=auth_header(token)
)
stelle_id = stelle.json()["id"]
verliehen = await client.post(
"/api/v1/verleihe",
json={
"objekt_id": objekt.id,
"externe_stelle_id": stelle_id,
"verliehen_am": date.today().isoformat(),
},
headers=auth_header(token),
)
verleih_id = verliehen.json()["id"]
pdf_response = await client.get(
f"/api/v1/verleihe/{verleih_id}/uebergabeliste", headers=auth_header(token)
)
assert pdf_response.status_code == 200
assert pdf_response.headers["content-type"] == "application/pdf"
assert pdf_response.content.startswith(b"%PDF")
@pytest.mark.asyncio
async def test_verleih_uebergabeliste_404_bei_unbekanntem_verleih(client, admin_user):
token = await login(client, "admin1")
response = await client.get(
"/api/v1/verleihe/00000000-0000-0000-0000-000000000000/uebergabeliste",
headers=auth_header(token),
)
assert response.status_code == 404