v1.6.0: max_bot fixes — feature keys, flush→commit, test-run, categories, broadcast page, proxy error handling, deploy scripts
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
from datetime import datetime
|
||||
from app.settings_cache import SettingsCache
|
||||
from app.conversation import get_or_create_user, get_template_rendered
|
||||
from app.fsm import BotState, FSM
|
||||
from app.keyboards.inline import build_main_menu_buttons
|
||||
|
||||
_DATE_KEY = "appt_date"
|
||||
_SLOT_KEY = "appt_slot"
|
||||
|
||||
|
||||
async def handle_appointment(bot, user_data: dict, db, max_api):
|
||||
max_user_id = user_data["user_id"]
|
||||
text = user_data.get("text", "").strip()
|
||||
payload = user_data.get("payload", "")
|
||||
state = FSM.get_state(max_user_id)
|
||||
|
||||
if state != BotState.FEATURE_APPOINTMENT:
|
||||
FSM.set_state(max_user_id, BotState.FEATURE_APPOINTMENT)
|
||||
FSM.set_temp(max_user_id, {})
|
||||
await max_api.send_message(
|
||||
max_user_id,
|
||||
"📅 **Запись на визит**\n\nУкажите желаемую дату (ДД.ММ.ГГГГ):"
|
||||
)
|
||||
return
|
||||
|
||||
tmp = FSM.get_temp(max_user_id)
|
||||
|
||||
if _DATE_KEY not in tmp:
|
||||
try:
|
||||
parsed = datetime.strptime(text.strip(), "%d.%m.%Y")
|
||||
tmp[_DATE_KEY] = parsed.strftime("%Y-%m-%d")
|
||||
FSM.set_temp(max_user_id, tmp)
|
||||
|
||||
slots = _generate_slots()
|
||||
msg_lines = [f"📅 **{parsed.strftime('%d.%m.%Y')}**\n\nДоступные слоты:\n"]
|
||||
for i, slot in enumerate(slots, 1):
|
||||
msg_lines.append(f"{i}. {slot}")
|
||||
msg_lines.append("\nВведите номер слота (1-{}):".format(len(slots)))
|
||||
await max_api.send_message(max_user_id, "\n".join(msg_lines), format="markdown")
|
||||
except Exception:
|
||||
await max_api.send_message(max_user_id, "Неверный формат даты. Укажите дату в формате ДД.ММ.ГГГГ")
|
||||
return
|
||||
|
||||
if _SLOT_KEY not in tmp:
|
||||
slots = _generate_slots()
|
||||
try:
|
||||
idx = int(text.strip()) - 1
|
||||
if 0 <= idx < len(slots):
|
||||
tmp[_SLOT_KEY] = slots[idx]
|
||||
FSM.set_temp(max_user_id, tmp)
|
||||
await _confirm_appointment(bot, user_data, db, max_api, tmp)
|
||||
return
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
await max_api.send_message(max_user_id, f"Укажите номер слота (1-{len(slots)}):")
|
||||
return
|
||||
|
||||
await _confirm_appointment(bot, user_data, db, max_api, tmp)
|
||||
|
||||
|
||||
def _generate_slots() -> list:
|
||||
start_h = SettingsCache.get_int("work_hours_start", 9)
|
||||
end_h = SettingsCache.get_int("work_hours_end", 18)
|
||||
slots = []
|
||||
for h in range(start_h, end_h):
|
||||
slots.append(f"{h:02d}:00-{h + 1:02d}:00")
|
||||
return slots
|
||||
|
||||
|
||||
async def _confirm_appointment(bot, user_data, db, max_api, tmp):
|
||||
max_user_id = user_data["user_id"]
|
||||
date_str = tmp.get(_DATE_KEY, "—")
|
||||
slot_str = tmp.get(_SLOT_KEY, "—")
|
||||
user = await get_or_create_user(db, max_user_id)
|
||||
text = await get_template_rendered(db, "appointment_confirm",
|
||||
date=f"{date_str} {slot_str}",
|
||||
engineer="будет назначен")
|
||||
await max_api.send_message(max_user_id, text, format="markdown")
|
||||
|
||||
conv = await _create_appointment_conv(db, user.id, f"{date_str} {slot_str}")
|
||||
from app.integrations import _1c_unf as ic_integration
|
||||
await ic_integration.send_to_1c(db, conv)
|
||||
|
||||
FSM.clear_temp(max_user_id)
|
||||
FSM.transition(max_user_id, "done")
|
||||
buttons = build_main_menu_buttons()
|
||||
menu_text = await get_template_rendered(db, "main_menu")
|
||||
await max_api.send_message_with_keyboard(max_user_id, menu_text, buttons)
|
||||
|
||||
|
||||
async def _create_appointment_conv(db, user_id, details):
|
||||
from app.conversation import create_conversation, add_message
|
||||
from sqlalchemy import select
|
||||
from app.models.models import BotCategory
|
||||
result = await db.execute(
|
||||
select(BotCategory).where(BotCategory.name == "Обслуживание").limit(1)
|
||||
)
|
||||
cat = result.scalar_one_or_none()
|
||||
conv = await create_conversation(db, user_id)
|
||||
conv.inquiry_text = f"Запись на визит: {details}"
|
||||
conv.inquiry_type = cat.id if cat else None
|
||||
conv.priority = "normal"
|
||||
await db.flush()
|
||||
await add_message(db, conv.id, "in", details)
|
||||
return conv
|
||||
Reference in New Issue
Block a user