refactor: improve client association and validation by safeguarding the client object and adding re-association logic.

This commit is contained in:
Fanilo-Nantenaina 2025-11-28 12:05:06 +03:00
parent a4dd2c40ba
commit e6c2ab6670

View file

@ -1266,16 +1266,15 @@ class SageConnector:
if not client_obj_cible: if not client_obj_cible:
raise ValueError(f"Impossible de charger client {client_code}") raise ValueError(f"Impossible de charger client {client_code}")
# ✅ SOLUTION : Utiliser SetClient au lieu de SetDefaultClient # ✅ Associer le client
# SetClient définit UNIQUEMENT le client sans réinitialiser les autres champs
try: try:
doc_cible.SetClient(client_obj_cible) doc_cible.SetClient(client_obj_cible)
logger.info( logger.info(
f"[TRANSFORM] SetClient() appelé pour {client_code}" f"[TRANSFORM] SetClient() appele pour {client_code}"
) )
except Exception as e: except Exception as e:
logger.warning( logger.warning(
f"[TRANSFORM] SetClient() échoué: {e}, tentative SetDefaultClient()" f"[TRANSFORM] SetClient() echoue: {e}, tentative SetDefaultClient()"
) )
doc_cible.SetDefaultClient(client_obj_cible) doc_cible.SetDefaultClient(client_obj_cible)
@ -1297,13 +1296,16 @@ class SageConnector:
if not client_verifie: if not client_verifie:
raise ValueError( raise ValueError(
f"Échec association client {client_code} - CT_Num reste vide après Write()" f"Echec association client {client_code} - CT_Num reste vide apres Write()"
) )
logger.info( logger.info(
f"[TRANSFORM] Client {client_code} associé et vérifié (CT_Num={client_verifie})" f"[TRANSFORM] Client {client_code} associe et verifie (CT_Num={client_verifie})"
) )
# 🔒 GARDER UNE RÉFÉRENCE À L'OBJET CLIENT POUR RÉASSOCIATION
client_obj_sauvegarde = client_obj_cible
# ======================================== # ========================================
# ÉTAPE 7 : COPIER LES LIGNES # ÉTAPE 7 : COPIER LES LIGNES
# ======================================== # ========================================
@ -1392,11 +1394,9 @@ class SageConnector:
"[TRANSFORM] Completion champs obligatoires facture..." "[TRANSFORM] Completion champs obligatoires facture..."
) )
# 1. Code journal (SEUL CHAMP VRAIMENT CRITIQUE) # 1. Code journal
try: try:
journal = None journal = None
# Essayer de récupérer du document source
try: try:
journal = getattr(doc_source, "DO_CodeJournal", None) journal = getattr(doc_source, "DO_CodeJournal", None)
if journal: if journal:
@ -1406,12 +1406,10 @@ class SageConnector:
except: except:
pass pass
# Si pas trouvé, utiliser "VTE" (Ventes - confirmé existant dans votre config)
if not journal: if not journal:
journal = "VTE" journal = "VTE"
logger.info("[TRANSFORM] Journal par defaut: VTE") logger.info("[TRANSFORM] Journal par defaut: VTE")
# Vérifier si le champ existe avant de l'assigner
if hasattr(doc_cible, "DO_CodeJournal"): if hasattr(doc_cible, "DO_CodeJournal"):
doc_cible.DO_CodeJournal = journal doc_cible.DO_CodeJournal = journal
logger.info( logger.info(
@ -1421,14 +1419,12 @@ class SageConnector:
logger.warning( logger.warning(
"[TRANSFORM] DO_CodeJournal inexistant sur ce document" "[TRANSFORM] DO_CodeJournal inexistant sur ce document"
) )
except Exception as e: except Exception as e:
# Le journal n'est peut-être pas obligatoire sur votre installation
logger.warning( logger.warning(
f"[TRANSFORM] Impossible de definir code journal: {e}" f"[TRANSFORM] Impossible de definir code journal: {e}"
) )
# 2. Souche de numérotation (copie depuis source) # 2. Souche
try: try:
souche = getattr(doc_source, "DO_Souche", 0) souche = getattr(doc_source, "DO_Souche", 0)
if hasattr(doc_cible, "DO_Souche"): if hasattr(doc_cible, "DO_Souche"):
@ -1437,7 +1433,7 @@ class SageConnector:
except Exception as e: except Exception as e:
logger.debug(f"[TRANSFORM] Souche non definie: {e}") logger.debug(f"[TRANSFORM] Souche non definie: {e}")
# 3. Régime de TVA (si présent) # 3. Régime de TVA
try: try:
regime = getattr(doc_source, "DO_Regime", None) regime = getattr(doc_source, "DO_Regime", None)
if regime is not None and hasattr(doc_cible, "DO_Regime"): if regime is not None and hasattr(doc_cible, "DO_Regime"):
@ -1446,7 +1442,7 @@ class SageConnector:
except Exception as e: except Exception as e:
logger.debug(f"[TRANSFORM] Regime TVA non defini: {e}") logger.debug(f"[TRANSFORM] Regime TVA non defini: {e}")
# 4. Type de transaction (si présent) # 4. Type de transaction
try: try:
transaction = getattr(doc_source, "DO_Transaction", None) transaction = getattr(doc_source, "DO_Transaction", None)
if transaction is not None and hasattr( if transaction is not None and hasattr(
@ -1460,20 +1456,24 @@ class SageConnector:
# 5. Domaine (Vente = 0) # 5. Domaine (Vente = 0)
try: try:
if hasattr(doc_cible, "DO_Domaine"): if hasattr(doc_cible, "DO_Domaine"):
doc_cible.DO_Domaine = 0 # 0 = Vente doc_cible.DO_Domaine = 0
logger.info("[TRANSFORM] Domaine: 0 (Vente)") logger.info("[TRANSFORM] Domaine: 0 (Vente)")
except Exception as e: except Exception as e:
logger.debug(f"[TRANSFORM] Domaine non defini: {e}") logger.debug(f"[TRANSFORM] Domaine non defini: {e}")
# Écrire le document avec les champs complétés # ========================================
logger.info( # 🔒 RÉASSOCIER LE CLIENT AVANT VALIDATION
"[TRANSFORM] Ecriture document avec champs completes..." # ========================================
) logger.info("[TRANSFORM] Reassociation client avant validation...")
doc_cible.Write()
# ============================================================================== try:
# ÉTAPE 9 : VALIDATION SIMPLIFIÉE (à remplacer aussi) doc_cible.SetClient(client_obj_sauvegarde)
# ============================================================================== except:
doc_cible.SetDefaultClient(client_obj_sauvegarde)
# Écriture finale avec tous les champs complétés
logger.info("[TRANSFORM] Ecriture document finale...")
doc_cible.Write()
# ======================================== # ========================================
# ÉTAPE 9 : VALIDER LE DOCUMENT # ÉTAPE 9 : VALIDER LE DOCUMENT
@ -1483,15 +1483,13 @@ class SageConnector:
# Relire pour vérifier # Relire pour vérifier
doc_cible.Read() doc_cible.Read()
# Diagnostic pré-validation (uniquement champs existants) # Diagnostic pré-validation
logger.info("[TRANSFORM] === PRE-VALIDATION CHECK ===") logger.info("[TRANSFORM] === PRE-VALIDATION CHECK ===")
# Liste des champs à vérifier (avec hasattr pour éviter les erreurs)
champs_a_verifier = [ champs_a_verifier = [
"DO_Type", "DO_Type",
"CT_Num", "CT_Num",
"DO_Date", "DO_Date",
"DO_CodeJournal",
"DO_Souche", "DO_Souche",
"DO_Statut", "DO_Statut",
"DO_Regime", "DO_Regime",
@ -1506,16 +1504,58 @@ class SageConnector:
except: except:
pass pass
# Vérifier UNIQUEMENT les champs absolument critiques # ✅ VÉRIFICATION CLIENT AMÉLIORÉE
champs_manquants = [] client_final = getattr(doc_cible, "CT_Num", None)
if not getattr(doc_cible, "CT_Num", None): if not client_final:
champs_manquants.append("Client (CT_Num)") try:
client_obj_test = getattr(doc_cible, "Client", None)
if client_obj_test:
client_obj_test.Read()
client_final = getattr(client_obj_test, "CT_Num", None)
logger.info(
f"[TRANSFORM] Client recupere via .Client: {client_final}"
)
except:
pass
if champs_manquants: # Si toujours pas de client, dernière réassociation forcée
erreur = f"Champs obligatoires manquants: {', '.join(champs_manquants)}" if not client_final:
logger.error(f"[TRANSFORM] {erreur}") logger.warning(
raise ValueError(erreur) "[TRANSFORM] Client perdu ! Tentative reassociation d'urgence..."
)
try:
doc_cible.SetClient(client_obj_sauvegarde)
except:
doc_cible.SetDefaultClient(client_obj_sauvegarde)
doc_cible.Write()
doc_cible.Read()
client_final = getattr(doc_cible, "CT_Num", None)
if not client_final:
try:
client_obj_test = getattr(doc_cible, "Client", None)
if client_obj_test:
client_obj_test.Read()
client_final = getattr(
client_obj_test, "CT_Num", None
)
except:
pass
if not client_final:
logger.error(
"[TRANSFORM] IMPOSSIBLE d'associer le client malgre toutes les tentatives"
)
raise ValueError(
f"Client {client_code} impossible a associer au document"
)
logger.info(
f"[TRANSFORM] ✅ Client confirme avant validation: {client_final}"
)
# Lancer le processus # Lancer le processus
try: try:
@ -1527,7 +1567,6 @@ class SageConnector:
logger.error(f"[TRANSFORM] ERREUR Process(): {e}") logger.error(f"[TRANSFORM] ERREUR Process(): {e}")
logger.error("[TRANSFORM] === DIAGNOSTIC COMPLET ===") logger.error("[TRANSFORM] === DIAGNOSTIC COMPLET ===")
# Afficher uniquement les attributs DO_ et CT_ qui existent
try: try:
attributs_doc = [ attributs_doc = [
attr attr