Feature: Pflege-Routinen (Zecken-/Flohschutz, Krallen, Fellpflege) — neuer Pflege-Tab mit Erledigt+Auto-Wiedervorlage, Push-Erinnerungen, intervall_tage-Fix im INSERT, SW v1132

This commit is contained in:
rene 2026-05-29 10:32:05 +02:00
parent 8c2bc0c445
commit a356626d39
9 changed files with 187 additions and 26 deletions

View file

@ -15,7 +15,9 @@ MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")
ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp", ".pdf"}
# Erlaubte Typen
TYPEN = {"impfung", "entwurmung", "tierarzt", "medikament", "gewicht", "allergie", "dokument", "laeufigkeit"}
# Routine-/Pflege-Typen (wiederkehrend mit intervall_tage): parasit, krallen, fellpflege
TYPEN = {"impfung", "entwurmung", "tierarzt", "medikament", "gewicht", "allergie", "dokument",
"laeufigkeit", "parasit", "krallen", "fellpflege"}
# ------------------------------------------------------------------
@ -164,15 +166,15 @@ async def create_health(dog_id: int, data: HealthCreate,
(dog_id, typ, bezeichnung, datum, naechstes, notiz,
wert, einheit, charge_nr, tierarzt_name, kosten, diagnose,
dosierung, haeufigkeit, aktiv, bis_datum,
schweregrad, reaktion, erinnerung, tierarzt_id,
schweregrad, reaktion, erinnerung, intervall_tage, tierarzt_id,
deckdatum, wurftermin)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
(dog_id, data.typ, data.bezeichnung, data.datum, data.naechstes,
data.notiz, data.wert, data.einheit, data.charge_nr,
data.tierarzt_name, data.kosten, data.diagnose, data.dosierung,
data.haeufigkeit, data.aktiv, data.bis_datum,
data.schweregrad, data.reaktion, data.erinnerung, data.tierarzt_id,
data.deckdatum, data.wurftermin)
data.schweregrad, data.reaktion, data.erinnerung, data.intervall_tage,
data.tierarzt_id, data.deckdatum, data.wurftermin)
)
row = conn.execute(
"SELECT * FROM health WHERE dog_id=? ORDER BY id DESC LIMIT 1",
@ -212,6 +214,34 @@ async def update_health(dog_id: int, entry_id: int, data: HealthUpdate,
return _entry_with_media(row, media_map)
# ------------------------------------------------------------------
# POST /api/dogs/{dog_id}/health/{id}/erledigt
# Markiert eine wiederkehrende Routine als heute erledigt und schreibt
# bei gesetztem intervall_tage das nächste Fälligkeitsdatum automatisch fort.
# ------------------------------------------------------------------
@router.post("/{dog_id}/health/{entry_id}/erledigt")
async def complete_health(dog_id: int, entry_id: int, user=Depends(get_current_user)):
from datetime import timedelta
today = date.today()
with db() as conn:
_check_dog_owner(conn, dog_id, user["id"])
entry = conn.execute(
"SELECT * FROM health WHERE id=? AND dog_id=?", (entry_id, dog_id)
).fetchone()
if not entry:
raise HTTPException(404, "Eintrag nicht gefunden.")
intervall = entry["intervall_tage"]
naechstes = (today + timedelta(days=intervall)).isoformat() if intervall else None
conn.execute(
"UPDATE health SET datum=?, naechstes=? WHERE id=?",
(today.isoformat(), naechstes, entry_id),
)
row = conn.execute("SELECT * FROM health WHERE id=?", (entry_id,)).fetchone()
media_map = _fetch_media_items(conn, [entry_id])
return _entry_with_media(row, media_map)
# ------------------------------------------------------------------
# DELETE /api/dogs/{dog_id}/health/{id}
# ------------------------------------------------------------------
@ -500,6 +530,9 @@ _TERMIN_TYPEN = {
'tierarzt': {'label': 'Tierarztbesuch','beim_tierarzt': True, 'icon': 'first-aid'},
'medikament': {'label': 'Medikament', 'beim_tierarzt': False, 'icon': 'pill'},
'laeufigkeit': {'label': 'Läufigkeit', 'beim_tierarzt': False, 'icon': 'calendar'},
'parasit': {'label': 'Zecken-/Flohschutz', 'beim_tierarzt': False, 'icon': 'bug-beetle'},
'krallen': {'label': 'Krallen schneiden', 'beim_tierarzt': False, 'icon': 'scissors'},
'fellpflege': {'label': 'Fellpflege', 'beim_tierarzt': False, 'icon': 'wind'},
}
@router.get("/{dog_id}/health/terminvorschlaege")