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)])
|
||||
def transformer_document(
|
||||
numero_source: str = Query(..., description="Numéro du document source"),
|
||||
type_source: int = Query(..., description="Type document source"),
|
||||
type_cible: int = Query(..., description="Type document cible"),
|
||||
numero: str, type_source: int = Query(...), type_cible: int = Query(...)
|
||||
):
|
||||
"""
|
||||
🔧 Transformation de document
|
||||
🔍 DIAGNOSTIC AVANCÉ: Analyse pourquoi une transformation échoue
|
||||
|
||||
✅ CORRECTION : Utilise les VRAIS types Sage Dataven
|
||||
|
||||
Types valides :
|
||||
- 0: Devis
|
||||
- 10: Bon de commande
|
||||
- 20: Préparation
|
||||
- 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)
|
||||
Vérifie:
|
||||
- Statut du document source
|
||||
- Statuts autorisés
|
||||
- Lignes du document
|
||||
- Client associé
|
||||
- Champs obligatoires manquants
|
||||
"""
|
||||
try:
|
||||
logger.info(
|
||||
f"🔄 Transformation demandée: {numero_source} "
|
||||
f"(type {type_source}) → type {type_cible}"
|
||||
if not sage or not sage.cial:
|
||||
raise HTTPException(503, "Service Sage indisponible")
|
||||
|
||||
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
|
||||
transformations_valides = {
|
||||
(0, 10), # Devis → Commande
|
||||
(10, 30), # Commande → Bon de livraison
|
||||
(10, 60), # Commande → Facture
|
||||
(30, 60), # Bon de livraison → Facture
|
||||
(0, 60), # Devis → Facture (si autorisé)
|
||||
doc = win32com.client.CastTo(persist, "IBODocumentVente3")
|
||||
doc.Read()
|
||||
|
||||
diagnostic = {
|
||||
"numero": numero,
|
||||
"type_source": type_source,
|
||||
"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:
|
||||
logger.error(
|
||||
f"❌ Transformation non autorisée: {type_source} → {type_cible}"
|
||||
)
|
||||
raise HTTPException(
|
||||
400,
|
||||
f"Transformation non autorisée: type {type_source} → type {type_cible}. "
|
||||
diagnostic["problemes_detectes"].append(
|
||||
{
|
||||
"severite": "BLOQUANT",
|
||||
"champ": "Transformation",
|
||||
"message": f"Transformation {type_source} → {type_cible} non autorisée. "
|
||||
f"Transformations valides: {transformations_valides}",
|
||||
}
|
||||
)
|
||||
|
||||
# Appel au connecteur Sage
|
||||
resultat = sage.transformer_document(numero_source, type_source, type_cible)
|
||||
# Résumé
|
||||
nb_bloquants = sum(
|
||||
1
|
||||
for p in diagnostic["problemes_detectes"]
|
||||
if p.get("severite") == "BLOQUANT"
|
||||
)
|
||||
nb_avertissements = len(diagnostic["avertissements"])
|
||||
|
||||
logger.info(
|
||||
f"✅ Transformation réussie: {numero_source} → "
|
||||
f"{resultat.get('document_cible', '?')} "
|
||||
f"({resultat.get('nb_lignes', 0)} lignes)"
|
||||
diagnostic["resume"] = {
|
||||
"peut_transformer": nb_bloquants == 0,
|
||||
"nb_problemes_bloquants": nb_bloquants,
|
||||
"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:
|
||||
raise
|
||||
except ValueError as e:
|
||||
logger.error(f"❌ Erreur métier transformation: {e}")
|
||||
raise HTTPException(400, str(e))
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Erreur technique transformation: {e}", exc_info=True)
|
||||
raise HTTPException(500, f"Erreur transformation: {str(e)}")
|
||||
logger.error(f"[DIAG] Erreur diagnostic transformation: {e}", exc_info=True)
|
||||
raise HTTPException(500, str(e))
|
||||
|
||||
|
||||
@app.post("/sage/documents/champ-libre", dependencies=[Depends(verify_token)])
|
||||
|
|
|
|||
Loading…
Reference in a new issue