Modified create client context

This commit is contained in:
Fanilo-Nantenaina 2025-12-05 19:37:48 +03:00
parent 2e96cec20d
commit e8558e207b
2 changed files with 69 additions and 50 deletions

View file

@ -198,18 +198,21 @@ def client_get(req: CodeRequest):
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
# DANS main.py
@app.post("/sage/clients/create", dependencies=[Depends(verify_token)]) @app.post("/sage/clients/create", dependencies=[Depends(verify_token)])
def create_client_endpoint(req: ClientCreateRequest): def create_client_endpoint(req: ClientCreateRequest):
"""Création d'un client dans Sage""" """Création d'un client dans Sage"""
try: try:
# Transformation du modèle Pydantic en dict pour le connecteur # L'appel au connecteur est fait ici
resultat = sage.creer_client(req.dict()) resultat = sage.creer_client(req.dict())
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier création client: {e}") logger.warning(f"Erreur métier création client: {e}")
# Erreur métier (ex: doublon) -> 400 Bad Request
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
except Exception as e: except Exception as e:
logger.error(f"Erreur technique création client: {e}") logger.error(f"Erreur technique création client: {e}")
# Erreur technique (ex: COM) -> 500 Internal Server Error
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
# ===================================================== # =====================================================

View file

@ -2377,79 +2377,95 @@ class SageConnector:
def creer_client(self, client_data: Dict) -> Dict: def creer_client(self, client_data: Dict) -> Dict:
""" """
Crée un nouveau client dans Sage via CptaApplication.FactoryClient Crée un nouveau client dans Sage 100c via l'API COM,
en utilisant CreateNew() pour obtenir l'objet concret.
""" """
if not self.cial: if not self.cial:
raise RuntimeError("Connexion Sage non établie") raise RuntimeError("Connexion Sage non établie")
try: try:
with self._com_context(), self._lock_com: with self._com_context(), self._lock_com:
# 1. Accès à la Factory Client (Module Comptabilité) # 1. Accès à la Factory Client (CptaApplication si Tiers)
factory_client = self.cial.CptaApplication.FactoryClient factory_client = self.cial.CptaApplication.FactoryClient
# 2. Création de l'objet en mémoire # CORRECTION CRITIQUE: Utiliser CreateNew() pour obtenir l'objet Tiers concret
client = factory_client.Create() # Ou CreateNew() selon version, Create() est plus standard client = factory_client.CreateNew()
# 3. Remplissage des Champs OBLIGATOIRES # 2. Remplissage des Champs OBLIGATOIRES (Conformes F_COMPTET)
# Si 'num' est fourni, on l'utilise, sinon Sage utilisera la souche par défaut
if client_data.get("num"):
client.CT_Num = client_data["num"]
# CT_Num (Numéro de compte)
num_prop = client_data.get("num", "")
if num_prop:
# S'assurer que le numéro est en majuscule (conforme Alpha Majuscule)
client.CT_Num = num_prop.upper()
# CT_Intitule - Si cette ligne échoue, l'objet créé n'est pas bon.
client.CT_Intitule = client_data["intitule"] client.CT_Intitule = client_data["intitule"]
client.CT_Type = 0 # 0 = Client client.CT_Type = 0 # 0 = Client
# Compte Collectif (Obligatoire, ex: 411000) # CORRECTION : Utiliser CT_CompteG (mappé à CG_NumPrinc)
if client_data.get("compte_collectif"): if client_data.get("compte_collectif"):
client.CT_CompteA = client_data["compte_collectif"] client.CT_CompteG = client_data["compte_collectif"]
# 4. Remplissage des Champs OPTIONNELS # Initialisation des champs obligatoires (N_...)
# --- Adresse principale --- client.N_CatTarif = 1
try: client.N_CatCompta = 1
client.Adresse.Adresse = client_data.get("adresse", "") client.N_Period = 1
client.Adresse.CodePostal = client_data.get("code_postal", "") client.N_Expedition = 1
client.Adresse.Ville = client_data.get("ville", "") client.N_Condition = 1
client.Adresse.Pays = client_data.get("pays", "") client.N_Risque = 1
except Exception as e:
logger.warning(f"Erreur remplissage adresse: {e}")
# --- Contact / Télécom --- # CT_NumPayeur doit être défini, souvent égal à CT_Num
client.CT_NumPayeur = client.CT_Num
# 3. CHAMPS OPTIONNELS
# --- Adresse principale (Accès via sous-objet Adresse) ---
# Ajout d'une gestion d'erreur sur l'accès aux sous-objets car ils peuvent varier
try: try:
client.Telecom.Telephone = client_data.get("telephone", "") if client_data.get("adresse"): client.Adresse.Adresse = client_data["adresse"]
client.Telecom.EMail = client_data.get("email", "") if client_data.get("code_postal"): client.Adresse.CodePostal = client_data["code_postal"]
if client_data.get("ville"): client.Adresse.Ville = client_data["ville"]
if client_data.get("pays"): client.Adresse.Pays = client_data["pays"]
except Exception as e: except Exception as e:
logger.warning(f"Erreur remplissage telecom: {e}") logger.warning(f"Impossible de définir l'adresse: {e}")
# --- Contact / Télécom (Accès via sous-objet Telecom) ---
try:
if client_data.get("telephone"): client.Telecom.Telephone = client_data["telephone"]
if client_data.get("email"): client.Telecom.EMail = client_data["email"]
except Exception as e:
logger.warning(f"Impossible de définir les télécoms: {e}")
# --- Identifiants --- # --- Identifiants ---
if client_data.get("siret"): if client_data.get("siret"): client.CT_Siret = client_data["siret"]
try: client.CT_Siret = client_data["siret"] if client_data.get("tva_intra"): client.CT_Identifiant = client_data["tva_intra"]
except: pass
if client_data.get("tva_intra"): # 4. Écriture en base
try: client.CT_Identifiant = client_data["tva_intra"]
except: pass
# 5. Écriture en base
client.Write() client.Write()
# Récupération du numéro généré (surtout si auto-incrément)
num_final = client.CT_Num num_final = client.CT_Num
logger.info(f"✅ Client créé et conforme: {num_final} - {client.CT_Intitule}")
# Mise à jour du cache local immédiate pour qu'il soit trouvable tout de suite
with self._lock_clients:
self._cache_clients.append(self._extraire_client(client))
self._cache_clients_dict[num_final] = self._extraire_client(client)
logger.info(f"✅ Client créé avec succès : {num_final} - {client.CT_Intitule}")
return { return {
"numero": num_final, "numero": num_final,
"intitule": client.CT_Intitule, "intitule": client.CT_Intitule,
"compte_collectif": getattr(client, "CT_CompteA", "") "compte_collectif": getattr(client, "CT_CompteG", "")
} }
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur création client: {e}", exc_info=True) logger.error(f"❌ Erreur création client: {e}", exc_info=True)
# Gestion d'erreur spécifique pour les doublons # Gestion d'erreur remontant l'erreur COM détaillée (si disponible)
if "doublon" in str(e).lower() or "existe déjà" in str(e).lower(): error_message = str(e)
raise ValueError(f"Le client ou le numéro existe déjà.") if self.cial:
raise RuntimeError(f"Erreur technique Sage: {str(e)}") try:
err = self.cial.LastError
if err:
error_message = f"Erreur Sage: {err.Description}"
if "doublon" in err.Description.lower():
raise ValueError(f"Ce client ou ce numéro existe déjà. {error_message}")
except:
pass
# Le connecteur lève maintenant un RuntimeError clair
raise RuntimeError(f"Erreur technique Sage: {error_message}")