84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
from datetime import datetime
|
|
from enum import Enum
|
|
from sqlalchemy import String, Text, DateTime, Integer, Boolean, JSON
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
from typing import TYPE_CHECKING
|
|
|
|
from app.core.database import Base
|
|
|
|
if TYPE_CHECKING:
|
|
from app.models.inventory import UserInventory
|
|
|
|
|
|
class ShopItemType(str, Enum):
|
|
FRAME = "frame"
|
|
TITLE = "title"
|
|
NAME_COLOR = "name_color"
|
|
BACKGROUND = "background"
|
|
CONSUMABLE = "consumable"
|
|
|
|
|
|
class ItemRarity(str, Enum):
|
|
COMMON = "common"
|
|
UNCOMMON = "uncommon"
|
|
RARE = "rare"
|
|
EPIC = "epic"
|
|
LEGENDARY = "legendary"
|
|
|
|
|
|
class ConsumableType(str, Enum):
|
|
SKIP = "skip"
|
|
BOOST = "boost"
|
|
WILD_CARD = "wild_card"
|
|
LUCKY_DICE = "lucky_dice"
|
|
COPYCAT = "copycat"
|
|
UNDO = "undo"
|
|
|
|
|
|
class ShopItem(Base):
|
|
__tablename__ = "shop_items"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
item_type: Mapped[str] = mapped_column(String(30), nullable=False, index=True)
|
|
code: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True)
|
|
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
price: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
rarity: Mapped[str] = mapped_column(String(20), default=ItemRarity.COMMON.value)
|
|
asset_data: Mapped[dict | None] = mapped_column(JSON, nullable=True)
|
|
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
available_from: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
available_until: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
stock_limit: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
stock_remaining: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
|
|
|
|
# Relationships
|
|
inventory_items: Mapped[list["UserInventory"]] = relationship(
|
|
"UserInventory",
|
|
back_populates="item"
|
|
)
|
|
|
|
@property
|
|
def is_available(self) -> bool:
|
|
"""Check if item is currently available for purchase"""
|
|
if not self.is_active:
|
|
return False
|
|
|
|
now = datetime.utcnow()
|
|
|
|
if self.available_from and self.available_from > now:
|
|
return False
|
|
|
|
if self.available_until and self.available_until < now:
|
|
return False
|
|
|
|
if self.stock_remaining is not None and self.stock_remaining <= 0:
|
|
return False
|
|
|
|
return True
|
|
|
|
@property
|
|
def is_consumable(self) -> bool:
|
|
return self.item_type == ShopItemType.CONSUMABLE.value
|