inventory/inventory/models/inventory.py

132 lines
5.3 KiB
Python

from typing import Any, List, Optional, TYPE_CHECKING
from .image import Image
if TYPE_CHECKING:
from .brands import Brand
from .items import Item
from .work_log import WorkLog
from .rooms import Room
from .image import Image
from sqlalchemy import Boolean, ForeignKey, Identity, Index, Integer, Unicode, DateTime, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
import datetime
from . import db
from .image import ImageAttachable
class Inventory(db.Model, ImageAttachable):
__tablename__ = 'inventory'
__table_args__ = (
Index('Inventory$Barcode', 'barcode'),
)
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)
timestamp: Mapped[datetime.datetime] = mapped_column(DateTime)
condition: Mapped[str] = mapped_column(Unicode(255))
type_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("item.id"), nullable=True, index=True)
name: Mapped[Optional[str]] = mapped_column(Unicode(255))
serial: Mapped[Optional[str]] = mapped_column(Unicode(255))
model: Mapped[Optional[str]] = mapped_column(Unicode(255))
notes: Mapped[Optional[str]] = mapped_column(Unicode(255))
owner_id = mapped_column(Integer, ForeignKey('users.id'), nullable=True, index=True)
brand_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("brand.id"), nullable=True, index=True)
location_id: Mapped[Optional[str]] = mapped_column(ForeignKey("rooms.id"), nullable=True, index=True)
barcode: Mapped[Optional[str]] = mapped_column(Unicode(255))
shared: Mapped[Optional[bool]] = mapped_column(Boolean, server_default=text('((0))'))
image_id: Mapped[Optional[int]] = mapped_column(ForeignKey('images.id', ondelete='SET NULL'), nullable=True, index=True)
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')
image: Mapped[Optional['Image']] = relationship('Image', back_populates='inventory', passive_deletes=True)
def __init__(self, timestamp: datetime.datetime, condition: str, type_id: Optional[int] = None,
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.type_id = type_id
self.name = 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.name:
parts.append(f"name={repr(self.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.identifier)}")
if self.location:
parts.append(f"location={repr(self.location.identifier)}")
return f"<Inventory({', '.join(parts)})>"
@property
def identifier(self) -> str:
if self.name:
return f"Name: {self.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,
'type_id': self.type_id,
'name': self.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"),
type_id=data["type_id"],
name=data.get("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))
)
def attach_image(self, image: Image) -> None:
self.image = image