init commit
This commit is contained in:
140
lottery/bot/handlers.py
Normal file
140
lottery/bot/handlers.py
Normal file
@@ -0,0 +1,140 @@
|
||||
# bot/handlers.py
|
||||
import re
|
||||
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes
|
||||
from asgiref.sync import sync_to_async
|
||||
from webapp.models import BindingRequest, Client, Invoice
|
||||
from draw.models import Lottery, DrawResult, LotteryParticipant
|
||||
from bot.state import BINDING_PENDING
|
||||
|
||||
@sync_to_async
|
||||
def get_client_by_telegram_id(telegram_id: int):
|
||||
try:
|
||||
return Client.objects.get(telegram_id=str(telegram_id))
|
||||
except Client.DoesNotExist:
|
||||
return None
|
||||
|
||||
@sync_to_async
|
||||
def get_invoices_for_client(client):
|
||||
return list(Invoice.objects.filter(client_club_card_number=client.club_card_number))
|
||||
|
||||
@sync_to_async
|
||||
def get_draws_for_client(client):
|
||||
return list(
|
||||
DrawResult.objects.filter(participant__invoice__client_club_card_number=client.club_card_number)
|
||||
.select_related('lottery', 'prize', 'participant__invoice')
|
||||
)
|
||||
|
||||
@sync_to_async
|
||||
def create_binding_request(telegram_chat_id, client_card):
|
||||
return BindingRequest.objects.create(
|
||||
telegram_chat_id=str(telegram_chat_id),
|
||||
client_card=client_card
|
||||
)
|
||||
|
||||
async def whoami(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if not update.message:
|
||||
return
|
||||
chat_id = update.message.chat_id
|
||||
client = await get_client_by_telegram_id(chat_id)
|
||||
if not client:
|
||||
await update.message.reply_text(
|
||||
"❌ Пользователь не найден. Возможно, Вы ещё не привязали свою клубную карту."
|
||||
)
|
||||
return
|
||||
|
||||
invoices = await get_invoices_for_client(client)
|
||||
draws = await get_draws_for_client(client)
|
||||
|
||||
message_text = f"👤 *Профиль клиента:*\n" \
|
||||
f"• *Имя:* {client.name}\n" \
|
||||
f"• *Клубная карта:* {client.club_card_number}\n\n"
|
||||
|
||||
message_text += "💳 *Счета:*\n"
|
||||
if invoices:
|
||||
show_all = len(invoices) > 5
|
||||
displayed_invoices = invoices[:5] if show_all else invoices
|
||||
for inv in displayed_invoices:
|
||||
invoice_str = str(inv).split('/')[0].strip()
|
||||
message_text += f" • {invoice_str} (*{inv.sum}*)\n"
|
||||
else:
|
||||
message_text += " _Нет счетов_\n"
|
||||
|
||||
message_text += "\n🎉 *Розыгрыши и выигранные призы:*\n"
|
||||
if draws:
|
||||
for draw in draws:
|
||||
lottery_name = draw.lottery.name if draw.lottery else "неизвестно"
|
||||
invoice_info = (draw.participant.invoice
|
||||
if draw.participant and hasattr(draw.participant, 'invoice')
|
||||
else "неизвестно")
|
||||
prize_info = (draw.prize.reward
|
||||
if draw.prize and hasattr(draw.prize, 'reward')
|
||||
else "неизвестно")
|
||||
message_text += f" • Лотерея: *{lottery_name}*\n Счет: _{invoice_info}_\n Выигрыш: *{prize_info}*\n\n"
|
||||
else:
|
||||
message_text += " _Нет результатов розыгрышей_\n"
|
||||
|
||||
reply_markup = None
|
||||
if invoices and len(invoices) > 5:
|
||||
reply_markup = InlineKeyboardMarkup([
|
||||
[InlineKeyboardButton("Показать все счета", callback_data="show_all_invoices")]
|
||||
])
|
||||
|
||||
await update.message.reply_text(message_text, parse_mode="Markdown", reply_markup=reply_markup)
|
||||
|
||||
async def handle_client_card(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""
|
||||
Обработчик команды /bind.
|
||||
После ввода команды бот запрашивает ввод номера КК и ожидает сообщение с кодом.
|
||||
Здесь мы просто добавляем ID пользователя в pending.
|
||||
"""
|
||||
if not update.message:
|
||||
return
|
||||
telegram_chat_id = update.message.chat_id
|
||||
# Если пользователь уже привязан, сообщаем об этом.
|
||||
client = await get_client_by_telegram_id(telegram_chat_id)
|
||||
if client:
|
||||
await update.message.reply_text("✅ Вы уже привязаны!")
|
||||
return
|
||||
|
||||
# Добавляем пользователя в список pending и просим ввести номер КК.
|
||||
BINDING_PENDING.add(telegram_chat_id)
|
||||
await update.message.reply_text("Введите номер вашей клубной карты (КК):")
|
||||
|
||||
async def process_binding_input(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""
|
||||
Обрабатывает ввод номера КК от пользователя, который находится в состоянии ожидания.
|
||||
"""
|
||||
if not update.message or not update.message.text:
|
||||
return
|
||||
client_card = update.message.text.strip()
|
||||
telegram_chat_id = update.message.chat_id
|
||||
|
||||
if not re.fullmatch(r'\d{3,}', client_card):
|
||||
await update.message.reply_text("❌ Неверный формат клиентской карты. Пожалуйста, введите корректный код (минимум 3 цифры).")
|
||||
return
|
||||
|
||||
await create_binding_request(telegram_chat_id, client_card)
|
||||
if telegram_chat_id in BINDING_PENDING:
|
||||
BINDING_PENDING.remove(telegram_chat_id)
|
||||
await update.message.reply_text("✅ Заявка отправлена. После подтверждения вы сможете участвовать в чате.")
|
||||
|
||||
async def show_all_invoices_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
chat_id = query.message.chat_id
|
||||
client = await get_client_by_telegram_id(chat_id)
|
||||
if not client:
|
||||
await query.edit_message_text("❌ Пользователь не найден. Возможно, Вы ещё не привязали свою клубную карту.")
|
||||
return
|
||||
|
||||
invoices = await get_invoices_for_client(client)
|
||||
message_text = "💳 *Все счета:*\n"
|
||||
if invoices:
|
||||
for inv in invoices:
|
||||
invoice_str = str(inv).split('/')[0].strip()
|
||||
message_text += f" • {invoice_str} (*{inv.sum}*)\n"
|
||||
else:
|
||||
message_text += " _Нет счетов_\n"
|
||||
|
||||
await query.edit_message_text(message_text, parse_mode="Markdown")
|
||||
Reference in New Issue
Block a user