Better usage and exploitation of contact_to_dict
This commit is contained in:
parent
09e3589132
commit
6bb1253a1a
1 changed files with 74 additions and 104 deletions
|
|
@ -74,13 +74,6 @@ class SageConnector:
|
|||
if conn:
|
||||
conn.close()
|
||||
|
||||
# def _safe_strip(self, value):
|
||||
# """Strip sécurisé pour valeurs SQL"""
|
||||
# if value is None:
|
||||
# return None
|
||||
# if isinstance(value, str):
|
||||
# return value.strip()
|
||||
# return value
|
||||
|
||||
def _cleanup_com_thread(self):
|
||||
"""Nettoie COM pour le thread actuel (à appeler à la fin)"""
|
||||
|
|
@ -937,7 +930,6 @@ class SageConnector:
|
|||
cursor.execute(query, [numero])
|
||||
rows = cursor.fetchall()
|
||||
|
||||
# Récupérer le contact par défaut du client
|
||||
query_client = """
|
||||
SELECT CT_Contact
|
||||
FROM F_COMPTET
|
||||
|
|
@ -954,7 +946,6 @@ class SageConnector:
|
|||
for row in rows:
|
||||
contact = self._row_to_contact_dict(row)
|
||||
|
||||
# Vérifier si c'est le contact par défaut
|
||||
if nom_contact_defaut:
|
||||
nom_complet = f"{contact.get('prenom', '')} {contact['nom']}".strip()
|
||||
contact["est_defaut"] = (
|
||||
|
|
@ -6666,7 +6657,7 @@ class SageConnector:
|
|||
def creer_contact(self, contact_data: Dict) -> Dict:
|
||||
"""
|
||||
Crée un nouveau contact dans F_CONTACTT via COM
|
||||
VERSION CORRIGÉE - Utilise IBOTiersContact3
|
||||
VERSION FINALE COMPLÈTE
|
||||
"""
|
||||
if not self.cial:
|
||||
raise RuntimeError("Connexion Sage non établie")
|
||||
|
|
@ -6717,7 +6708,7 @@ class SageConnector:
|
|||
persist = factory_contact.Create()
|
||||
logger.info(f" Objet cree: {type(persist).__name__}")
|
||||
|
||||
# Cast vers IBOTiersContact3 (qui a Nom, Prenom, etc.)
|
||||
# Cast vers IBOTiersContact3
|
||||
contact = None
|
||||
interfaces_a_tester = [
|
||||
"IBOTiersContact3",
|
||||
|
|
@ -6730,12 +6721,11 @@ class SageConnector:
|
|||
try:
|
||||
temp = win32com.client.CastTo(persist, interface_name)
|
||||
|
||||
# Vérifier si Nom existe (pas CT_Num !)
|
||||
# Vérifier si Nom existe
|
||||
if hasattr(temp, '_prop_map_put_'):
|
||||
props = list(temp._prop_map_put_.keys())
|
||||
logger.info(f" Test {interface_name}: props={props[:15]}")
|
||||
|
||||
# Chercher Nom ou CT_Nom
|
||||
if 'Nom' in props or 'CT_Nom' in props:
|
||||
contact = temp
|
||||
logger.info(f" OK Cast reussi vers {interface_name}")
|
||||
|
|
@ -6930,24 +6920,22 @@ class SageConnector:
|
|||
logger.info(f" CT_No={contact_no}")
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Retour
|
||||
contact_dict = {
|
||||
"numero": numero_client,
|
||||
"n_contact": n_contact or contact_no,
|
||||
"civilite": contact_data.get("civilite"),
|
||||
"nom": nom,
|
||||
"prenom": prenom,
|
||||
"fonction": contact_data.get("fonction"),
|
||||
"service_code": contact_data.get("service_code"),
|
||||
"telephone": contact_data.get("telephone"),
|
||||
"portable": contact_data.get("portable"),
|
||||
"telecopie": contact_data.get("telecopie"),
|
||||
"email": contact_data.get("email"),
|
||||
"facebook": contact_data.get("facebook"),
|
||||
"linkedin": contact_data.get("linkedin"),
|
||||
"skype": contact_data.get("skype"),
|
||||
"est_defaut": est_defaut,
|
||||
}
|
||||
# Utiliser _contact_to_dict
|
||||
contact_dict = self._contact_to_dict(
|
||||
contact,
|
||||
numero_client=numero_client,
|
||||
contact_numero=contact_no,
|
||||
n_contact=n_contact
|
||||
)
|
||||
contact_dict["est_defaut"] = est_defaut
|
||||
|
||||
logger.info("=" * 80)
|
||||
logger.info("[DEBUG RETOUR]")
|
||||
logger.info(f" numero_client = {numero_client}")
|
||||
logger.info(f" contact_no = {contact_no}")
|
||||
logger.info(f" n_contact = {n_contact}")
|
||||
logger.info(f" contact_dict COMPLET = {contact_dict}")
|
||||
logger.info("=" * 80)
|
||||
|
||||
return contact_dict
|
||||
|
||||
|
|
@ -6958,11 +6946,10 @@ class SageConnector:
|
|||
logger.error(f"[ERREUR] {e}", exc_info=True)
|
||||
raise RuntimeError(f"Erreur technique: {e}")
|
||||
|
||||
|
||||
def modifier_contact(self, numero: str, contact_numero: int, updates: Dict) -> Dict:
|
||||
"""
|
||||
Modifie un contact existant via COM
|
||||
VERSION REFACTORISÉE - Utilise FactoryTiersContact
|
||||
VERSION COMPLÈTE REFACTORISÉE
|
||||
"""
|
||||
if not self.cial:
|
||||
raise RuntimeError("Connexion Sage non établie")
|
||||
|
|
@ -6987,58 +6974,44 @@ class SageConnector:
|
|||
except Exception as e:
|
||||
raise ValueError(f"Client {numero} introuvable: {e}")
|
||||
|
||||
# Charger le contact via FactoryTiersContact
|
||||
# Charger le contact via SQL puis DossierContact
|
||||
logger.info("[2] Chargement du contact")
|
||||
|
||||
if not hasattr(client_obj, 'FactoryTiersContact'):
|
||||
raise RuntimeError("FactoryTiersContact non trouvee sur le client")
|
||||
|
||||
factory_contact = client_obj.FactoryTiersContact
|
||||
nom_recherche = None
|
||||
prenom_recherche = None
|
||||
|
||||
try:
|
||||
# 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:
|
||||
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 non trouvable via ReadNomPrenom")
|
||||
|
||||
contact = win32com.client.CastTo(persist, "IBOTiersContact3")
|
||||
contact.Read()
|
||||
logger.info(f" OK Contact charge: {contact.Nom}")
|
||||
# Récupérer nom/prénom via SQL
|
||||
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 FactoryDossierContact
|
||||
factory_dossier = self.cial.CptaApplication.FactoryDossierContact
|
||||
persist = factory_dossier.ReadNomPrenom(nom_recherche, prenom_recherche)
|
||||
|
||||
if not persist:
|
||||
raise ValueError(f"Contact non trouvable via ReadNomPrenom")
|
||||
|
||||
contact = win32com.client.CastTo(persist, "IBOTiersContact3")
|
||||
contact.Read()
|
||||
logger.info(f" OK Contact charge: {contact.Nom}")
|
||||
|
||||
# Appliquer les modifications
|
||||
logger.info("[3] Application des modifications")
|
||||
modifications_appliquees = []
|
||||
|
|
@ -7207,7 +7180,13 @@ class SageConnector:
|
|||
logger.info(f"[SUCCES] Contact modifie: CT_No={contact_numero}")
|
||||
logger.info("=" * 80)
|
||||
|
||||
contact_dict = self._contact_to_dict(contact)
|
||||
# Utiliser _contact_to_dict
|
||||
contact_dict = self._contact_to_dict(
|
||||
contact,
|
||||
numero_client=numero,
|
||||
contact_numero=contact_numero,
|
||||
n_contact=None
|
||||
)
|
||||
contact_dict["est_defaut"] = est_actuellement_defaut
|
||||
|
||||
return contact_dict
|
||||
|
|
@ -7218,12 +7197,12 @@ class SageConnector:
|
|||
except Exception as e:
|
||||
logger.error(f"[ERREUR] {e}", exc_info=True)
|
||||
raise RuntimeError(f"Erreur technique: {e}")
|
||||
|
||||
|
||||
|
||||
def definir_contact_defaut(self, numero: str, contact_numero: int) -> Dict:
|
||||
"""
|
||||
Définit un contact comme contact par défaut du client
|
||||
VERSION REFACTORISÉE
|
||||
VERSION COMPLÈTE REFACTORISÉE
|
||||
"""
|
||||
if not self.cial:
|
||||
raise RuntimeError("Connexion Sage non établie")
|
||||
|
|
@ -7325,7 +7304,7 @@ class SageConnector:
|
|||
except Exception as e:
|
||||
logger.error(f"[ERREUR] {e}", exc_info=True)
|
||||
raise RuntimeError(f"Erreur technique: {e}")
|
||||
|
||||
|
||||
|
||||
def lister_contacts(self, numero: str) -> List[Dict]:
|
||||
"""
|
||||
|
|
@ -7383,7 +7362,6 @@ class SageConnector:
|
|||
|
||||
try:
|
||||
with self._com_context(), self._lock_com:
|
||||
# Charger le client
|
||||
factory_client = self.cial.CptaApplication.FactoryClient
|
||||
persist_client = factory_client.ReadNumero(numero)
|
||||
|
||||
|
|
@ -7393,7 +7371,6 @@ class SageConnector:
|
|||
client = win32com.client.CastTo(persist_client, "IBOClient3")
|
||||
client.Read()
|
||||
|
||||
# Méthode 1: Via CT_NoContact (si disponible)
|
||||
ct_no_defaut = None
|
||||
try:
|
||||
ct_no_defaut = getattr(client, "CT_NoContact", None)
|
||||
|
|
@ -7402,7 +7379,6 @@ class SageConnector:
|
|||
except:
|
||||
pass
|
||||
|
||||
# Méthode 2: Via CT_Contact (nom)
|
||||
nom_contact_defaut = None
|
||||
try:
|
||||
nom_contact_defaut = getattr(client, "CT_Contact", None)
|
||||
|
|
@ -7411,11 +7387,9 @@ class SageConnector:
|
|||
except:
|
||||
pass
|
||||
|
||||
# Si on a le CT_No, on retourne le contact complet
|
||||
if ct_no_defaut:
|
||||
return self.obtenir_contact(numero, ct_no_defaut)
|
||||
|
||||
# Sinon, chercher par nom dans la liste des contacts
|
||||
if nom_contact_defaut:
|
||||
contacts = self.lister_contacts(numero)
|
||||
for contact in contacts:
|
||||
|
|
@ -7433,7 +7407,7 @@ class SageConnector:
|
|||
def supprimer_contact(self, numero: str, contact_numero: int) -> Dict:
|
||||
"""
|
||||
Supprime un contact via COM
|
||||
VERSION REFACTORISÉE
|
||||
VERSION COMPLÈTE REFACTORISÉE
|
||||
"""
|
||||
if not self.cial:
|
||||
raise RuntimeError("Connexion Sage non établie")
|
||||
|
|
@ -7521,15 +7495,19 @@ class SageConnector:
|
|||
except Exception as e:
|
||||
logger.error(f"[ERREUR] {e}", exc_info=True)
|
||||
raise RuntimeError(f"Erreur technique: {e}")
|
||||
|
||||
|
||||
def _contact_to_dict(self, contact) -> Dict:
|
||||
def _contact_to_dict(self, contact, numero_client=None, contact_numero=None, n_contact=None) -> Dict:
|
||||
"""
|
||||
Convertit un objet COM Contact (IBOTiersContact3) en dictionnaire
|
||||
VERSION REFACTORISÉE
|
||||
|
||||
Args:
|
||||
contact: Objet COM contact
|
||||
numero_client: Code du client (optionnel)
|
||||
contact_numero: CT_No du contact (optionnel)
|
||||
n_contact: N_Contact du contact (optionnel)
|
||||
"""
|
||||
try:
|
||||
# IBOTiersContact3 utilise Nom/Prenom (sans préfixe CT_)
|
||||
# Civilité
|
||||
civilite_code = getattr(contact, "Civilite", None)
|
||||
civilite_map = {0: "M.", 1: "Mme", 2: "Mlle", 3: "Société"}
|
||||
civilite = civilite_map.get(civilite_code) if civilite_code is not None else None
|
||||
|
|
@ -7550,19 +7528,10 @@ class SageConnector:
|
|||
except:
|
||||
pass
|
||||
|
||||
# Récupérer CT_No et N_Contact via SQL si possible
|
||||
# Car IBOTiersContact3 du DossierContact ne les a pas
|
||||
contact_numero = None
|
||||
n_contact = None
|
||||
numero = None
|
||||
|
||||
# Ces infos doivent venir de F_CONTACTT
|
||||
# On les passe plutôt en paramètre ou on les récupère différemment
|
||||
|
||||
return {
|
||||
"numero": numero, # À passer en paramètre
|
||||
"contact_numero": contact_numero, # À passer en paramètre
|
||||
"n_contact": n_contact, # À passer en paramètre
|
||||
"numero": numero_client,
|
||||
"contact_numero": contact_numero,
|
||||
"n_contact": n_contact or contact_numero,
|
||||
"civilite": civilite,
|
||||
"nom": self._safe_strip(getattr(contact, "Nom", None)),
|
||||
"prenom": self._safe_strip(getattr(contact, "Prenom", None)),
|
||||
|
|
@ -7579,7 +7548,8 @@ class SageConnector:
|
|||
except Exception as e:
|
||||
logger.warning(f"Erreur conversion contact: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
|
||||
def _row_to_contact_dict(self, row) -> Dict:
|
||||
"""Convertit une ligne SQL en dictionnaire contact"""
|
||||
civilite_code = row.CT_Civilite
|
||||
|
|
|
|||
Loading…
Reference in a new issue