ai_giga_tcg/app/models/inventory_management.py

248 lines
10 KiB
Python

from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from app.db.database import Base
from sqlalchemy import event
from sqlalchemy.orm import Session
class PhysicalItem(Base):
__tablename__ = "physical_items"
id = Column(Integer, primary_key=True)
item_type = Column(String)
product_id = Column(Integer, ForeignKey("tcgplayer_products.id"), nullable=False)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
__mapper_args__ = {
'polymorphic_on': item_type,
'polymorphic_identity': 'physical_item'
}
# Relationships
product = relationship("TCGPlayerProduct")
inventory_item = relationship("InventoryItem", uselist=False, back_populates="physical_item")
transaction_item = relationship("TransactionItem", back_populates="physical_item")
class SealedCase(PhysicalItem):
__tablename__ = "sealed_cases"
id = Column(Integer, ForeignKey('physical_items.id'), primary_key=True)
expected_value = Column(Float)
num_boxes = Column(Integer)
__mapper_args__ = {
'polymorphic_identity': 'sealed_case'
}
# Relationships
boxes = relationship("SealedBox", back_populates="case", foreign_keys="[SealedBox.case_id]")
open_event = relationship("OpenEvent", uselist=False, back_populates="sealed_case")
class SealedBox(PhysicalItem):
__tablename__ = "sealed_boxes"
id = Column(Integer, ForeignKey('physical_items.id'), primary_key=True)
case_id = Column(Integer, ForeignKey("sealed_cases.id"), nullable=True)
expected_value = Column(Float)
__mapper_args__ = {
'polymorphic_identity': 'sealed_box'
}
# Relationships
case = relationship("SealedCase", back_populates="boxes", foreign_keys=[case_id])
open_event = relationship("OpenEvent", uselist=False, back_populates="sealed_box")
# event listeners
@event.listens_for(SealedCase, 'before_insert')
def set_expected_value(mapper, connection, target):
session = Session.object_session(target)
if session:
expected_value = session.query(SealedExpectedValue).filter(SealedExpectedValue.product_id == target.product_id).filter(SealedExpectedValue.deleted_at == None).order_by(SealedExpectedValue.created_at.desc()).first()
if expected_value:
target.expected_value = expected_value.expected_value
else:
raise ValueError("No expected value found for this product")
@event.listens_for(SealedBox, 'before_insert')
def set_expected_value(mapper, connection, target):
session = Session.object_session(target)
if session:
expected_value = session.query(SealedExpectedValue).filter(SealedExpectedValue.product_id == target.product_id).filter(SealedExpectedValue.deleted_at == None).order_by(SealedExpectedValue.created_at.desc()).first()
if expected_value:
target.expected_value = expected_value.expected_value
else:
raise ValueError("No expected value found for this product")
class OpenBox(PhysicalItem):
__tablename__ = "open_boxes"
id = Column(Integer, ForeignKey('physical_items.id'), primary_key=True)
open_event_id = Column(Integer, ForeignKey("open_events.id"))
sealed_box_id = Column(Integer, ForeignKey("sealed_boxes.id"))
__mapper_args__ = {
'polymorphic_identity': 'open_box'
}
# Relationships
open_event = relationship("OpenEvent", back_populates="resulting_boxes")
sealed_box = relationship("SealedBox", foreign_keys=[sealed_box_id])
cards = relationship("OpenCard", back_populates="box", foreign_keys="[OpenCard.box_id]")
class OpenCard(PhysicalItem):
__tablename__ = "open_cards"
id = Column(Integer, ForeignKey('physical_items.id'), primary_key=True)
open_event_id = Column(Integer, ForeignKey("open_events.id"))
box_id = Column(Integer, ForeignKey("open_boxes.id"), nullable=True)
__mapper_args__ = {
'polymorphic_identity': 'open_card'
}
# Relationships
open_event = relationship("OpenEvent", back_populates="resulting_cards")
box = relationship("OpenBox", back_populates="cards", foreign_keys=[box_id])
class InventoryItem(Base):
__tablename__ = "inventory_items"
id = Column(Integer, primary_key=True, index=True)
physical_item_id = Column(Integer, ForeignKey("physical_items.id"), unique=True)
cost_basis = Column(Float) # Current cost basis for this item
parent_id = Column(Integer, ForeignKey("inventory_items.id"), nullable=True) # For tracking hierarchy
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
physical_item = relationship("PhysicalItem", back_populates="inventory_item")
parent = relationship("InventoryItem", remote_side=[id], back_populates="children")
children = relationship("InventoryItem", back_populates="parent", overlaps="parent")
marketplace_listing = relationship("MarketplaceListing", back_populates="inventory_item")
class TransactionItem(Base):
__tablename__ = "transaction_items"
id = Column(Integer, primary_key=True, index=True)
transaction_id = Column(Integer, ForeignKey("transactions.id"))
physical_item_id = Column(Integer, ForeignKey("physical_items.id"))
unit_price = Column(Float, nullable=False)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
transaction = relationship("Transaction", back_populates="transaction_items")
physical_item = relationship("PhysicalItem", back_populates="transaction_items")
class OpenEvent(Base):
__tablename__ = "open_events"
id = Column(Integer, primary_key=True, index=True)
sealed_case_id = Column(Integer, ForeignKey("sealed_cases.id"), nullable=True)
sealed_box_id = Column(Integer, ForeignKey("sealed_boxes.id"), nullable=True)
open_date = Column(DateTime(timezone=True))
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
sealed_case = relationship("SealedCase", back_populates="open_event")
sealed_box = relationship("SealedBox", back_populates="open_event")
resulting_boxes = relationship("OpenBox", back_populates="open_event")
resulting_cards = relationship("OpenCard", back_populates="open_event")
class Vendor(Base):
__tablename__ = "vendors"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
class Customer(Base):
__tablename__ = "customers"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
class Transaction(Base):
__tablename__ = "transactions"
id = Column(Integer, primary_key=True, index=True)
vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=True)
customer_id = Column(Integer, ForeignKey("customers.id"), nullable=True)
marketplace_id = Column(Integer, ForeignKey("marketplaces.id"), nullable=True)
transaction_type = Column(String) # 'purchase' or 'sale'
transaction_date = Column(DateTime(timezone=True))
transaction_total_amount = Column(Float)
transaction_notes = Column(String)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
transaction_items = relationship("TransactionItem", back_populates="transaction")
class SealedExpectedValue(Base):
__tablename__ = "sealed_expected_values"
id = Column(Integer, primary_key=True, index=True)
product_id = Column(Integer, ForeignKey("tcgplayer_products.id"), nullable=True)
expected_value = Column(Float)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
class MostRecentTCGPlayerPrice(Base):
__tablename__ = "most_recent_tcgplayer_price"
__table_args__ = {'extend_existing': True, 'autoload_with': None, 'info': {'is_view': True}}
id = Column(Integer, primary_key=True, index=True)
product_id = Column(Integer, ForeignKey("tcgplayer_products.id"))
date = Column(DateTime)
low_price = Column(Float)
mid_price = Column(Float)
high_price = Column(Float)
market_price = Column(Float)
direct_low_price = Column(Float)
sub_type_name = Column(String)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
# Relationships
product = relationship("TCGPlayerProduct", back_populates="most_recent_tcgplayer_price")
class Marketplace(Base):
__tablename__ = "marketplaces"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
listings = relationship("MarketplaceListing", back_populates="marketplace")
class MarketplaceListing(Base):
__tablename__ = "marketplace_listings"
id = Column(Integer, primary_key=True, index=True)
inventory_item_id = Column(Integer, ForeignKey("inventory_items.id"), nullable=False)
marketplace_id = Column(Integer, ForeignKey("marketplaces.id"), nullable=False)
product_id = Column(Integer, ForeignKey("tcgplayer_products.id"), nullable=False)
listing_date = Column(DateTime(timezone=True))
delisting_date = Column(DateTime(timezone=True), nullable=True)
listed_price = Column(Float)
created_at = Column(DateTime(timezone=True))
updated_at = Column(DateTime(timezone=True))
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
inventory_item = relationship("InventoryItem", back_populates="marketplace_listings")
marketplace = relationship("Marketplace", back_populates="listings")
product = relationship("TCGPlayerProduct", back_populates="marketplace_listings")