feat(objekt): letzte abgeschlossene Kontrolle je Objekt anzeigen
Bisher nirgends vermerkt/abrufbar, wann ein Objekt zuletzt komplett
kontrolliert wurde (nur roh in kontrolle.beendet_am ableitbar). Neues Feld
ObjektRead.letzte_kontrolle_am (jüngste Kontrolle mit status=abgeschlossen),
angezeigt in Objektliste und Admin-Objektsektion ("noch nie kontrolliert"
falls keine).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import re
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.kontrolle import Kontrolle, KontrollStatus
|
||||
from app.models.objekt import Objekt
|
||||
from app.models.objektposition import Objektposition, ObjektpositionStatus
|
||||
from app.models.vorlage import Beladungsvorlage, Vorlagenposition
|
||||
@@ -29,6 +31,22 @@ async def naechster_freier_code(db: AsyncSession, spalte, praefix: str) -> str:
|
||||
return f"{praefix}-{hoechste + 1:0{breite}d}"
|
||||
|
||||
|
||||
async def letzte_kontrollen_map(db: AsyncSession, objekt_ids: list[int]) -> dict[int, datetime]:
|
||||
"""Nutzer-Frage: "wann war die letzte komplette Kontrolle vom Objekt" - bisher
|
||||
nirgends vermerkt (kein Cache-Feld am Objekt, nur ableitbar aus kontrolle.
|
||||
beendet_am). Liefert je Objekt den jüngsten Abschluss-Zeitpunkt einer
|
||||
Kontrolle mit status=abgeschlossen; Objekte ohne abgeschlossene Kontrolle
|
||||
fehlen im Ergebnis (Aufrufer behandelt das als "noch nie kontrolliert")."""
|
||||
if not objekt_ids:
|
||||
return {}
|
||||
result = await db.execute(
|
||||
select(Kontrolle.objekt_id, func.max(Kontrolle.beendet_am))
|
||||
.where(Kontrolle.objekt_id.in_(objekt_ids), Kontrolle.status == KontrollStatus.abgeschlossen)
|
||||
.group_by(Kontrolle.objekt_id)
|
||||
)
|
||||
return {objekt_id: beendet_am for objekt_id, beendet_am in result.all()}
|
||||
|
||||
|
||||
async def sollmenge_map(db: AsyncSession, vorlage_id: int | None) -> dict[int, Decimal]:
|
||||
"""material_id -> Sollmenge laut Vorlage (Prompt 10: Basis für die dynamische
|
||||
Auflösung, wenn eine Objektposition keinen Override hat)."""
|
||||
|
||||
Reference in New Issue
Block a user