127 lines
4.0 KiB
Python

import logging
from datetime import datetime
from telegram import Update
from telegram.ext import ContextTypes
from config import PATRICK_ID
from services.tickets import get_ticket, resoudre_ticket
from services.faq_service import faq_service
from services.nextcloud import upload_text
from utils.produit_detector import detecter_produit
log = logging.getLogger(__name__)
def _parse_args(args: list[str]) -> tuple[str, str, str, int]:
"""
Format : /resolu #2026-047 cause | solution | 45min
Retourne : (ticket_id, cause, solution, duree_min)
"""
texte = " ".join(args)
ticket_id = texte.split()[0].lstrip("#")
reste = texte[len(ticket_id) + 1:].strip()
parties = [p.strip() for p in reste.split("|")]
cause = parties[0] if len(parties) > 0 else ""
solution = parties[1] if len(parties) > 1 else ""
duree_str = parties[2] if len(parties) > 2 else "0"
duree_min = int("".join(c for c in duree_str if c.isdigit()) or "0")
return ticket_id, cause, solution, duree_min
def _generer_fiche_md(ticket: dict, cause: str, solution: str, duree_min: int, produit: str) -> str:
date = datetime.now().strftime("%Y-%m-%d")
return f"""# SAV Résolu — {ticket['id']}
**Chantier :** {ticket['chantier']}
**Date :** {date}
**Technicien :** {ticket['username']}
**Produit :** {produit}
**Durée :** {duree_min} min
## Symptôme
{ticket['description']}
## Cause
{cause}
## Solution
{solution}
"""
async def cmd_resolu(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/resolu #2026-047 relais AC défaillant | remplacer ref 4241 | 45min"""
if update.effective_user.id != PATRICK_ID:
return
if not context.args:
await update.message.reply_text(
"Usage : `/resolu #2026-047 cause | solution | 45min`",
parse_mode="Markdown",
)
return
try:
ticket_id, cause, solution, duree_min = _parse_args(context.args)
except Exception:
await update.message.reply_text("❌ Format invalide.\nUsage : `/resolu #ID cause | solution | durée`", parse_mode="Markdown")
return
ticket = get_ticket(ticket_id)
if not ticket:
await update.message.reply_text(f"❌ Ticket `#{ticket_id}` introuvable.", parse_mode="Markdown")
return
if ticket["status"] == "resolu":
await update.message.reply_text(f"⚠️ Ticket `#{ticket_id}` déjà résolu.", parse_mode="Markdown")
return
# 1. Clôturer dans SQLite
resoudre_ticket(ticket_id, cause, solution, duree_min)
# 2. Détecter le produit
produit = detecter_produit(f"{ticket['description']} {cause} {solution}")
# 3. Générer fiche .md → Nextcloud
date_str = datetime.now().strftime("%Y%m%d")
slug = ticket["chantier"].replace(" ", "_")[:30]
nc_path = f"SAV/{date_str}_{slug}_{ticket_id}.md"
fiche_md = _generer_fiche_md(ticket, cause, solution, duree_min, produit)
try:
await upload_text(fiche_md, nc_path)
except Exception as exc:
log.error("upload fiche SAV : %s", exc)
# 4. Indexer dans la FAQ
faq_service.indexer_fiche_sav(
ticket_id=ticket_id,
produit=produit,
symptome=ticket["description"],
cause=cause,
solution=solution,
chantier=ticket["chantier"],
date=datetime.now().strftime("%Y-%m-%d"),
duree_min=duree_min,
)
# 5. Notifier le technicien original
try:
await context.bot.send_message(
chat_id=ticket["chat_id"],
text=(
f"✅ *SAV #{ticket_id} résolu*\n\n"
f"🏠 {ticket['chantier']}\n"
f"🔧 {produit}\n"
f"💡 *Solution :* {solution}\n"
f"{duree_min} min"
),
parse_mode="Markdown",
)
except Exception as exc:
log.error("notify technicien : %s", exc)
await update.message.reply_text(
f"✅ Ticket `#{ticket_id}` clôturé et indexé dans la FAQ.\n"
f"📁 Fiche : `{nc_path}`",
parse_mode="Markdown",
)