from typing import Dict, Any UNIVERSIGN_TO_LOCAL: Dict[str, str] = { "draft": "EN_ATTENTE", "ready": "EN_ATTENTE", "started": "EN_COURS", "completed": "SIGNE", "closed": "SIGNE", "refused": "REFUSE", "expired": "EXPIRE", "canceled": "REFUSE", "failed": "ERREUR", } LOCAL_TO_SAGE_STATUS: Dict[str, int] = { "EN_ATTENTE": 0, "EN_COURS": 1, "SIGNE": 2, "REFUSE": 3, "EXPIRE": 4, "ERREUR": 5, } STATUS_ACTIONS: Dict[str, Dict[str, Any]] = { "SIGNE": { "update_sage_status": True, "trigger_workflow": True, "send_notification": True, "archive_document": True, "update_sage_field": "CB_DateSignature", }, "REFUSE": { "update_sage_status": True, "trigger_workflow": False, "send_notification": True, "archive_document": False, "alert_sales": True, }, "EXPIRE": { "update_sage_status": True, "trigger_workflow": False, "send_notification": True, "archive_document": False, "schedule_reminder": True, }, "ERREUR": { "update_sage_status": False, "trigger_workflow": False, "send_notification": False, "log_error": True, "retry_sync": True, }, } ALLOWED_TRANSITIONS: Dict[str, list] = { "EN_ATTENTE": ["EN_COURS", "ERREUR"], "EN_COURS": ["SIGNE", "REFUSE", "EXPIRE", "ERREUR"], "SIGNE": [], "REFUSE": [], "EXPIRE": [], "ERREUR": ["EN_ATTENTE", "EN_COURS"], } STATUS_PRIORITY: Dict[str, int] = { "ERREUR": 0, "EN_ATTENTE": 1, "EN_COURS": 2, "EXPIRE": 3, "REFUSE": 4, "SIGNE": 5, } STATUS_MESSAGES: Dict[str, Dict[str, str]] = { "EN_ATTENTE": { "fr": "Document en attente d'envoi", "en": "Document pending", "icon": "⏳", "color": "gray", }, "EN_COURS": { "fr": "En attente de signature", "en": "Awaiting signature", "icon": "✍️", "color": "blue", }, "SIGNE": { "fr": "Signé avec succès", "en": "Successfully signed", "icon": "✅", "color": "green", }, "REFUSE": { "fr": "Signature refusée", "en": "Signature refused", "icon": "❌", "color": "red", }, "EXPIRE": { "fr": "Délai de signature expiré", "en": "Signature expired", "icon": "⏰", "color": "orange", }, "ERREUR": { "fr": "Erreur technique", "en": "Technical error", "icon": "⚠️", "color": "red", }, } def map_universign_to_local(universign_status: str) -> str: """Convertit un statut Universign en statut local.""" return UNIVERSIGN_TO_LOCAL.get(universign_status.lower(), "ERREUR") def get_sage_status_code(local_status: str) -> int: """Obtient le code numérique pour Sage.""" return LOCAL_TO_SAGE_STATUS.get(local_status, 5) def is_transition_allowed(from_status: str, to_status: str) -> bool: """Vérifie si une transition de statut est valide.""" if from_status == to_status: return True return to_status in ALLOWED_TRANSITIONS.get(from_status, []) def get_status_actions(local_status: str) -> Dict[str, Any]: """Obtient les actions à exécuter pour un statut.""" return STATUS_ACTIONS.get(local_status, {}) def is_final_status(local_status: str) -> bool: """Détermine si le statut est final.""" return local_status in ["SIGNE", "REFUSE", "EXPIRE"] def resolve_status_conflict(status_a: str, status_b: str) -> str: """Résout un conflit entre deux statuts (prend le plus prioritaire).""" priority_a = STATUS_PRIORITY.get(status_a, 0) priority_b = STATUS_PRIORITY.get(status_b, 0) return status_a if priority_a >= priority_b else status_b def get_status_message(local_status: str, lang: str = "fr") -> str: """Obtient le message utilisateur pour un statut.""" status_info = STATUS_MESSAGES.get(local_status, {}) icon = status_info.get("icon", "") message = status_info.get(lang, local_status) return f"{icon} {message}"