fix: Use win32com.client.CastTo for COM objects and enhance devis listing error handling and client data retrieval.

This commit is contained in:
Fanilo-Nantenaina 2025-11-27 13:29:49 +03:00
parent 7ee3751ee2
commit a1f7026fd9

43
main.py
View file

@ -6,7 +6,7 @@ from datetime import datetime, date
from enum import Enum from enum import Enum
import uvicorn import uvicorn
import logging import logging
import win32com.client
from config import settings, validate_settings from config import settings, validate_settings
from sage_connector import SageConnector from sage_connector import SageConnector
@ -258,18 +258,25 @@ def changer_statut_devis(doc_id: str, req: StatutRequest):
@app.post("/sage/devis/list", dependencies=[Depends(verify_token)]) @app.post("/sage/devis/list", dependencies=[Depends(verify_token)])
def devis_list(limit: int = 100, statut: Optional[int] = None): def devis_list(limit: int = 100, statut: Optional[int] = None):
""" """
Liste tous les devis avec filtres optionnels 📋 Liste tous les devis avec filtres optionnels
Utilise le cache pour performances optimales Utilise le cache pour performances optimales
CORRECTION: Ajout de win32com.client.CastTo et Query parameters
""" """
try: try:
if not sage or not sage.cial:
raise HTTPException(503, "Service Sage indisponible")
with sage._com_context(), sage._lock_com: with sage._com_context(), sage._lock_com:
factory = sage.cial.FactoryDocumentVente factory = sage.cial.FactoryDocumentVente
devis_list = [] devis_list = []
index = 1 index = 1
max_iterations = limit * 3 max_iterations = limit * 3 # Marge de sécurité
erreurs_consecutives = 0 erreurs_consecutives = 0
max_erreurs = 50 max_erreurs = 50
logger.info(f"🔍 Recherche devis (limit={limit}, statut={statut})")
while ( while (
len(devis_list) < limit len(devis_list) < limit
and index < max_iterations and index < max_iterations
@ -278,13 +285,16 @@ def devis_list(limit: int = 100, statut: Optional[int] = None):
try: try:
persist = factory.List(index) persist = factory.List(index)
if persist is None: if persist is None:
logger.debug(f"Fin de liste à l'index {index}")
break break
# ✅ CRITIQUE: Utiliser win32com.client.CastTo
doc = win32com.client.CastTo(persist, "IBODocumentVente3") doc = win32com.client.CastTo(persist, "IBODocumentVente3")
doc.Read() doc.Read()
# Filtrer uniquement devis (type 0) # Filtrer uniquement devis (type 0)
if getattr(doc, "DO_Type", -1) != 0: doc_type = getattr(doc, "DO_Type", -1)
if doc_type != 0:
index += 1 index += 1
continue continue
@ -295,7 +305,7 @@ def devis_list(limit: int = 100, statut: Optional[int] = None):
index += 1 index += 1
continue continue
# Charger client via .Client # Charger client via .Client
client_code = "" client_code = ""
client_intitule = "" client_intitule = ""
@ -307,8 +317,16 @@ def devis_list(limit: int = 100, statut: Optional[int] = None):
client_intitule = getattr( client_intitule = getattr(
client_obj, "CT_Intitule", "" client_obj, "CT_Intitule", ""
).strip() ).strip()
logger.debug(
f"✅ Client: {client_code} - {client_intitule}"
)
except Exception as e: except Exception as e:
logger.debug(f"Erreur chargement client: {e}") logger.debug(f"Erreur chargement client: {e}")
# Fallback sur cache si code disponible
if client_code:
client_cache = sage.lire_client(client_code)
if client_cache:
client_intitule = client_cache.get("intitule", "")
devis_list.append( devis_list.append(
{ {
@ -327,17 +345,26 @@ def devis_list(limit: int = 100, statut: Optional[int] = None):
except Exception as e: except Exception as e:
erreurs_consecutives += 1 erreurs_consecutives += 1
logger.debug(f"Erreur index {index}: {e}") logger.debug(f"⚠️ Erreur index {index}: {e}")
index += 1 index += 1
if erreurs_consecutives >= max_erreurs: if erreurs_consecutives >= max_erreurs:
logger.warning(
f"⚠️ Arrêt après {max_erreurs} erreurs consécutives"
)
break break
logger.info(f"{len(devis_list)} devis retournés") nb_avec_client = sum(1 for d in devis_list if d["client_intitule"])
logger.info(
f"{len(devis_list)} devis retournés ({nb_avec_client} avec client)"
)
return {"success": True, "data": devis_list} return {"success": True, "data": devis_list}
except HTTPException:
raise
except Exception as e: except Exception as e:
logger.error(f"Erreur liste devis: {e}") logger.error(f"Erreur liste devis: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))