Feature: Warteliste pro Wurf — CRUD, Status-Flow, Formular (SW by-v891)

This commit is contained in:
rene 2026-05-13 16:45:46 +02:00
parent e8c2d5b940
commit 67e68bbe2d
8 changed files with 324 additions and 7 deletions

View file

@ -650,3 +650,98 @@ async def generate_contract(
</html>"""
return HTMLResponse(content=html)
# ------------------------------------------------------------------
# Warteliste
# ------------------------------------------------------------------
class WaitlistEntry(BaseModel):
name: str
email: Optional[str] = None
telefon: Optional[str] = None
nachricht: Optional[str] = None
wunsch_geschlecht: str = "egal"
wunsch_farbe: Optional[str] = None
prioritaet: int = 0
status: str = "anfrage"
notiz: Optional[str] = None
class WaitlistUpdate(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
telefon: Optional[str] = None
nachricht: Optional[str] = None
wunsch_geschlecht: Optional[str] = None
wunsch_farbe: Optional[str] = None
prioritaet: Optional[int] = None
status: Optional[str] = None
notiz: Optional[str] = None
@router.get("/litters/{litter_id}/waitlist")
async def get_waitlist(litter_id: int, user=Depends(_require_breeder)):
with db() as conn:
_check_litter_owner(litter_id, user, conn)
rows = conn.execute(
"SELECT * FROM litter_waitlist WHERE litter_id=? ORDER BY prioritaet, created_at",
(litter_id,)
).fetchall()
return [dict(r) for r in rows]
@router.post("/litters/{litter_id}/waitlist", status_code=201)
async def add_waitlist_entry(litter_id: int, body: WaitlistEntry, user=Depends(_require_breeder)):
with db() as conn:
_check_litter_owner(litter_id, user, conn)
cur = conn.execute(
"""INSERT INTO litter_waitlist
(litter_id, name, email, telefon, nachricht, wunsch_geschlecht, wunsch_farbe,
prioritaet, status, notiz)
VALUES (?,?,?,?,?,?,?,?,?,?)""",
(litter_id, body.name, body.email, body.telefon, body.nachricht,
body.wunsch_geschlecht, body.wunsch_farbe, body.prioritaet, body.status, body.notiz)
)
row = conn.execute("SELECT * FROM litter_waitlist WHERE id=?", (cur.lastrowid,)).fetchone()
return dict(row)
@router.put("/litters/waitlist/{entry_id}")
async def update_waitlist_entry(entry_id: int, body: WaitlistUpdate, user=Depends(_require_breeder)):
with db() as conn:
entry = conn.execute(
"""SELECT w.*, bp.user_id AS owner_user_id FROM litter_waitlist w
JOIN litters l ON l.id = w.litter_id
JOIN breeder_profiles bp ON bp.id = l.breeder_id
WHERE w.id=?""",
(entry_id,)
).fetchone()
if not entry:
raise HTTPException(404, "Eintrag nicht gefunden.")
if user["rolle"] != "admin" and entry["owner_user_id"] != user["id"]:
raise HTTPException(403, "Kein Zugriff.")
fields = {k: v for k, v in body.model_dump().items() if v is not None}
if not fields:
return dict(entry)
sets = ", ".join(f"{k}=?" for k in fields)
conn.execute(f"UPDATE litter_waitlist SET {sets} WHERE id=?", (*fields.values(), entry_id))
row = conn.execute("SELECT * FROM litter_waitlist WHERE id=?", (entry_id,)).fetchone()
return dict(row)
@router.delete("/litters/waitlist/{entry_id}", status_code=204)
async def delete_waitlist_entry(entry_id: int, user=Depends(_require_breeder)):
with db() as conn:
entry = conn.execute(
"""SELECT w.id, bp.user_id AS owner_user_id FROM litter_waitlist w
JOIN litters l ON l.id = w.litter_id
JOIN breeder_profiles bp ON bp.id = l.breeder_id
WHERE w.id=?""",
(entry_id,)
).fetchone()
if not entry:
raise HTTPException(404, "Eintrag nicht gefunden.")
if user["rolle"] != "admin" and entry["owner_user_id"] != user["id"]:
raise HTTPException(403, "Kein Zugriff.")
conn.execute("DELETE FROM litter_waitlist WHERE id=?", (entry_id,))