From be7bc287c0409e94804d9dedbd5f5aac0592b2db Mon Sep 17 00:00:00 2001 From: Fanilo-Nantenaina Date: Sat, 6 Dec 2025 10:16:44 +0300 Subject: [PATCH] Updates for PUT on client --- main.py | 21 ++++++ sage_connector.py | 168 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/main.py b/main.py index 7df753b..1ac24ae 100644 --- a/main.py +++ b/main.py @@ -89,6 +89,12 @@ class ClientCreateRequest(BaseModel): siret: Optional[str] = None tva_intra: Optional[str] = None +class ClientUpdateGatewayRequest(BaseModel): + """Modèle pour modification client côté gateway""" + code: str + client_data: Dict + + # ===================================================== # SÉCURITÉ # ===================================================== @@ -182,6 +188,21 @@ def clients_list(req: FiltreRequest): logger.error(f"Erreur liste clients: {e}") raise HTTPException(500, str(e)) +@app.post("/sage/clients/update", dependencies=[Depends(verify_token)]) +def modifier_client_endpoint(req: ClientUpdateGatewayRequest): + """ + ✏️ Modification d'un client dans Sage + """ + try: + resultat = sage.modifier_client(req.code, req.client_data) + return {"success": True, "data": resultat} + + except ValueError as e: + logger.warning(f"Erreur métier modification client: {e}") + raise HTTPException(404, str(e)) + except Exception as e: + logger.error(f"Erreur technique modification client: {e}") + raise HTTPException(500, str(e)) @app.post("/sage/clients/get", dependencies=[Depends(verify_token)]) def client_get(req: CodeRequest): diff --git a/sage_connector.py b/sage_connector.py index 540bc35..5e102d9 100644 --- a/sage_connector.py +++ b/sage_connector.py @@ -2744,4 +2744,172 @@ class SageConnector: pass raise RuntimeError(f"Erreur technique Sage: {error_message}") + + + def modifier_client(self, code: str, client_data: Dict) -> Dict: + """ + ✏️ Modification d'un client existant dans Sage 100c + + Args: + code: Code du client à modifier + client_data: Dictionnaire avec les champs à mettre à jour + + Returns: + Client modifié + """ + if not self.cial: + raise RuntimeError("Connexion Sage non établie") + + try: + with self._com_context(), self._lock_com: + # ======================================== + # ÉTAPE 1 : CHARGER LE CLIENT EXISTANT + # ======================================== + logger.info(f"🔍 Recherche client {code}...") + + factory_client = self.cial.CptaApplication.FactoryClient + persist = factory_client.ReadNumero(code) + + if not persist: + raise ValueError(f"Client {code} introuvable") + + client = win32com.client.CastTo(persist, "IBOClient3") + client.Read() + + logger.info(f"✅ Client {code} trouvé: {getattr(client, 'CT_Intitule', '')}") + + # ======================================== + # ÉTAPE 2 : METTRE À JOUR LES CHAMPS FOURNIS + # ======================================== + logger.info("📝 Mise à jour des champs...") + + champs_modifies = [] + + # Intitulé + if "intitule" in client_data: + intitule = str(client_data["intitule"])[:69].strip() + client.CT_Intitule = intitule + champs_modifies.append(f"intitule='{intitule}'") + + # Adresse + if any(k in client_data for k in ["adresse", "code_postal", "ville", "pays"]): + try: + adresse_obj = client.Adresse + + if "adresse" in client_data: + adresse = str(client_data["adresse"])[:35].strip() + adresse_obj.Adresse = adresse + champs_modifies.append("adresse") + + if "code_postal" in client_data: + cp = str(client_data["code_postal"])[:9].strip() + adresse_obj.CodePostal = cp + champs_modifies.append("code_postal") + + if "ville" in client_data: + ville = str(client_data["ville"])[:35].strip() + adresse_obj.Ville = ville + champs_modifies.append("ville") + + if "pays" in client_data: + pays = str(client_data["pays"])[:35].strip() + adresse_obj.Pays = pays + champs_modifies.append("pays") + + except Exception as e: + logger.warning(f"⚠️ Erreur mise à jour adresse: {e}") + + # Télécom + if "email" in client_data or "telephone" in client_data: + try: + telecom_obj = client.Telecom + + if "email" in client_data: + email = str(client_data["email"])[:69].strip() + telecom_obj.EMail = email + champs_modifies.append("email") + + if "telephone" in client_data: + tel = str(client_data["telephone"])[:21].strip() + telecom_obj.Telephone = tel + champs_modifies.append("telephone") + + except Exception as e: + logger.warning(f"⚠️ Erreur mise à jour télécom: {e}") + + # SIRET + if "siret" in client_data: + try: + siret = str(client_data["siret"])[:14].strip() + client.CT_Siret = siret + champs_modifies.append("siret") + except Exception as e: + logger.warning(f"⚠️ Erreur mise à jour SIRET: {e}") + + # TVA Intracommunautaire + if "tva_intra" in client_data: + try: + tva = str(client_data["tva_intra"])[:25].strip() + client.CT_Identifiant = tva + champs_modifies.append("tva_intra") + except Exception as e: + logger.warning(f"⚠️ Erreur mise à jour TVA: {e}") + + if not champs_modifies: + logger.warning("⚠️ Aucun champ à modifier") + return self._extraire_client(client) + + logger.info(f"📝 Champs à modifier: {', '.join(champs_modifies)}") + + # ======================================== + # ÉTAPE 3 : ÉCRIRE LES MODIFICATIONS + # ======================================== + logger.info("💾 Écriture des modifications...") + + try: + client.Write() + logger.info("✅ Write() réussi !") + + except Exception as e: + error_detail = str(e) + + try: + sage_error = self.cial.CptaApplication.LastError + if sage_error: + error_detail = f"{sage_error.Description} (Code: {sage_error.Number})" + except: + pass + + logger.error(f"❌ Erreur Write(): {error_detail}") + raise RuntimeError(f"Échec modification: {error_detail}") + + # ======================================== + # ÉTAPE 4 : RELIRE ET RETOURNER + # ======================================== + client.Read() + + logger.info(f"✅✅✅ CLIENT MODIFIÉ: {code} ({len(champs_modifies)} champs) ✅✅✅") + + # Refresh cache + self._refresh_cache_clients() + + return self._extraire_client(client) + + except ValueError as e: + logger.error(f"❌ Erreur métier: {e}") + raise + + except Exception as e: + logger.error(f"❌ Erreur modification client: {e}", exc_info=True) + + error_message = str(e) + if self.cial: + try: + err = self.cial.CptaApplication.LastError + if err: + error_message = f"Erreur Sage: {err.Description}" + except: + pass + + raise RuntimeError(f"Erreur technique Sage: {error_message}") \ No newline at end of file