DispelEvilBot/bot/services/shop.py

67 lines
2.4 KiB
Python

"""Сервис магазина."""
from __future__ import annotations
from common.analytics import EventType, record
from common.models import Donat, Title
from common.repositories import shop_repo
async def list_titles() -> list[Title]:
rows = await shop_repo.get_titles_list()
return [Title(id=int(row["i"]), title=row["n"] or "", price=int(row["p"] or 0)) for row in rows]
async def list_donats() -> list[Donat]:
rows = await shop_repo.get_donats_list()
return [Donat(id=int(row["i"]), title=row["n"] or "", price=int(row["p"] or 0)) for row in rows]
async def buy_title(id_user: int, id_title: int) -> bool:
"""Купить звание. Возвращает True при успехе."""
price = await _title_price(id_title)
success = await shop_repo.buy_title(id_user, id_title) == 1
record(
EventType.PURCHASE_TITLE,
user_id=id_user,
payload={"title_id": id_title, "price": price, "success": success},
)
if success:
record(
EventType.MONEY_SPEND,
user_id=id_user,
payload={"amount": price, "reason": "title", "product_id": id_title},
)
return success
async def buy_donat(id_user: int, id_donat: int) -> str | None:
"""Купить донат. Возвращает промокод или None при неуспехе."""
price = await _donat_price(id_donat)
result = await shop_repo.buy_donat(id_user, id_donat)
promo = None if result == "-1" else result
record(
EventType.PURCHASE_DONAT,
user_id=id_user,
payload={"donat_id": id_donat, "price": price, "success": promo is not None},
)
if promo is not None:
record(
EventType.MONEY_SPEND,
user_id=id_user,
payload={"amount": price, "reason": "donat", "product_id": id_donat},
)
return promo
async def _title_price(id_title: int) -> int:
"""Цена звания для события покупки (0, если позиция недоступна)."""
return next((title.price for title in await list_titles() if title.id == id_title), 0)
async def _donat_price(id_donat: int) -> int:
"""Цена доната для события покупки (0, если позиция недоступна)."""
return next((donat.price for donat in await list_donats() if donat.id == id_donat), 0)