From cc016f09d39b29cc68d510bee138927a3fae682a Mon Sep 17 00:00:00 2001 From: patrick Date: Sun, 6 Sep 2026 23:48:31 +0200 Subject: [PATCH] feat(akte): Ablaufdatum in der Beladung-Tabelle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bevorstehende Ablaufdaten waren nur im Dashboard und als Einsatzbereitschafts-Grund sichtbar, nicht direkt an der jeweiligen Beladungsposition in der Akte. Neue Spalte "Ablauf", rot bei überfälligem, gelb bei <30 Tagen verbleibender Zeit. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV --- backend/app/schemas/akte.py | 3 ++- backend/app/services/akte.py | 1 + backend/tests/test_akte.py | 1 + frontend/src/api/types.ts | 1 + frontend/src/pages/AktePage.tsx | 11 +++++++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/app/schemas/akte.py b/backend/app/schemas/akte.py index ad0fd82..349b34d 100644 --- a/backend/app/schemas/akte.py +++ b/backend/app/schemas/akte.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime +from datetime import date, datetime from decimal import Decimal from pydantic import BaseModel, ConfigDict @@ -27,6 +27,7 @@ class BeladungsPosition(BaseModel): fach: str | None sollmenge: Decimal istmenge: Decimal + ablaufdatum: date | None class AkteRead(BaseModel): diff --git a/backend/app/services/akte.py b/backend/app/services/akte.py index 6bae501..b60a7ca 100644 --- a/backend/app/services/akte.py +++ b/backend/app/services/akte.py @@ -123,6 +123,7 @@ async def akte_fuer_objekt(db: AsyncSession, objekt_id: int) -> AkteRead | None: if material.materialtyp == MaterialTyp.geraet_sn else position.istmenge ), + ablaufdatum=position.ablaufdatum, ) for position, material in beladung_result.all() ] diff --git a/backend/tests/test_akte.py b/backend/tests/test_akte.py index fdbdb4a..ba0f104 100644 --- a/backend/tests/test_akte.py +++ b/backend/tests/test_akte.py @@ -54,6 +54,7 @@ async def test_akte_buendelt_teilbereiche(client, db_session, objekt_mit_positio assert body["beladung"][0]["material_id"] == _material.id assert body["beladung"][0]["sollmenge"] == "10" assert body["beladung"][0]["istmenge"] == "0" + assert body["beladung"][0]["ablaufdatum"] is None @pytest.mark.asyncio diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index 1e1848f..45cc64d 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -319,6 +319,7 @@ export interface BeladungsPosition { fach: string | null; sollmenge: string; istmenge: string; + ablaufdatum: string | null; } export interface Akte { diff --git a/frontend/src/pages/AktePage.tsx b/frontend/src/pages/AktePage.tsx index c4da991..dbbd84a 100644 --- a/frontend/src/pages/AktePage.tsx +++ b/frontend/src/pages/AktePage.tsx @@ -10,6 +10,13 @@ import { ReadinessBadge } from "../components/status/ReadinessBadge"; import { GRUND_TEXT } from "../components/status/gruendeText"; import { EREIGNIS_LABEL } from "../components/status/ereignisText"; +function ablaufFarbe(ablaufdatum: string): string | undefined { + const tage = (new Date(ablaufdatum).getTime() - Date.now()) / (1000 * 60 * 60 * 24); + if (tage < 0) return "var(--color-danger)"; + if (tage < 30) return "var(--color-warning)"; + return undefined; +} + const MANGEL_PRIORITAET_LABEL: Record = { niedrig: "Niedrig", normal: "Normal", @@ -120,6 +127,7 @@ export function AktePage() { Fach Soll Ist + Ablauf @@ -133,6 +141,9 @@ export function AktePage() { {b.istmenge} {b.einheit} + + {b.ablaufdatum ? new Date(b.ablaufdatum).toLocaleDateString("de-DE") : "–"} + ))}