Modified create client context
This commit is contained in:
parent
2e96cec20d
commit
e8558e207b
2 changed files with 69 additions and 50 deletions
5
main.py
5
main.py
|
|
@ -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))
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
|
||||||
|
|
@ -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}")
|
||||||
Loading…
Reference in a new issue