From 0763a56b069feaf9d95b6db683d58eae49d9a0ae Mon Sep 17 00:00:00 2001 From: Fanilo-Nantenaina Date: Fri, 28 Nov 2025 11:11:23 +0300 Subject: [PATCH] Testing BC to FA --- main.py | 63 ++++++++++++++++++++++++++++ sage_connector.py | 104 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 162 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index cf7715d..8bd9682 100644 --- a/main.py +++ b/main.py @@ -1450,6 +1450,69 @@ def tester_creation_par_type(type_doc: int = Query(..., ge=0, le=20)): raise HTTPException(500, str(e)) +@app.get("/sage/diagnostic/facture-requirements", dependencies=[Depends(verify_token)]) +def diagnostiquer_exigences_facture(): + """ + DIAGNOSTIC: Découvre les champs obligatoires pour créer une facture + """ + try: + if not sage or not sage.cial: + raise HTTPException(503, "Service Sage indisponible") + + with sage._com_context(), sage._lock_com: + # Créer un process facture de test + process = sage.cial.CreateProcess_Document(60) + doc_test = process.Document + + try: + doc_test = win32com.client.CastTo(doc_test, "IBODocumentVente3") + except: + pass + + # Tester tous les champs potentiellement obligatoires + champs_a_tester = [ + "DO_ModeRegl", + "DO_CondRegl", + "DO_CodeJournal", + "DO_Souche", + "DO_TypeCalcul", + "DO_CodeTaxe1", + "CT_Num", + "DO_Date", + "DO_Statut", + ] + + resultats = {} + + for champ in champs_a_tester: + try: + valeur = getattr(doc_test, champ, None) + resultats[champ] = { + "valeur_defaut": str(valeur) if valeur is not None else "None", + "accessible": True, + } + except Exception as e: + resultats[champ] = { + "valeur_defaut": "N/A", + "accessible": False, + "erreur": str(e)[:100], + } + + # Ne pas valider le document de test + del process + del doc_test + + return { + "success": True, + "champs_facture": resultats, + "conseil": "Les champs avec valeur_defaut=None ou 0 sont souvent obligatoires", + } + + except Exception as e: + logger.error(f"[DIAG] Erreur: {e}", exc_info=True) + raise HTTPException(500, str(e)) + + # ===================================================== # LANCEMENT # ===================================================== diff --git a/sage_connector.py b/sage_connector.py index c432c07..7ae40be 100644 --- a/sage_connector.py +++ b/sage_connector.py @@ -1352,17 +1352,111 @@ class SageConnector: logger.info(f"[TRANSFORM] {nb_lignes} lignes copiees") # ======================================== - # ÉTAPE 8 : VALIDER LE DOCUMENT + # ÉTAPE 8 : COMPLÉTER LES CHAMPS OBLIGATOIRES POUR FACTURE + # ======================================== + if type_cible == 60: # Facture + logger.info( + "[TRANSFORM] Completion champs obligatoires facture..." + ) + + # Mode de règlement (obligatoire pour facture) + try: + # Récupérer le mode de règlement du client + if client_obj_cible: + mode_reglement = getattr( + client_obj_cible, "CT_ModeRegl", None + ) + if mode_reglement: + doc_cible.DO_ModeRegl = mode_reglement + logger.info( + f"[TRANSFORM] Mode reglement: {mode_reglement}" + ) + except Exception as e: + logger.warning( + f"[TRANSFORM] Impossible de definir mode reglement: {e}" + ) + # Forcer un mode par défaut (0 = Aucun) + try: + doc_cible.DO_ModeRegl = 0 + except: + pass + + # Conditions de règlement + try: + if client_obj_cible: + cond_reglement = getattr( + client_obj_cible, "CT_CondRegl", None + ) + if cond_reglement: + doc_cible.DO_CondRegl = cond_reglement + except Exception as e: + logger.warning( + f"[TRANSFORM] Impossible de definir conditions reglement: {e}" + ) + + # Code journal (critique pour facture) + try: + # Vérifier si un code journal est déjà défini + journal_actuel = getattr(doc_cible, "DO_CodeJournal", None) + if not journal_actuel: + # Essayer de récupérer le journal par défaut + try: + # Généralement "VE" pour ventes + doc_cible.DO_CodeJournal = "VE" + logger.info("[TRANSFORM] Code journal: VE") + except: + pass + except Exception as e: + logger.warning( + f"[TRANSFORM] Impossible de definir code journal: {e}" + ) + + # Souche de numérotation + try: + souche = getattr(doc_cible, "DO_Souche", None) + if not souche or souche == 0: + # Utiliser souche par défaut (généralement 0) + doc_cible.DO_Souche = 0 + except Exception as e: + logger.warning( + f"[TRANSFORM] Impossible de definir souche: {e}" + ) + + # ======================================== + # ÉTAPE 9 : VALIDER LE DOCUMENT # ======================================== logger.info("[TRANSFORM] Validation document cible...") doc_cible.Write() - process.Process() - logger.info("[TRANSFORM] Document cible valide") + try: + process.Process() + logger.info("[TRANSFORM] Document cible valide") + except Exception as e: + logger.error(f"[TRANSFORM] Erreur Process(): {e}") + + # Diagnostic détaillé + try: + logger.info("[TRANSFORM] === DIAGNOSTIC DOCUMENT ===") + logger.info(f"Type: {getattr(doc_cible, 'DO_Type', '?')}") + logger.info(f"Client: {getattr(doc_cible, 'CT_Num', '?')}") + logger.info(f"Date: {getattr(doc_cible, 'DO_Date', '?')}") + logger.info( + f"Mode reglement: {getattr(doc_cible, 'DO_ModeRegl', '?')}" + ) + logger.info( + f"Code journal: {getattr(doc_cible, 'DO_CodeJournal', '?')}" + ) + logger.info( + f"Souche: {getattr(doc_cible, 'DO_Souche', '?')}" + ) + except: + pass + + raise # ======================================== - # ÉTAPE 9 : RÉCUPÉRER LE NUMÉRO + # ÉTAPE 10 : RÉCUPÉRER LE NUMÉRO # ======================================== numero_cible = None try: @@ -1385,7 +1479,7 @@ class SageConnector: logger.info(f"[TRANSFORM] Document cible cree: {numero_cible}") # ======================================== - # ÉTAPE 10 : COMMIT & MAJ STATUT SOURCE + # ÉTAPE 11 : COMMIT & MAJ STATUT SOURCE # ======================================== if transaction_active: try: