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

View file

@ -2377,79 +2377,95 @@ class SageConnector:
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:
raise RuntimeError("Connexion Sage non établie")
try:
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
# 2. Création de l'objet en mémoire
client = factory_client.Create() # Ou CreateNew() selon version, Create() est plus standard
# CORRECTION CRITIQUE: Utiliser CreateNew() pour obtenir l'objet Tiers concret
client = factory_client.CreateNew()
# 3. Remplissage des Champs OBLIGATOIRES
# 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"]
# 2. Remplissage des Champs OBLIGATOIRES (Conformes F_COMPTET)
# 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_Type = 0 # 0 = Client
# Compte Collectif (Obligatoire, ex: 411000)
# CORRECTION : Utiliser CT_CompteG (mappé à CG_NumPrinc)
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
# --- Adresse principale ---
try:
client.Adresse.Adresse = client_data.get("adresse", "")
client.Adresse.CodePostal = client_data.get("code_postal", "")
client.Adresse.Ville = client_data.get("ville", "")
client.Adresse.Pays = client_data.get("pays", "")
except Exception as e:
logger.warning(f"Erreur remplissage adresse: {e}")
# Initialisation des champs obligatoires (N_...)
client.N_CatTarif = 1
client.N_CatCompta = 1
client.N_Period = 1
client.N_Expedition = 1
client.N_Condition = 1
client.N_Risque = 1
# --- 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:
client.Telecom.Telephone = client_data.get("telephone", "")
client.Telecom.EMail = client_data.get("email", "")
if client_data.get("adresse"): client.Adresse.Adresse = client_data["adresse"]
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:
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 ---
if client_data.get("siret"):
try: client.CT_Siret = client_data["siret"]
except: pass
if client_data.get("siret"): client.CT_Siret = client_data["siret"]
if client_data.get("tva_intra"): client.CT_Identifiant = client_data["tva_intra"]
if client_data.get("tva_intra"):
try: client.CT_Identifiant = client_data["tva_intra"]
except: pass
# 5. Écriture en base
# 4. Écriture en base
client.Write()
# Récupération du numéro généré (surtout si auto-incrément)
num_final = client.CT_Num
# 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}")
logger.info(f"✅ Client créé et conforme: {num_final} - {client.CT_Intitule}")
return {
"numero": num_final,
"intitule": client.CT_Intitule,
"compte_collectif": getattr(client, "CT_CompteA", "")
"compte_collectif": getattr(client, "CT_CompteG", "")
}
except Exception as e:
logger.error(f"❌ Erreur création client: {e}", exc_info=True)
# Gestion d'erreur spécifique pour les doublons
if "doublon" in str(e).lower() or "existe déjà" in str(e).lower():
raise ValueError(f"Le client ou le numéro existe déjà.")
raise RuntimeError(f"Erreur technique Sage: {str(e)}")
# Gestion d'erreur remontant l'erreur COM détaillée (si disponible)
error_message = str(e)
if self.cial:
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}")