Files
MABEA/backend/app/models/wartung.py
T
patrickandClaude Sonnet 5 2a4d391711
CI / backend-tests (push) Failing after 2m4s
CI / frontend-build (push) Successful in 18s
feat(maintenance): MAINT-Epic (Wartungspläne/-aufträge, Werkstatt) + Akte-Redesign
Neues Wartungskonzept: Wartungsplan+Position+Intervall (zeit/km/
Betriebsstunden, kombinierbar - fällig sobald ein Kriterium erreicht
ist), Wartungsauftrag mit intern/externer Werkstatt, Status offen/
in_arbeit/erledigt, Kosten, Historie, Dokument-Anhang. Ad-hoc-Aufträge
ohne Plan möglich (z.B. kleinere Reparatur). Admin-Tab "Wartungspläne".

Objektakte-Redesign (Epic 21, Nutzer-Feedback "wirkt nicht modern"):
CSS-Grid statt Karten-Stapel, einspaltig mobil, zweispaltig ab 900px;
Fahrzeug-Objekte zeigen Wartung/Fahrzeugdaten prominent, Geräte/
Rucksäcke die Beladung. Dabei gefundene Lücke: Beladung (Soll/Ist je
Position) fehlte in der Akte komplett, nur über eine laufende
Kontrolle sichtbar - jetzt eigene Karte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-06 23:17:39 +02:00

81 lines
3.2 KiB
Python

import enum
import uuid
from datetime import date, datetime
from decimal import Decimal
from sqlalchemy import ForeignKey, Integer, Numeric, String, Text
from sqlalchemy.dialects.postgresql import ENUM as PgEnum, TIMESTAMP, UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base import Base
class IntervallTyp(str, enum.Enum):
zeit = "zeit"
km = "km"
betriebsstunden = "betriebsstunden"
class WartungsauftragStatus(str, enum.Enum):
offen = "offen"
in_arbeit = "in_arbeit"
erledigt = "erledigt"
intervall_typ_pg = PgEnum(IntervallTyp, name="intervall_typ", create_type=False)
wartungsauftrag_status_pg = PgEnum(WartungsauftragStatus, name="wartungsauftrag_status", create_type=False)
class Wartungsplan(Base):
__tablename__ = "wartungsplan"
id: Mapped[int] = mapped_column(primary_key=True)
objekttyp_id: Mapped[int] = mapped_column(ForeignKey("objekttyp.id"), nullable=False)
name: Mapped[str] = mapped_column(String, nullable=False)
class WartungsplanPosition(Base):
__tablename__ = "wartungsplan_position"
id: Mapped[int] = mapped_column(primary_key=True)
wartungsplan_id: Mapped[int] = mapped_column(ForeignKey("wartungsplan.id"), nullable=False)
wartungsart: Mapped[str] = mapped_column(String, nullable=False)
beschreibung: Mapped[str | None] = mapped_column(Text)
class Wartungsintervall(Base):
__tablename__ = "wartungsintervall"
id: Mapped[int] = mapped_column(primary_key=True)
wartungsplan_position_id: Mapped[int] = mapped_column(
ForeignKey("wartungsplan_position.id"), nullable=False
)
typ: Mapped[IntervallTyp] = mapped_column(intervall_typ_pg, nullable=False)
# zeit: Monate. km/betriebsstunden: Einheit des jeweiligen Fahrzeugdetails-Feldes.
wert: Mapped[int] = mapped_column(Integer, nullable=False)
class Wartungsauftrag(Base):
__tablename__ = "wartungsauftrag"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
objekt_id: Mapped[int] = mapped_column(ForeignKey("objekt.id"), nullable=False)
geraet_instanz_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True), ForeignKey("geraet_instanz.id")
)
wartungsplan_position_id: Mapped[int | None] = mapped_column(ForeignKey("wartungsplan_position.id"))
wartungsart: Mapped[str] = mapped_column(String, nullable=False)
beschreibung: Mapped[str | None] = mapped_column(Text)
status: Mapped[WartungsauftragStatus] = mapped_column(
wartungsauftrag_status_pg, nullable=False, default=WartungsauftragStatus.offen
)
werkstatt_intern: Mapped[bool] = mapped_column(nullable=False, default=True)
werkstatt_name: Mapped[str | None] = mapped_column(String)
faelligkeit_am: Mapped[date | None] = mapped_column()
erstellt_am: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), nullable=False)
erledigt_am: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True))
durchgefuehrt_von: Mapped[int | None] = mapped_column(ForeignKey("benutzer.id"))
kosten: Mapped[Decimal | None] = mapped_column(Numeric)
kilometerstand_bei_erledigung: Mapped[int | None] = mapped_column(Integer)
betriebsstunden_bei_erledigung: Mapped[Decimal | None] = mapped_column(Numeric)