94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
import logging
|
|
from datetime import datetime
|
|
from telegram import Update
|
|
from telegram.ext import ContextTypes
|
|
from models.session import set_state, get_data, clear_data, MENU
|
|
from handlers import get_menu_keyboard, MENU_TEXT
|
|
from handlers.chantier import nom_depuis_dossier
|
|
from services.nextcloud import upload_photo, create_deck_card
|
|
from services.telegram import notify_sav as send_notification
|
|
from services.faq_service import faq_service
|
|
from services.tickets import creer_ticket
|
|
from utils.produit_detector import detecter_produit
|
|
from config import DECK_BOARD_ID, DECK_COL_SAV
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
async def handle_sav(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
msg = update.message
|
|
text = (msg.caption or msg.text or "").strip()
|
|
user_id = msg.from_user.id
|
|
chantier_folder = get_data(user_id, "chantier_folder")
|
|
|
|
# Résoudre le chantier et la description
|
|
if chantier_folder:
|
|
chantier = nom_depuis_dossier(chantier_folder)
|
|
description = text
|
|
else:
|
|
if not text or "/" not in text:
|
|
await msg.reply_text(
|
|
"❌ Format requis : `NOM_Ville / Description`",
|
|
parse_mode="Markdown",
|
|
)
|
|
return
|
|
chantier, _, description = text.partition("/")
|
|
chantier = chantier.strip()
|
|
description = description.strip()
|
|
|
|
if not description:
|
|
await msg.reply_text("❌ Description manquante.", parse_mode="Markdown")
|
|
return
|
|
|
|
ouvrier = msg.from_user.full_name
|
|
now = datetime.now()
|
|
|
|
photo_bytes: bytes | None = None
|
|
if msg.photo:
|
|
try:
|
|
tg_file = await context.bot.get_file(msg.photo[-1].file_id)
|
|
photo_bytes = bytes(await tg_file.download_as_bytearray())
|
|
ts = now.strftime("%y%m%d_%H%M%S")
|
|
remote_path = f"SAV_Urgent/{now.strftime('%Y-%m-%d')}_{chantier}/photo_{ts}.jpg"
|
|
await upload_photo(photo_bytes, remote_path)
|
|
except Exception as exc:
|
|
log.error("SAV photo upload : %s", exc)
|
|
|
|
# Créer ticket SQLite
|
|
produit = detecter_produit(description)
|
|
ticket_id = creer_ticket(
|
|
user_id=msg.from_user.id,
|
|
username=msg.from_user.full_name,
|
|
chat_id=msg.chat_id,
|
|
chantier=chantier,
|
|
description=description,
|
|
produit=produit,
|
|
)
|
|
|
|
try:
|
|
await send_notification(context.bot, ouvrier, chantier, description, photo_bytes)
|
|
except Exception as exc:
|
|
log.error("notify_sav : %s", exc)
|
|
|
|
if DECK_BOARD_ID and DECK_COL_SAV:
|
|
await create_deck_card(
|
|
DECK_BOARD_ID,
|
|
DECK_COL_SAV,
|
|
f"SAV #{ticket_id} — {chantier}",
|
|
f"Ouvrier : {ouvrier}\n{description}",
|
|
)
|
|
|
|
clear_data(user_id)
|
|
set_state(user_id, MENU)
|
|
await msg.reply_text(
|
|
f"✅ SAV enregistré — ticket `#{ticket_id}`",
|
|
parse_mode="Markdown",
|
|
)
|
|
await msg.reply_text(MENU_TEXT, reply_markup=get_menu_keyboard())
|
|
|
|
# FAQ — pistes de diagnostic si base disponible
|
|
if faq_service.disponible:
|
|
solution = await faq_service.repondre(description)
|
|
if solution:
|
|
await msg.reply_text(f"💡 Pistes de diagnostic :\n\n{solution}")
|