"""Обработчик главного меню.""" import asyncio from maxapi.context import BaseContext from maxapi.dispatcher import Router from maxapi.filters import F from maxapi.types.updates.message_callback import MessageCallback from bot.flow_config import PAYLOADS, TRANSITIONS from bot.keyboards import main_menu_kb from bot.nav_helper import nav_finish, nav_prepare from bot.texts import MenuTexts from database.queries.organizations import get_organization from external.intradesk_api import count_client_open_tasks, get_client_last_comment router = Router(router_id="menu") async def build_main_menu_text(bot_user: dict) -> str: """Формирует текст главного меню — данные берутся из Intradesk API.""" org_id = bot_user.get("org_id") org_name: str | None = None intradesk_id: int | None = None if org_id: org = await get_organization(org_id) org_name = org["name"] if org else None intradesk_id = org.get("intradesk_id") if org else None lines: list[str] = [] lines.append(MenuTexts.ORG_HEADER.format(org_name=org_name) if org_name else MenuTexts.NO_ORG_HEADER) lines.append(MenuTexts.SEPARATOR) if intradesk_id: # Счётчик активных и последний комментарий — параллельно active, last_comment = await asyncio.gather( count_client_open_tasks(intradesk_id), get_client_last_comment(intradesk_id), ) if active == 0: lines += [ MenuTexts.NO_TICKETS, "", MenuTexts.NO_TICKETS_HINT, ] else: lines.append(MenuTexts.ACTIVE_COUNT.format(active=active)) if last_comment and last_comment.get("text"): ctext = last_comment["text"] if len(ctext) > 120: ctext = ctext[:120] + "…" raw_date = last_comment.get("date") or "" date_part = raw_date[:10] time_part = raw_date[11:16] if len(raw_date) >= 16 else "" if len(date_part) == 10: y, m, d = date_part.split("-") short_date = f"{d}.{m}" + (f" {time_part}" if time_part else "") else: short_date = raw_date author = (last_comment.get("author") or "").strip() task_num = last_comment.get("task_number") num_str = f" (заявка #{task_num})" if task_num else "" lines += [ "", MenuTexts.LAST_COMMENT.format(num_str=num_str), f"«{ctext}»", MenuTexts.LAST_COMMENT_AUTHOR.format(author=author, short_date=short_date), ] else: lines += ["", MenuTexts.NO_NEW_COMMENTS] else: lines.append(MenuTexts.NO_ORG_DATA) lines += ["", MenuTexts.SEPARATOR, MenuTexts.CHOOSE_ACTION] return "\n".join(lines) @router.message_callback(F.callback.payload == PAYLOADS.MAIN_MENU) async def cb_main_menu( event: MessageCallback, context: BaseContext, bot_user: dict ) -> None: from bot.handlers.create_ticket import cleanup_ticket_flow await cleanup_ticket_flow(event.bot, context) await context.set_state(TRANSITIONS["nav:menu"]) await event.answer(notification="") chat_id = event.message.recipient.chat_id if event.message else None # Показываем «⏳» — edit-in-place если это последнее навигационное сообщение mid = await nav_prepare( event, context, loading_text=MenuTexts.LOADING, chat_id=chat_id, user_id=bot_user["max_user_id"], ) text = await build_main_menu_text(bot_user) await nav_finish( event.bot, context, mid=mid, chat_id=chat_id, user_id=bot_user["max_user_id"], text=text, attachments=[main_menu_kb()], )