Diagnostic transformation selective error
This commit is contained in:
parent
e6c2ab6670
commit
de0053b98b
1 changed files with 234 additions and 53 deletions
277
main.py
277
main.py
|
|
@ -489,74 +489,255 @@ def lire_document(numero: str, type_doc: int):
|
||||||
|
|
||||||
@app.post("/sage/documents/transform", dependencies=[Depends(verify_token)])
|
@app.post("/sage/documents/transform", dependencies=[Depends(verify_token)])
|
||||||
def transformer_document(
|
def transformer_document(
|
||||||
numero_source: str = Query(..., description="Numéro du document source"),
|
numero: str, type_source: int = Query(...), type_cible: int = Query(...)
|
||||||
type_source: int = Query(..., description="Type document source"),
|
|
||||||
type_cible: int = Query(..., description="Type document cible"),
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
🔧 Transformation de document
|
🔍 DIAGNOSTIC AVANCÉ: Analyse pourquoi une transformation échoue
|
||||||
|
|
||||||
✅ CORRECTION : Utilise les VRAIS types Sage Dataven
|
Vérifie:
|
||||||
|
- Statut du document source
|
||||||
Types valides :
|
- Statuts autorisés
|
||||||
- 0: Devis
|
- Lignes du document
|
||||||
- 10: Bon de commande
|
- Client associé
|
||||||
- 20: Préparation
|
- Champs obligatoires manquants
|
||||||
- 30: Bon de livraison
|
|
||||||
- 40: Bon de retour
|
|
||||||
- 50: Bon d'avoir
|
|
||||||
- 60: Facture
|
|
||||||
|
|
||||||
Transformations autorisées :
|
|
||||||
- Devis (0) → Commande (10)
|
|
||||||
- Commande (10) → Bon livraison (30)
|
|
||||||
- Commande (10) → Facture (60)
|
|
||||||
- Bon livraison (30) → Facture (60)
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
logger.info(
|
if not sage or not sage.cial:
|
||||||
f"🔄 Transformation demandée: {numero_source} "
|
raise HTTPException(503, "Service Sage indisponible")
|
||||||
f"(type {type_source}) → type {type_cible}"
|
|
||||||
|
with sage._com_context(), sage._lock_com:
|
||||||
|
factory = sage.cial.FactoryDocumentVente
|
||||||
|
|
||||||
|
# Lire le document source
|
||||||
|
persist = factory.ReadPiece(type_source, numero)
|
||||||
|
|
||||||
|
if not persist:
|
||||||
|
persist = sage._find_document_in_list(numero, type_source)
|
||||||
|
|
||||||
|
if not persist:
|
||||||
|
raise HTTPException(
|
||||||
|
404, f"Document {numero} (type {type_source}) introuvable"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ✅ Matrice des transformations valides pour VOTRE Sage
|
doc = win32com.client.CastTo(persist, "IBODocumentVente3")
|
||||||
transformations_valides = {
|
doc.Read()
|
||||||
(0, 10), # Devis → Commande
|
|
||||||
(10, 30), # Commande → Bon de livraison
|
diagnostic = {
|
||||||
(10, 60), # Commande → Facture
|
"numero": numero,
|
||||||
(30, 60), # Bon de livraison → Facture
|
"type_source": type_source,
|
||||||
(0, 60), # Devis → Facture (si autorisé)
|
"type_cible": type_cible,
|
||||||
|
"problemes_detectes": [],
|
||||||
|
"avertissements": [],
|
||||||
|
"suggestions": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 1. Vérifier le statut
|
||||||
|
statut_actuel = getattr(doc, "DO_Statut", -1)
|
||||||
|
diagnostic["statut_actuel"] = statut_actuel
|
||||||
|
|
||||||
|
if statut_actuel == 5:
|
||||||
|
diagnostic["problemes_detectes"].append(
|
||||||
|
{
|
||||||
|
"severite": "BLOQUANT",
|
||||||
|
"champ": "DO_Statut",
|
||||||
|
"valeur": 5,
|
||||||
|
"message": "Document déjà transformé (statut=5)",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
elif statut_actuel == 6:
|
||||||
|
diagnostic["problemes_detectes"].append(
|
||||||
|
{
|
||||||
|
"severite": "BLOQUANT",
|
||||||
|
"champ": "DO_Statut",
|
||||||
|
"valeur": 6,
|
||||||
|
"message": "Document annulé (statut=6)",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
elif statut_actuel in [3, 4]:
|
||||||
|
diagnostic["avertissements"].append(
|
||||||
|
{
|
||||||
|
"severite": "ATTENTION",
|
||||||
|
"champ": "DO_Statut",
|
||||||
|
"valeur": statut_actuel,
|
||||||
|
"message": f"Document déjà réalisé (statut={statut_actuel}). "
|
||||||
|
f"Un document cible existe peut-être déjà.",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
elif statut_actuel == 0:
|
||||||
|
diagnostic["suggestions"].append(
|
||||||
|
"Le document est en 'Brouillon' (statut=0). "
|
||||||
|
"Le système le passera automatiquement à 'Accepté' (statut=2) avant transformation."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Vérifier le client
|
||||||
|
client_code = ""
|
||||||
|
try:
|
||||||
|
client_obj = getattr(doc, "Client", None)
|
||||||
|
if client_obj:
|
||||||
|
client_obj.Read()
|
||||||
|
client_code = getattr(client_obj, "CT_Num", "").strip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not client_code:
|
||||||
|
diagnostic["problemes_detectes"].append(
|
||||||
|
{
|
||||||
|
"severite": "BLOQUANT",
|
||||||
|
"champ": "CT_Num",
|
||||||
|
"valeur": None,
|
||||||
|
"message": "Aucun client associé au document",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
diagnostic["client_code"] = client_code
|
||||||
|
|
||||||
|
# 3. Vérifier les lignes
|
||||||
|
try:
|
||||||
|
factory_lignes = getattr(doc, "FactoryDocumentLigne", None) or getattr(
|
||||||
|
doc, "FactoryDocumentVenteLigne", None
|
||||||
|
)
|
||||||
|
|
||||||
|
nb_lignes = 0
|
||||||
|
lignes_problemes = []
|
||||||
|
|
||||||
|
if factory_lignes:
|
||||||
|
index = 1
|
||||||
|
while index <= 100:
|
||||||
|
try:
|
||||||
|
ligne_p = factory_lignes.List(index)
|
||||||
|
if ligne_p is None:
|
||||||
|
break
|
||||||
|
|
||||||
|
ligne = win32com.client.CastTo(ligne_p, "IBODocumentLigne3")
|
||||||
|
ligne.Read()
|
||||||
|
|
||||||
|
nb_lignes += 1
|
||||||
|
|
||||||
|
# Vérifier article
|
||||||
|
article_ref = ""
|
||||||
|
try:
|
||||||
|
article_ref = getattr(ligne, "AR_Ref", "").strip()
|
||||||
|
if not article_ref:
|
||||||
|
article_obj = getattr(ligne, "Article", None)
|
||||||
|
if article_obj:
|
||||||
|
article_obj.Read()
|
||||||
|
article_ref = getattr(
|
||||||
|
article_obj, "AR_Ref", ""
|
||||||
|
).strip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not article_ref:
|
||||||
|
lignes_problemes.append(
|
||||||
|
{
|
||||||
|
"ligne": index,
|
||||||
|
"probleme": "Aucune référence article",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Vérifier prix
|
||||||
|
prix = float(getattr(ligne, "DL_PrixUnitaire", 0.0))
|
||||||
|
if prix == 0:
|
||||||
|
lignes_problemes.append(
|
||||||
|
{"ligne": index, "probleme": "Prix unitaire = 0"}
|
||||||
|
)
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
|
||||||
|
diagnostic["nb_lignes"] = nb_lignes
|
||||||
|
|
||||||
|
if nb_lignes == 0:
|
||||||
|
diagnostic["problemes_detectes"].append(
|
||||||
|
{
|
||||||
|
"severite": "BLOQUANT",
|
||||||
|
"champ": "Lignes",
|
||||||
|
"valeur": 0,
|
||||||
|
"message": "Document vide (aucune ligne)",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if lignes_problemes:
|
||||||
|
diagnostic["avertissements"].append(
|
||||||
|
{
|
||||||
|
"severite": "ATTENTION",
|
||||||
|
"champ": "Lignes",
|
||||||
|
"message": f"{len(lignes_problemes)} ligne(s) avec des problèmes",
|
||||||
|
"details": lignes_problemes,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
diagnostic["avertissements"].append(
|
||||||
|
{
|
||||||
|
"severite": "ERREUR",
|
||||||
|
"champ": "Lignes",
|
||||||
|
"message": f"Impossible de lire les lignes: {e}",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4. Vérifier les totaux
|
||||||
|
total_ht = float(getattr(doc, "DO_TotalHT", 0.0))
|
||||||
|
total_ttc = float(getattr(doc, "DO_TotalTTC", 0.0))
|
||||||
|
|
||||||
|
diagnostic["totaux"] = {"total_ht": total_ht, "total_ttc": total_ttc}
|
||||||
|
|
||||||
|
if total_ht == 0 and total_ttc == 0:
|
||||||
|
diagnostic["avertissements"].append(
|
||||||
|
{
|
||||||
|
"severite": "ATTENTION",
|
||||||
|
"champ": "Totaux",
|
||||||
|
"message": "Tous les totaux sont à 0",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5. Vérifier si la transformation est autorisée
|
||||||
|
transformations_valides = {(0, 10), (10, 30), (10, 60), (30, 60), (0, 60)}
|
||||||
|
|
||||||
if (type_source, type_cible) not in transformations_valides:
|
if (type_source, type_cible) not in transformations_valides:
|
||||||
logger.error(
|
diagnostic["problemes_detectes"].append(
|
||||||
f"❌ Transformation non autorisée: {type_source} → {type_cible}"
|
{
|
||||||
)
|
"severite": "BLOQUANT",
|
||||||
raise HTTPException(
|
"champ": "Transformation",
|
||||||
400,
|
"message": f"Transformation {type_source} → {type_cible} non autorisée. "
|
||||||
f"Transformation non autorisée: type {type_source} → type {type_cible}. "
|
|
||||||
f"Transformations valides: {transformations_valides}",
|
f"Transformations valides: {transformations_valides}",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Appel au connecteur Sage
|
# Résumé
|
||||||
resultat = sage.transformer_document(numero_source, type_source, type_cible)
|
nb_bloquants = sum(
|
||||||
|
1
|
||||||
|
for p in diagnostic["problemes_detectes"]
|
||||||
|
if p.get("severite") == "BLOQUANT"
|
||||||
|
)
|
||||||
|
nb_avertissements = len(diagnostic["avertissements"])
|
||||||
|
|
||||||
logger.info(
|
diagnostic["resume"] = {
|
||||||
f"✅ Transformation réussie: {numero_source} → "
|
"peut_transformer": nb_bloquants == 0,
|
||||||
f"{resultat.get('document_cible', '?')} "
|
"nb_problemes_bloquants": nb_bloquants,
|
||||||
f"({resultat.get('nb_lignes', 0)} lignes)"
|
"nb_avertissements": nb_avertissements,
|
||||||
|
}
|
||||||
|
|
||||||
|
if nb_bloquants == 0:
|
||||||
|
diagnostic["suggestions"].append(
|
||||||
|
"✅ Aucun problème bloquant détecté. La transformation devrait fonctionner."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
diagnostic["suggestions"].append(
|
||||||
|
f"❌ {nb_bloquants} problème(s) bloquant(s) doivent être résolus avant la transformation."
|
||||||
)
|
)
|
||||||
|
|
||||||
return {"success": True, "data": resultat}
|
return {"success": True, "diagnostic": diagnostic}
|
||||||
|
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
except ValueError as e:
|
|
||||||
logger.error(f"❌ Erreur métier transformation: {e}")
|
|
||||||
raise HTTPException(400, str(e))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"❌ Erreur technique transformation: {e}", exc_info=True)
|
logger.error(f"[DIAG] Erreur diagnostic transformation: {e}", exc_info=True)
|
||||||
raise HTTPException(500, f"Erreur transformation: {str(e)}")
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/sage/documents/champ-libre", dependencies=[Depends(verify_token)])
|
@app.post("/sage/documents/champ-libre", dependencies=[Depends(verify_token)])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue