One_Piece_Bounty_Bot / src /model /DevilFruitTrade.py
github-actions[bot]
Automated sync from GitHub
71e71e8
Raw
History Blame Contribute Delete
6.09 kB
import datetime
from peewee import *
from src.model.BaseModel import BaseModel
from src.model.DevilFruit import DevilFruit
from src.model.GroupChat import GroupChat
from src.model.User import User
from src.model.enums.devil_fruit.DevilFruitCategory import DevilFruitCategory
from src.model.enums.devil_fruit.DevilFruitSource import DevilFruitSource
from src.model.enums.devil_fruit.DevilFruitTradeStatus import DevilFruitTradeStatus
class DevilFruitTrade(BaseModel):
"""
Devil Fruit Trade class
"""
devil_fruit: DevilFruit | ForeignKeyField = ForeignKeyField(
DevilFruit,
null=True,
backref="devil_fruit_trades",
on_delete="RESTRICT",
on_update="CASCADE",
)
giver: User | ForeignKeyField = ForeignKeyField(
User,
null=True,
backref="devil_fruit_trade_givers",
on_delete="RESTRICT",
on_update="CASCADE",
)
receiver: User | ForeignKeyField = ForeignKeyField(
User,
null=True,
backref="devil_fruit_trade_receivers",
on_delete="RESTRICT",
on_update="CASCADE",
)
source: DevilFruitSource | SmallIntegerField = SmallIntegerField()
price: int | BigIntegerField = BigIntegerField(null=True)
tax_percentage: float | FloatField = FloatField(null=True)
reason: str | CharField = CharField(max_length=100, null=True)
date_sold: datetime.datetime | DateTimeField = DateTimeField(null=True)
status: DevilFruitTradeStatus | SmallIntegerField = SmallIntegerField(
default=DevilFruitTradeStatus.PENDING
)
group_chat: GroupChat | ForeignKeyField = ForeignKeyField(
GroupChat,
null=True,
backref="devil_fruit_trade_group_chats",
on_delete="RESTRICT",
on_update="CASCADE",
)
message_id: int = IntegerField(null=True)
class Meta:
db_table = "devil_fruit_trade"
@staticmethod
def get_average_price(devil_fruit_category: DevilFruitCategory) -> int:
"""
Get the average price of the sold fruits in a category
:return: The average price
"""
avg = (
DevilFruitTrade.select(fn.AVG(DevilFruitTrade.price))
.join(DevilFruit)
.where(
(DevilFruit.category == devil_fruit_category)
& (DevilFruitTrade.price.is_null(False))
& (DevilFruitTrade.status == DevilFruitTradeStatus.COMPLETED)
& (DevilFruitTrade.price > 0)
)
.scalar()
)
return int(avg) if avg is not None else None
def get_source(self) -> DevilFruitSource:
"""
Get the source of the trade
:return: The source
"""
return DevilFruitSource(self.source)
def get_status(self) -> DevilFruitTradeStatus:
"""
Get the status of the trade
:return: The status
"""
return DevilFruitTradeStatus(self.status)
@staticmethod
def delete_pending_trades(devil_fruit: DevilFruit):
"""
Delete pending trades of a devil fruit
:param devil_fruit: The devil fruit
:return: None
"""
DevilFruitTrade.delete().where(
(DevilFruitTrade.devil_fruit == devil_fruit)
& (DevilFruitTrade.status == DevilFruitTradeStatus.PENDING)
).execute()
@staticmethod
def delete_pending_trades_in_shop(devil_fruit: DevilFruit):
"""
Delete pending trades of a devil fruit in the shop
:param devil_fruit: The devil fruit
:return: None
"""
DevilFruitTrade.delete().where(
(DevilFruitTrade.devil_fruit == devil_fruit)
& (DevilFruitTrade.status == DevilFruitTradeStatus.PENDING)
& (DevilFruitTrade.source == DevilFruitSource.SHOP)
).execute()
@staticmethod
def delete_pending_trades_in_group(
devil_fruit: DevilFruit, group_chat: GroupChat, exclude_id: int
):
"""
Delete pending trades of a devil fruit in a group chat
:param devil_fruit: The devil fruit
:param group_chat: The group chat
:param exclude_id: The id to exclude
:return: None
"""
DevilFruitTrade.delete().where(
(DevilFruitTrade.devil_fruit == devil_fruit)
& (DevilFruitTrade.status == DevilFruitTradeStatus.PENDING)
& (DevilFruitTrade.group_chat == group_chat)
& (DevilFruitTrade.id != exclude_id)
).execute()
@staticmethod
def get_pending_in_shop(devil_fruit: DevilFruit) -> "DevilFruitTrade":
"""
Get a pending trade in the shop
:param devil_fruit: The devil fruit
:return: The trade
"""
return DevilFruitTrade.get_or_none(
DevilFruitTrade.devil_fruit == devil_fruit,
DevilFruitTrade.status == DevilFruitTradeStatus.PENDING,
DevilFruitTrade.source == DevilFruitSource.SHOP,
)
@staticmethod
def get_all_selling_in_shop_or_group(
group_chat: GroupChat = None, user: User = None
) -> list["DevilFruitTrade"]:
"""
Get all trades in the shop
:param group_chat: The group chat
:param user: The user
:return: The trades
"""
return DevilFruitTrade.select().where(
# Only non completed trades
(DevilFruitTrade.devil_fruit.is_null(False))
& (DevilFruitTrade.status == DevilFruitTradeStatus.PENDING)
& (
# Is in shop
(DevilFruitTrade.source == DevilFruitSource.SHOP)
| (
# Is in the given group chat
(DevilFruitTrade.source == DevilFruitSource.USER)
& (DevilFruitTrade.group_chat == group_chat)
# Not reserved to a specific user or reserved to the given user
& ((DevilFruitTrade.receiver.is_null()) | (DevilFruitTrade.receiver == user))
)
)
)
DevilFruitTrade.create_table()