import uuid from datetime import datetime from decimal import Decimal from typing import TYPE_CHECKING from sqlalchemy import DateTime, ForeignKey, Numeric, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base if TYPE_CHECKING: from app.models.user import User from app.models.company import Company class OvertimeBalance(Base): """Kumuliertes Überstundenguthaben pro Mitarbeiter. total_hours = Summe aller genehmigten Überstunden aus time_entries taken_hours = bereits als Freizeitausgleich genommene Stunden available = total_hours - taken_hours """ __tablename__ = "overtime_balances" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, unique=True, index=True, ) company_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("companies.id", ondelete="CASCADE"), nullable=False, index=True ) total_hours: Mapped[Decimal] = mapped_column(Numeric(8, 2), default=Decimal("0")) taken_hours: Mapped[Decimal] = mapped_column(Numeric(8, 2), default=Decimal("0")) last_calculated: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) last_expiry_applied_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() ) user: Mapped["User"] = relationship("User", lazy="noload") company: Mapped["Company"] = relationship("Company", lazy="noload") @property def available_hours(self) -> Decimal: return self.total_hours - self.taken_hours def __repr__(self) -> str: return f""