more inventory management work

This commit is contained in:
2025-04-22 16:44:47 -04:00
parent d8ae45c025
commit 210a033695
11 changed files with 1070 additions and 131 deletions

View File

@ -1,13 +1,15 @@
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("products.id"), nullable=False)
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)
@ -18,15 +20,17 @@ class PhysicalItem(Base):
}
# Relationships
product = relationship("Product")
product = relationship("TCGPlayerProduct")
inventory_item = relationship("InventoryItem", uselist=False, back_populates="physical_item")
transaction_items = relationship("TransactionItem", 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'
}
@ -40,6 +44,7 @@ class SealedBox(PhysicalItem):
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'
@ -49,6 +54,27 @@ class SealedBox(PhysicalItem):
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"
@ -95,6 +121,7 @@ class InventoryItem(Base):
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"
@ -151,6 +178,7 @@ class Transaction(Base):
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)
@ -160,4 +188,61 @@ class Transaction(Base):
deleted_at = Column(DateTime(timezone=True), nullable=True)
# Relationships
transaction_items = relationship("TransactionItem", back_populates="transaction")
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")

View File

@ -1,5 +1,6 @@
from sqlalchemy import Column, Integer, String, Float, DateTime
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from app.db.database import Base
class TCGPlayerProduct(Base):
@ -30,4 +31,8 @@ class TCGPlayerProduct(Base):
ext_flavor_text = Column(String)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
most_recent_tcgplayer_price = relationship("MostRecentTCGPlayerPrice", back_populates="product")
marketplace_listings = relationship("MarketplaceListing", back_populates="product")
inventory_items = relationship("InventoryItem", back_populates="product")