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
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user