108 lines
4 KiB
Python
108 lines
4 KiB
Python
"""Обработчик главного меню."""
|
|
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()],
|
|
)
|