validation method par SQL, dangereux actuellement mais "seem" functionnal
This commit is contained in:
parent
6b4b603aee
commit
5c80a5e912
1 changed files with 47 additions and 90 deletions
|
|
@ -293,113 +293,70 @@ def introspecter_validation(connector, numero_facture: str = None) -> Dict:
|
||||||
|
|
||||||
def valider_facture(connector, numero_facture: str) -> Dict:
|
def valider_facture(connector, numero_facture: str) -> Dict:
|
||||||
"""
|
"""
|
||||||
Valide via late binding forcé + invocation COM correcte
|
Valide une facture via SQL direct
|
||||||
|
⚠️ Contourne les règles métier Sage - à utiliser avec précaution
|
||||||
"""
|
"""
|
||||||
import win32com.client
|
logger.info(f"🔒 Validation facture {numero_facture} (SQL direct)")
|
||||||
import win32com.client.dynamic
|
|
||||||
import pythoncom
|
|
||||||
|
|
||||||
if not connector.cial:
|
# Vérifications préalables
|
||||||
raise RuntimeError("Connexion Sage non établie")
|
with connector._get_sql_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
logger.info(f"🔒 Validation facture {numero_facture} (v5)")
|
# Vérifier que la facture existe et peut être validée
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT DO_Valide, DO_Statut, DO_TotalTTC, DO_MontantRegle
|
||||||
|
FROM F_DOCENTETE
|
||||||
|
WHERE DO_Piece = ? AND DO_Type = 6
|
||||||
|
""",
|
||||||
|
(numero_facture,),
|
||||||
|
)
|
||||||
|
|
||||||
with connector._com_context(), connector._lock_com:
|
row = cursor.fetchone()
|
||||||
factory = connector.cial.FactoryDocumentVente
|
if not row:
|
||||||
|
|
||||||
if not factory.ExistPiece(60, numero_facture):
|
|
||||||
raise ValueError(f"Facture {numero_facture} introuvable")
|
raise ValueError(f"Facture {numero_facture} introuvable")
|
||||||
|
|
||||||
persist = factory.ReadPiece(60, numero_facture)
|
valide_avant, statut, total_ttc, montant_regle = row
|
||||||
doc = win32com.client.CastTo(persist, "IBODocumentVente3")
|
|
||||||
doc.Read()
|
|
||||||
|
|
||||||
# Lecture via getattr
|
if valide_avant == 1:
|
||||||
valide_avant = getattr(doc, "DO_Valide", None)
|
|
||||||
imprim_avant = getattr(doc, "DO_Imprim", None)
|
|
||||||
logger.info(f" Avant: DO_Imprim={imprim_avant}, DO_Valide={valide_avant}")
|
|
||||||
|
|
||||||
if valide_avant == True:
|
|
||||||
return {"numero_facture": numero_facture, "deja_valide": True}
|
return {"numero_facture": numero_facture, "deja_valide": True}
|
||||||
|
|
||||||
oleobj = doc._oleobj_
|
if statut == 6: # Annulé
|
||||||
|
raise ValueError("Facture annulée, validation impossible")
|
||||||
|
|
||||||
# Explorer les DISPID
|
# Valider via SQL
|
||||||
type_info = oleobj.GetTypeInfo()
|
cursor.execute(
|
||||||
type_attr = type_info.GetTypeAttr()
|
"""
|
||||||
|
UPDATE F_DOCENTETE
|
||||||
dispids = {}
|
SET DO_Valide = 1, DO_Imprim = 1
|
||||||
for i in range(type_attr.cFuncs):
|
WHERE DO_Piece = ? AND DO_Type = 6
|
||||||
func_desc = type_info.GetFuncDesc(i)
|
""",
|
||||||
names = type_info.GetNames(func_desc.memid)
|
(numero_facture,),
|
||||||
if names:
|
|
||||||
name = names[0]
|
|
||||||
if name in ("DO_Valide", "DO_Imprim"):
|
|
||||||
invkind = func_desc.invkind
|
|
||||||
logger.info(
|
|
||||||
f" {name}: memid={func_desc.memid}, invkind={invkind}, cParams={func_desc.cParamsOpt}"
|
|
||||||
)
|
)
|
||||||
dispids[name] = {
|
|
||||||
"memid": func_desc.memid,
|
|
||||||
"invkind": invkind,
|
|
||||||
"cParams": func_desc.cParamsOpt,
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(f" DISPIDs trouvés: {dispids}")
|
conn.commit()
|
||||||
|
|
||||||
errors = []
|
# Vérifier
|
||||||
|
cursor.execute(
|
||||||
# Méthode A: Invoke PROPERTYPUT
|
"""
|
||||||
if "DO_Valide" in dispids:
|
SELECT DO_Valide, DO_Imprim
|
||||||
memid = dispids["DO_Valide"]["memid"]
|
FROM F_DOCENTETE
|
||||||
try:
|
WHERE DO_Piece = ? AND DO_Type = 6
|
||||||
oleobj.Invoke(memid, 0, pythoncom.DISPATCH_PROPERTYPUT, False, True)
|
""",
|
||||||
doc.Write()
|
(numero_facture,),
|
||||||
logger.info(f" ✅ Méthode A: Invoke PROPERTYPUT OK")
|
|
||||||
except Exception as e:
|
|
||||||
errors.append(f"Invoke PROPERTYPUT: {e}")
|
|
||||||
logger.warning(f" Méthode A échouée: {e}")
|
|
||||||
|
|
||||||
# Méthode B: DumbDispatch
|
|
||||||
try:
|
|
||||||
raw_dispatch = win32com.client.dynamic.DumbDispatch(oleobj)
|
|
||||||
raw_dispatch.DO_Valide = True
|
|
||||||
doc.Write()
|
|
||||||
logger.info(f" ✅ Méthode B: DumbDispatch OK")
|
|
||||||
except Exception as e:
|
|
||||||
errors.append(f"DumbDispatch: {e}")
|
|
||||||
logger.warning(f" Méthode B échouée: {e}")
|
|
||||||
|
|
||||||
# Méthode C: Dispatch dynamique combiné
|
|
||||||
try:
|
|
||||||
if "DO_Valide" in dispids:
|
|
||||||
memid = dispids["DO_Valide"]["memid"]
|
|
||||||
oleobj.Invoke(
|
|
||||||
memid,
|
|
||||||
0,
|
|
||||||
pythoncom.DISPATCH_PROPERTYPUT | pythoncom.DISPATCH_METHOD,
|
|
||||||
False,
|
|
||||||
True,
|
|
||||||
)
|
)
|
||||||
doc.Write()
|
|
||||||
logger.info(f" ✅ Méthode C: Combined flags OK")
|
|
||||||
except Exception as e:
|
|
||||||
errors.append(f"Combined flags: {e}")
|
|
||||||
logger.warning(f" Méthode C échouée: {e}")
|
|
||||||
|
|
||||||
# Vérification
|
valide_apres, imprim_apres = cursor.fetchone()
|
||||||
doc.Read()
|
|
||||||
valide_apres = getattr(doc, "DO_Valide", None)
|
logger.info(f" SQL: DO_Valide={valide_apres}, DO_Imprim={imprim_apres}")
|
||||||
imprim_apres = getattr(doc, "DO_Imprim", None)
|
|
||||||
logger.info(f" Après: DO_Imprim={imprim_apres}, DO_Valide={valide_apres}")
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"numero_facture": numero_facture,
|
"numero_facture": numero_facture,
|
||||||
"avant": {"DO_Imprim": imprim_avant, "DO_Valide": valide_avant},
|
"methode": "SQL_DIRECT",
|
||||||
"apres": {"DO_Imprim": imprim_apres, "DO_Valide": valide_apres},
|
"DO_Valide": valide_apres == 1,
|
||||||
"dispids": dispids,
|
"DO_Imprim": imprim_apres == 1,
|
||||||
"errors": errors,
|
"success": valide_apres == 1,
|
||||||
"success": valide_apres == True,
|
"warning": "Validation SQL directe - règles métier Sage contournées",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue