from datetime import datetime, timedelta from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram.ext import ContextTypes from asgiref.sync import sync_to_async from hotels.models import Reservation, Hotel from users.models import User from bot.utils.pdf_report import generate_pdf_report from bot.utils.database import get_hotels_for_user, get_hotel_by_name async def statistics(update: Update, context: ContextTypes.DEFAULT_TYPE): """Вывод списка отелей для статистики.""" query = update.callback_query user_id = query.from_user.id await query.answer() # Получаем пользователя user = await sync_to_async(User.objects.filter(chat_id=user_id).first)() if not user: await query.edit_message_text("Вы не зарегистрированы в системе.") return # Получаем отели, связанные с пользователем user_hotels = await get_hotels_for_user(user) if not user_hotels: await query.edit_message_text("У вас нет доступных отелей для статистики.") return # Формируем кнопки для выбора отеля keyboard = [ [InlineKeyboardButton(hotel.hotel.name, callback_data=f"stats_hotel_{hotel.hotel.id}")] for hotel in user_hotels ] keyboard.append([InlineKeyboardButton("🏠 Главная", callback_data="main_menu")]) reply_markup = InlineKeyboardMarkup(keyboard) await query.edit_message_text("Выберите отель:", reply_markup=reply_markup) async def stats_select_period(update: Update, context: ContextTypes.DEFAULT_TYPE): """Выбор периода времени для статистики.""" query = update.callback_query await query.answer() hotel_id = int(query.data.split("_")[2]) context.user_data["selected_hotel"] = hotel_id keyboard = [ [InlineKeyboardButton("Неделя", callback_data="stats_period_week")], [InlineKeyboardButton("Месяц", callback_data="stats_period_month")], [InlineKeyboardButton("Все время", callback_data="stats_period_all")], [InlineKeyboardButton("🏠 Главная", callback_data="main_menu")], [InlineKeyboardButton("🔙 Назад", callback_data="statistics")], ] reply_markup = InlineKeyboardMarkup(keyboard) await query.edit_message_text("Выберите период времени:", reply_markup=reply_markup) async def generate_statistics(update: Update, context: ContextTypes.DEFAULT_TYPE): """Генерация и отправка статистики.""" query = update.callback_query await query.answer() hotel_id = context.user_data.get("selected_hotel") if not hotel_id: await query.edit_message_text("Ошибка: ID отеля не найден.") return period = query.data.split("_")[2] now = datetime.now() if period == "week": start_date = now - timedelta(days=7) end_date = now elif period == "month": start_date = now - timedelta(days=30) end_date = now else: start_date = None end_date = None reservations = await sync_to_async(list)( Reservation.objects.filter(hotel_id=hotel_id).prefetch_related('guests') ) if not reservations: await query.edit_message_text("Нет данных для статистики за выбранный период.") return hotel = await sync_to_async(Hotel.objects.get)(id=hotel_id) file_path = generate_pdf_report(hotel.name, reservations, start_date, end_date) with open(file_path, "rb") as file: await query.message.reply_document(document=file, filename=f"{hotel.name}_report.pdf") async def stats_back(update: Update, context): """Возврат к выбору отеля.""" query = update.callback_query await query.answer() # Получаем отели, связанные с пользователем user_id = query.from_user.id user = await sync_to_async(User.objects.filter(chat_id=user_id).first)() if not user: await query.edit_message_text("Ошибка: Пользователь не найден.") return hotels = await get_hotels_for_user(user) if not hotels: await query.edit_message_text("У вас нет доступных отелей.") return # Формируем кнопки для выбора отеля keyboard = [ [InlineKeyboardButton(hotel.name, callback_data=f"stats_hotel_{hotel.id}")] for hotel in hotels ] keyboard.append([InlineKeyboardButton("🏠 Главная", callback_data="main_menu")]) reply_markup = InlineKeyboardMarkup(keyboard) await query.edit_message_text("Выберите отель:", reply_markup=reply_markup)