from typing import Any, List, Optional, TYPE_CHECKING if TYPE_CHECKING: from .inventory import Inventory from .rooms import Room from .work_log import WorkLog from .image import Image from sqlalchemy import Boolean, ForeignKey, Identity, Integer, Unicode, text from sqlalchemy.orm import Mapped, mapped_column, relationship from . import db from .image import ImageAttachable class User(db.Model, ImageAttachable): __tablename__ = 'users' id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True) staff: Mapped[Optional[bool]] = mapped_column(Boolean, server_default=text('((0))')) active: Mapped[Optional[bool]] = mapped_column(Boolean, server_default=text('((0))')) last_name: Mapped[Optional[str]] = mapped_column(Unicode(255), nullable=True) first_name: Mapped[Optional[str]] = mapped_column(Unicode(255), nullable=True) title: Mapped[Optional[str]] = mapped_column(Unicode(255), nullable=True, default=None) location_id: Mapped[Optional[int]] = mapped_column(ForeignKey("rooms.id"), nullable=True, index=True) supervisor_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("users.id"), nullable=True, index=True) image_id: Mapped[Optional[int]] = mapped_column(ForeignKey('images.id', ondelete='SET NULL'), nullable=True, index=True) supervisor: Mapped[Optional['User']] = relationship('User', remote_side='User.id', back_populates='subordinates') subordinates: Mapped[List['User']] = relationship('User', back_populates='supervisor') work_logs: Mapped[List['WorkLog']] = relationship('WorkLog', back_populates='contact') location: Mapped[Optional['Room']] = relationship('Room', back_populates='users') inventory: Mapped[List['Inventory']] = relationship('Inventory', back_populates='owner') image: Mapped[Optional['Image']] = relationship('Image', back_populates='user', passive_deletes=True) ui_eagerload = tuple() ui_order_cols = ('first_name', 'last_name',) @property def identifier(self) -> str: return f"{self.first_name or ''} {self.last_name or ''}{', ' + (''.join(word[0].upper() for word in self.title.split())) if self.title else ''}".strip() def __init__(self, first_name: Optional[str] = None, last_name: Optional[str] = None, title: Optional[str] = None,location_id: Optional[int] = None, supervisor_id: Optional[int] = None, staff: Optional[bool] = False, active: Optional[bool] = False): self.first_name = first_name self.last_name = last_name self.title = title self.location_id = location_id self.supervisor_id = supervisor_id self.staff = staff self.active = active def __repr__(self): return f"" def serialize(self): return { 'id': self.id, 'first_name': self.first_name, 'last_name': self.last_name, 'title': self.title, 'location_id': self.location_id, 'supervisor_id': self.supervisor_id, 'staff': self.staff, 'active': self.active } @classmethod def from_dict(cls, data: dict[str, Any]) -> "User": return cls( staff=bool(data.get("staff", False)), active=bool(data.get("active", False)), last_name=data.get("last_name"), first_name=data.get("first_name"), title=data.get("title"), location_id=data.get("location_id"), supervisor_id=data.get("supervisor_id") )