67 lines
2.4 KiB
Python
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)
|