from typing import Any, List, Optional, TYPE_CHECKING if TYPE_CHECKING: from .brands import Brand from .items import Item from .work_log import WorkLog from .rooms import Room from sqlalchemy import Boolean, ForeignKey, Identity, Index, Integer, Unicode, DateTime, text from sqlalchemy.orm import Mapped, mapped_column, relationship import datetime from . import db class Inventory(db.Model): __tablename__ = 'Inventory' __table_args__ = ( Index('Inventory$Bar Code', 'Bar Code'), ) id: Mapped[int] = mapped_column("ID", Integer, Identity(start=1, increment=1), primary_key=True) timestamp: Mapped[datetime.datetime] = mapped_column('Date Entered', DateTime) condition: Mapped[str] = mapped_column('Working Condition', Unicode(255)) needed: Mapped[str] = mapped_column("Needed", Unicode(255)) type_id: Mapped[Optional[int]] = mapped_column('Item Type', Integer, ForeignKey("Items.ID"), nullable=True) inventory_name: Mapped[Optional[str]] = mapped_column('Inventory #', Unicode(255)) serial: Mapped[Optional[str]] = mapped_column('Serial #', Unicode(255)) model: Mapped[Optional[str]] = mapped_column('Model #', Unicode(255)) notes: Mapped[Optional[str]] = mapped_column('Notes', Unicode(255)) owner_id = mapped_column('Owner', Integer, ForeignKey('Users.ID')) brand_id: Mapped[Optional[int]] = mapped_column("Brand", Integer, ForeignKey("Brands.ID")) # Photo: Mapped[Optional[str]] = mapped_column(String(8000)) Will be replacing with something that actually works. location_id: Mapped[Optional[str]] = mapped_column(ForeignKey("Rooms.ID")) barcode: Mapped[Optional[str]] = mapped_column('Bar Code', Unicode(255)) shared: Mapped[Optional[bool]] = mapped_column(Boolean, server_default=text('((0))')) location: Mapped[Optional['Room']] = relationship('Room', back_populates='inventory') owner = relationship('User', back_populates='inventory') brand: Mapped[Optional['Brand']] = relationship('Brand', back_populates='inventory') item: Mapped['Item'] = relationship('Item', back_populates='inventory') work_logs: Mapped[List['WorkLog']] = relationship('WorkLog', back_populates='work_item') def __init__(self, timestamp: datetime.datetime, condition: str, needed: str, type_id: Optional[int] = None, inventory_name: Optional[str] = None, serial: Optional[str] = None, model: Optional[str] = None, notes: Optional[str] = None, owner_id: Optional[int] = None, brand_id: Optional[int] = None, location_id: Optional[str] = None, barcode: Optional[str] = None, shared: bool = False): self.timestamp = timestamp self.condition = condition self.needed = needed self.type_id = type_id self.inventory_name = inventory_name self.serial = serial self.model = model self.notes = notes self.owner_id = owner_id self.brand_id = brand_id self.location_id = location_id self.barcode = barcode self.shared = shared def __repr__(self): parts = [f"id={self.id}"] if self.inventory_name: parts.append(f"name={repr(self.inventory_name)}") if self.item: parts.append(f"item={repr(self.item.description)}") if self.notes: parts.append(f"notes={repr(self.notes)}") if self.owner: parts.append(f"owner={repr(self.owner.full_name)}") if self.location: parts.append(f"location={repr(self.location.full_name)}") return f"" @property def identifier(self) -> str: if self.inventory_name: return f"Name: {self.inventory_name}" elif self.barcode: return f"Bar: {self.barcode}" elif self.serial: return f"Serial: {self.serial}" else: return f"ID: {self.id}" def serialize(self) -> dict[str, Any]: return { 'id': self.id, 'timestamp': self.timestamp.isoformat() if self.timestamp else None, 'condition': self.condition, 'needed': self.needed, 'type_id': self.type_id, 'inventory_name': self.inventory_name, 'serial': self.serial, 'model': self.model, 'notes': self.notes, 'owner_id': self.owner_id, 'brand_id': self.brand_id, 'location_id': self.location_id, 'barcode': self.barcode, 'shared': self.shared } @classmethod def from_dict(cls, data: dict[str, Any]) -> "Inventory": timestamp_str = data.get("timestamp") return cls( timestamp = datetime.datetime.fromisoformat(str(timestamp_str)) if timestamp_str else datetime.datetime.now(), condition=data.get("condition", "Unverified"), needed=data.get("needed", ""), type_id=data["type_id"], inventory_name=data.get("inventory_name"), serial=data.get("serial"), model=data.get("model"), notes=data.get("notes"), owner_id=data.get("owner_id"), brand_id=data.get("brand_id"), location_id=data.get("location_id"), barcode=data.get("barcode"), shared=bool(data.get("shared", False)) )