modifier_contact successful

This commit is contained in:
fanilo 2025-12-28 21:32:31 +01:00
parent 3e617d070a
commit 7f64a2a548

View file

@ -6962,7 +6962,7 @@ class SageConnector:
def modifier_contact(self, numero: str, contact_numero: int, updates: Dict) -> Dict:
"""
Modifie un contact existant via COM
VERSION CORRIGÉE pour Sage 100
VERSION REFACTORISÉE - Utilise FactoryTiersContact
"""
if not self.cial:
raise RuntimeError("Connexion Sage non établie")
@ -6973,135 +6973,192 @@ class SageConnector:
logger.info(f"[MODIFICATION CONTACT] CT_No={contact_numero}")
logger.info("=" * 80)
# Lire le contact existant - CORRECTION ICI
logger.info("[1] Lecture contact existant")
# Charger le client
logger.info("[1] Chargement du client")
factory_client = self.cial.CptaApplication.FactoryClient
try:
persist_client = factory_client.ReadNumero(numero)
if not persist_client:
raise ValueError(f"Client {numero} non trouve")
# Trouver la factory
factory_contact = None
factory_names = [
"FactoryContact",
"FactoryContactTiers",
"FactoryTypeContacts",
]
client_obj = win32com.client.CastTo(persist_client, "IBOClient3")
client_obj.Read()
logger.info(f" OK Client charge")
except Exception as e:
raise ValueError(f"Client {numero} introuvable: {e}")
for factory_name in factory_names:
try:
if hasattr(self.cial.CptaApplication, factory_name):
factory_contact = getattr(self.cial.CptaApplication, factory_name)
break
except:
continue
# Charger le contact via FactoryTiersContact
logger.info("[2] Chargement du contact")
if not factory_contact:
raise RuntimeError("Aucune factory de contacts trouvée")
if not hasattr(client_obj, 'FactoryTiersContact'):
raise RuntimeError("FactoryTiersContact non trouvee sur le client")
factory_contact = client_obj.FactoryTiersContact
try:
# ReadNumero peut accepter 1 ou 2 paramètres selon la version
# Chercher le contact par son CT_No
# Il faut lister et trouver celui avec le bon CT_No
# ou utiliser une autre méthode de lecture
# STRATÉGIE : Lister tous les contacts et trouver le bon
contacts_collection = None
all_contacts = []
# Essayer de lister via SQL d'abord (plus fiable)
try:
persist = factory_contact.ReadNumero(numero, contact_numero)
except TypeError:
# Si 2 paramètres ne fonctionnent pas, essayer avec CT_No seulement
persist = factory_contact.ReadNumero(contact_numero)
with self._get_sql_connection() as conn:
cursor = conn.cursor()
cursor.execute(
"SELECT CT_Nom, CT_Prenom FROM F_CONTACTT WHERE CT_Num = ? AND CT_No = ?",
[numero, contact_numero]
)
row = cursor.fetchone()
if not row:
raise ValueError(f"Contact CT_No={contact_numero} non trouve")
nom_recherche = row.CT_Nom.strip() if row.CT_Nom else ""
prenom_recherche = row.CT_Prenom.strip() if row.CT_Prenom else ""
logger.info(f" Contact trouve en SQL: {prenom_recherche} {nom_recherche}")
except Exception as e:
raise ValueError(f"Contact introuvable: {e}")
# Charger via ReadNomPrenom
factory_dossier = self.cial.CptaApplication.FactoryDossierContact
persist = factory_dossier.ReadNomPrenom(nom_recherche, prenom_recherche)
if not persist:
raise ValueError(f"Contact CT_No={contact_numero} non trouvé pour client {numero}")
# Essayer de caster
contact = None
for interface_name in ["IBOContactT3", "IBOContact3", "IBOContactT"]:
try:
contact = win32com.client.CastTo(persist, interface_name)
break
except:
continue
if not contact:
contact = persist
raise ValueError(f"Contact non trouvable via ReadNomPrenom")
contact = win32com.client.CastTo(persist, "IBOTiersContact3")
contact.Read()
logger.info(f" ✓ Contact chargé: {getattr(contact, 'CT_Nom', '?')}")
logger.info(f" OK Contact charge: {contact.Nom}")
except Exception as e:
raise ValueError(f"Contact introuvable: {e}")
# Appliquer les modifications
logger.info("[2] Application des modifications")
logger.info("[3] Application des modifications")
modifications_appliquees = []
# Identité
if "civilite" in updates:
civilite_map = {"M.": 0, "Mme": 1, "Mlle": 2, "Société": 3}
civilite_map = {"M.": 0, "Mme": 1, "Mlle": 2, "Societe": 3}
civilite_code = civilite_map.get(updates["civilite"])
if civilite_code is not None:
self._try_set_attribute(contact, "CT_Civilite", civilite_code)
logger.info(f" CT_Civilite = {civilite_code}")
modifications_appliquees.append("civilite")
try:
contact.Civilite = civilite_code
logger.info(f" Civilite = {civilite_code}")
modifications_appliquees.append("civilite")
except:
pass
if "nom" in updates:
nom = self._clean_str(updates["nom"], 35)
if nom:
self._try_set_attribute(contact, "CT_Nom", nom)
logger.info(f" CT_Nom = {nom}")
modifications_appliquees.append("nom")
try:
contact.Nom = nom
logger.info(f" Nom = {nom}")
modifications_appliquees.append("nom")
except:
pass
if "prenom" in updates:
prenom = self._clean_str(updates["prenom"], 35)
self._try_set_attribute(contact, "CT_Prenom", prenom)
logger.info(f" CT_Prenom = {prenom}")
modifications_appliquees.append("prenom")
try:
contact.Prenom = prenom
logger.info(f" Prenom = {prenom}")
modifications_appliquees.append("prenom")
except:
pass
if "fonction" in updates:
fonction = self._clean_str(updates["fonction"], 35)
self._try_set_attribute(contact, "CT_Fonction", fonction)
logger.info(f" CT_Fonction = {fonction}")
modifications_appliquees.append("fonction")
try:
contact.Fonction = fonction
logger.info(f" Fonction = {fonction}")
modifications_appliquees.append("fonction")
except:
pass
# Service
if "service_code" in updates:
service = self._safe_int(updates["service_code"])
if service is not None:
self._try_set_attribute(contact, "N_Service", service)
logger.info(f" N_Service = {service}")
modifications_appliquees.append("service_code")
if service is not None and hasattr(contact, 'ServiceContact'):
try:
contact.ServiceContact = service
logger.info(f" ServiceContact = {service}")
modifications_appliquees.append("service_code")
except:
pass
# Coordonnées
coord_fields = {
"telephone": ("CT_Telephone", 21),
"portable": ("CT_TelPortable", 21),
"telecopie": ("CT_Telecopie", 21),
"email": ("CT_EMail", 69),
}
for key, (attr, max_len) in coord_fields.items():
if key in updates:
value = self._clean_str(updates[key], max_len)
self._try_set_attribute(contact, attr, value)
logger.info(f" {attr} = {value}")
modifications_appliquees.append(key)
# Réseaux sociaux
social_fields = {
"facebook": ("CT_Facebook", 69),
"linkedin": ("CT_LinkedIn", 69),
"skype": ("CT_Skype", 69),
}
for key, (attr, max_len) in social_fields.items():
if key in updates:
value = self._clean_str(updates[key], max_len)
self._try_set_attribute(contact, attr, value)
logger.info(f" {attr} = {value}")
modifications_appliquees.append(key)
# Enregistrement du contact
logger.info("[3] WRITE CONTACT")
try:
contact.Write()
# Coordonnées via Telecom
if hasattr(contact, 'Telecom'):
try:
contact.Read()
telecom = contact.Telecom
if "telephone" in updates:
telephone = self._clean_str(updates["telephone"], 21)
if self._try_set_attribute(telecom, "Telephone", telephone):
logger.info(f" Telephone = {telephone}")
modifications_appliquees.append("telephone")
if "portable" in updates:
portable = self._clean_str(updates["portable"], 21)
if self._try_set_attribute(telecom, "Portable", portable):
logger.info(f" Portable = {portable}")
modifications_appliquees.append("portable")
if "email" in updates:
email = self._clean_str(updates["email"], 69)
if self._try_set_attribute(telecom, "EMail", email):
logger.info(f" EMail = {email}")
modifications_appliquees.append("email")
if "telecopie" in updates:
fax = self._clean_str(updates["telecopie"], 21)
if self._try_set_attribute(telecom, "Telecopie", fax):
logger.info(f" Telecopie = {fax}")
modifications_appliquees.append("telecopie")
except:
pass
logger.info(" ✓ Write() réussi")
# Réseaux sociaux
if "facebook" in updates:
facebook = self._clean_str(updates["facebook"], 69)
try:
contact.Facebook = facebook
logger.info(f" Facebook = {facebook}")
modifications_appliquees.append("facebook")
except:
pass
if "linkedin" in updates:
linkedin = self._clean_str(updates["linkedin"], 69)
try:
contact.LinkedIn = linkedin
logger.info(f" LinkedIn = {linkedin}")
modifications_appliquees.append("linkedin")
except:
pass
if "skype" in updates:
skype = self._clean_str(updates["skype"], 69)
try:
contact.Skype = skype
logger.info(f" Skype = {skype}")
modifications_appliquees.append("skype")
except:
pass
# Enregistrement du contact
logger.info("[4] Enregistrement")
try:
contact.Write()
contact.Read()
logger.info(" OK Write() reussi")
except Exception as e:
error_detail = str(e)
try:
@ -7110,67 +7167,44 @@ class SageConnector:
error_detail = f"{sage_error.Description} (Code: {sage_error.Number})"
except:
pass
logger.error(f" ✗ Erreur Write: {error_detail}")
raise RuntimeError(f"Échec modification contact: {error_detail}")
logger.error(f" ERROR Write: {error_detail}")
raise RuntimeError(f"Echec modification contact: {error_detail}")
logger.info(f" Modifications appliquées: {', '.join(modifications_appliquees)}")
logger.info(f" Modifications appliquees: {', '.join(modifications_appliquees)}")
# Gestion du contact par défaut
est_defaut_demande = updates.get("est_defaut")
est_actuellement_defaut = False
if est_defaut_demande is not None and est_defaut_demande:
logger.info("[4] Gestion contact par défaut")
logger.info("[5] Gestion contact par defaut")
try:
# Construire le nom complet
nom_final = getattr(contact, "CT_Nom", "")
prenom_final = getattr(contact, "CT_Prenom", "")
nom_complet = f"{prenom_final} {nom_final}".strip() if prenom_final else nom_final
nom_complet = f"{contact.Prenom} {contact.Nom}".strip() if contact.Prenom else contact.Nom
# Charger le client
factory_client = self.cial.CptaApplication.FactoryClient
persist_client = factory_client.ReadNumero(numero)
client_obj = win32com.client.CastTo(persist_client, "IBOClient3")
client_obj.Read()
# Mettre à jour CT_Contact
ancien_contact = getattr(client_obj, "CT_Contact", "")
client_obj.CT_Contact = nom_complet
logger.info(f" CT_Contact: '{ancien_contact}' '{nom_complet}'")
logger.info(f" CT_Contact = '{nom_complet}'")
# Essayer CT_NoContact si disponible
if self._try_set_attribute(client_obj, "CT_NoContact", contact_numero):
logger.info(f" CT_NoContact = {contact_numero}")
if hasattr(client_obj, 'CT_NoContact'):
try:
client_obj.CT_NoContact = contact_numero
logger.info(f" CT_NoContact = {contact_numero}")
except:
pass
# Enregistrer le client
client_obj.Write()
client_obj.Read()
logger.info(" ✓ Contact défini comme par défaut")
logger.info(" OK Contact par defaut defini")
est_actuellement_defaut = True
except Exception as e:
logger.warning(f" ⚠ Échec définition par défaut: {e}")
else:
# Vérifier si c'est déjà le contact par défaut
try:
factory_client = self.cial.CptaApplication.FactoryClient
persist_client = factory_client.ReadNumero(numero)
client_obj = win32com.client.CastTo(persist_client, "IBOClient3")
client_obj.Read()
ct_contact = getattr(client_obj, "CT_Contact", "")
nom_final = getattr(contact, "CT_Nom", "")
prenom_final = getattr(contact, "CT_Prenom", "")
nom_complet = f"{prenom_final} {nom_final}".strip() if prenom_final else nom_final
est_actuellement_defaut = (ct_contact == nom_complet)
except:
pass
logger.warning(f" WARN Echec: {e}")
logger.info("=" * 80)
logger.info(f"[SUCCÈS] Contact modifié: CT_No={contact_numero}")
if est_actuellement_defaut:
logger.info(f" Contact par défaut")
logger.info(f"[SUCCES] Contact modifie: CT_No={contact_numero}")
logger.info("=" * 80)
contact_dict = self._contact_to_dict(contact)