161 lines
5.5 KiB
Python
161 lines
5.5 KiB
Python
from datetime import datetime
|
|
from decimal import Decimal
|
|
from typing import Dict
|
|
|
|
from sqlalchemy import JSON, BigInteger, ForeignKey, Numeric, String
|
|
from sqlalchemy.ext.asyncio import AsyncAttrs
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
|
|
|
__all__ = [
|
|
"Base",
|
|
"Item",
|
|
"Provider",
|
|
"Order",
|
|
"LocationType",
|
|
"Location",
|
|
"ItemBatch",
|
|
"Discount",
|
|
"Customer",
|
|
"Cart",
|
|
"ItemOnShelf",
|
|
]
|
|
|
|
|
|
class Base(AsyncAttrs, DeclarativeBase):
|
|
pass
|
|
|
|
|
|
class Provider(Base):
|
|
__tablename__ = "providers"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str]
|
|
address: Mapped[str]
|
|
phone: Mapped[str]
|
|
vat: Mapped[str]
|
|
|
|
def __repr__(self) -> str:
|
|
return f"<Provider ({self.name}) at {hex(id(self))}>"
|
|
|
|
|
|
class Item(Base):
|
|
__tablename__ = "items"
|
|
sku: Mapped[int] = mapped_column(primary_key=True)
|
|
upc: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
provider: Mapped[int] = mapped_column(ForeignKey("providers.id"))
|
|
name: Mapped[str] = mapped_column(nullable=False)
|
|
package: Mapped[str] = mapped_column(unique=False)
|
|
current: Mapped[bool] = mapped_column(
|
|
comment="True if the item can be still requested to a provider, "
|
|
"False if it has been discontinued"
|
|
)
|
|
# unit_weight: Mapped[int] = mapped_column(
|
|
# comment="Unit weight in grams not including additional packaging"
|
|
# ) To be added as exercise
|
|
volume_unpacked: Mapped[int] = mapped_column(
|
|
comment="Volume of the item unpacked in cubic decimeters"
|
|
)
|
|
volume_packed: Mapped[int] = mapped_column(
|
|
comment="Volume of each unit item when packaged in cubic decimeters"
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"<Item {self.name} at {hex(id(self))}>"
|
|
|
|
|
|
class Order(Base):
|
|
__tablename__ = "orders"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
sku: Mapped[int] = mapped_column(ForeignKey("items.sku"))
|
|
placed: Mapped[datetime]
|
|
qty: Mapped[int] = mapped_column(nullable=False)
|
|
provider: Mapped[int] = mapped_column(ForeignKey("providers.id"))
|
|
|
|
|
|
class LocationType(Base):
|
|
__tablename__ = "locationtypes"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str]
|
|
retail: Mapped[bool]
|
|
|
|
|
|
class Location(Base):
|
|
__tablename__ = "locations"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
loctype: Mapped[int] = mapped_column(ForeignKey("locationtypes.id"))
|
|
name: Mapped[str]
|
|
capacity: Mapped[int]
|
|
|
|
|
|
class ItemBatch(Base):
|
|
__tablename__ = "batches"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
lot: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
order: Mapped[str] = mapped_column(ForeignKey("orders.id"), nullable=True)
|
|
received: Mapped[datetime] = mapped_column(nullable=True)
|
|
unit_cost: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=False)
|
|
price: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=False)
|
|
best_until: Mapped[datetime]
|
|
quantity: Mapped[int]
|
|
sku: Mapped[id] = mapped_column(ForeignKey("items.sku"))
|
|
item: Mapped[Item] = relationship()
|
|
|
|
|
|
class Discount(Base):
|
|
__tablename__ = "discounts"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str] = mapped_column(unique=True, nullable=False)
|
|
definition: Mapped[Dict[str, Dict[str, int]]] = mapped_column(JSON, nullable=True)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"Type: {self.name} at {id(self)}"
|
|
|
|
|
|
class TaskOwner(Base):
|
|
__tablename__ = "taskowners"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str] = mapped_column(unique=True, nullable=False)
|
|
|
|
|
|
class Task(Base):
|
|
__tablename__ = "tasks"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
taskowner: Mapped[int] = mapped_column(ForeignKey("taskowners.id"), nullable=False)
|
|
location: Mapped[int] = mapped_column(ForeignKey("locations.id"), nullable=False)
|
|
sku: Mapped[int] = mapped_column(ForeignKey("items.sku"), nullable=False)
|
|
description: Mapped[str]
|
|
|
|
|
|
class Customer(Base):
|
|
__tablename__ = "customers"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
document: Mapped[str] = mapped_column(nullable=False)
|
|
info: Mapped[Dict[str, str]] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
class Cart(Base):
|
|
__tablename__ = "carts"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
checkout: Mapped[datetime] = mapped_column(nullable=True)
|
|
location: Mapped[int] = mapped_column(ForeignKey("locations.id"), nullable=False)
|
|
customer: Mapped[int] = mapped_column(ForeignKey("customers.id"), nullable=True)
|
|
|
|
|
|
class ItemOnCart(Base):
|
|
__tablename__ = "itemsoncart"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
cart: Mapped[int] = mapped_column(ForeignKey("carts.id"), nullable=False)
|
|
upc: Mapped[int] = mapped_column(nullable=False) # Not FK to avoid sync issues
|
|
quantity: Mapped[int] = mapped_column(nullable=True)
|
|
unitprice: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=True)
|
|
discount: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=True)
|
|
|
|
|
|
class ItemOnShelf(Base):
|
|
__tablename__ = "itemsonshelf"
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
batch: Mapped[int] = mapped_column(ForeignKey("batches.id"), nullable=True)
|
|
discount: Mapped[int] = mapped_column(ForeignKey("discounts.id"), nullable=True)
|
|
quantity: Mapped[int] = mapped_column(nullable=False)
|
|
location: Mapped[int] = mapped_column(ForeignKey("locations.id"), nullable=False)
|
|
batches: Mapped[ItemBatch] = relationship()
|