from datetime import datetime, date from typing import TYPE_CHECKING from sqlalchemy import ForeignKey, Table, Column from sqlalchemy.sql import expression from sqlalchemy.orm import Mapped, mapped_column, relationship from models.base import BaseModel if TYPE_CHECKING: from models import User, Position class WorkShift(BaseModel): __tablename__ = "work_shifts" id: Mapped[int] = mapped_column(primary_key=True) started_at: Mapped[datetime] = mapped_column( nullable=False, ) finished_at: Mapped[datetime] = mapped_column( nullable=True, ) is_paused: Mapped[bool] = mapped_column( default=False, server_default=expression.false(), ) user_id: Mapped[int] = mapped_column( ForeignKey("users.id"), ) user: Mapped["User"] = relationship( "User", back_populates="work_shifts", lazy="selectin", ) pauses: Mapped[list["WorkShiftPause"]] = relationship( "WorkShiftPause", back_populates="work_shift", uselist=True, foreign_keys="[WorkShiftPause.work_shift_id]", cascade="all, delete", ) class WorkShiftPause(BaseModel): __tablename__ = "work_shifts_pauses" id: Mapped[int] = mapped_column(primary_key=True) started_at: Mapped[datetime] = mapped_column( nullable=False, ) finished_at: Mapped[datetime] = mapped_column( nullable=True, ) work_shift_id: Mapped[int] = mapped_column( ForeignKey("work_shifts.id"), ) work_shift: Mapped[WorkShift] = relationship( "WorkShift", back_populates="pauses", lazy="selectin", ) work_shifts_positions = Table( 'work_shifts_positions', BaseModel.metadata, Column('position_key', ForeignKey('positions.key'), primary_key=True), Column('work_shift_id', ForeignKey('planned_work_shifts.id'), primary_key=True), ) class PlannedWorkShift(BaseModel): __tablename__ = "planned_work_shifts" id: Mapped[int] = mapped_column(primary_key=True) shift_date: Mapped[date] = mapped_column(nullable=False, index=True) created_at: Mapped[datetime] = mapped_column(nullable=False) user_id: Mapped[int] = mapped_column(ForeignKey('users.id'), nullable=False, index=True) user: Mapped["User"] = relationship(lazy="selectin", backref="planned_work_shifts") positions: Mapped[list["Position"]] = relationship( "Position", uselist=True, secondary=work_shifts_positions, lazy="selectin", )