feat: Add API endpoints and SageClient methods for managing prospects, suppliers, credit notes, and delivery notes.
This commit is contained in:
parent
a73bdc4d9e
commit
b4a76579b8
2 changed files with 288 additions and 127 deletions
245
api.py
245
api.py
|
|
@ -154,8 +154,10 @@ from datetime import datetime
|
||||||
# MODÈLES PYDANTIC POUR USERS
|
# MODÈLES PYDANTIC POUR USERS
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
||||||
|
|
||||||
class UserResponse(BaseModel):
|
class UserResponse(BaseModel):
|
||||||
"""Modèle de réponse pour un utilisateur"""
|
"""Modèle de réponse pour un utilisateur"""
|
||||||
|
|
||||||
id: str
|
id: str
|
||||||
email: str
|
email: str
|
||||||
nom: str
|
nom: str
|
||||||
|
|
@ -170,6 +172,7 @@ class UserResponse(BaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# SERVICES EXTERNES (Universign)
|
# SERVICES EXTERNES (Universign)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
@ -1583,13 +1586,132 @@ async def statut_queue():
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ENDPOINTS - PROSPECTS
|
||||||
|
# =====================================================
|
||||||
|
@app.get("/prospects", tags=["Prospects"])
|
||||||
|
async def rechercher_prospects(query: Optional[str] = Query(None)):
|
||||||
|
"""🔍 Recherche prospects via gateway Windows"""
|
||||||
|
try:
|
||||||
|
prospects = sage_client.lister_prospects(filtre=query or "")
|
||||||
|
return prospects
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur recherche prospects: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/prospects/{code}", tags=["Prospects"])
|
||||||
|
async def lire_prospect(code: str):
|
||||||
|
"""📄 Lecture d'un prospect par code"""
|
||||||
|
try:
|
||||||
|
prospect = sage_client.lire_prospect(code)
|
||||||
|
if not prospect:
|
||||||
|
raise HTTPException(404, f"Prospect {code} introuvable")
|
||||||
|
return prospect
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur lecture prospect: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ENDPOINTS - FOURNISSEURS
|
||||||
|
# =====================================================
|
||||||
|
@app.get("/fournisseurs", tags=["Fournisseurs"])
|
||||||
|
async def rechercher_fournisseurs(query: Optional[str] = Query(None)):
|
||||||
|
"""🔍 Recherche fournisseurs via gateway Windows"""
|
||||||
|
try:
|
||||||
|
fournisseurs = sage_client.lister_fournisseurs(filtre=query or "")
|
||||||
|
return fournisseurs
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur recherche fournisseurs: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/fournisseurs/{code}", tags=["Fournisseurs"])
|
||||||
|
async def lire_fournisseur(code: str):
|
||||||
|
"""📄 Lecture d'un fournisseur par code"""
|
||||||
|
try:
|
||||||
|
fournisseur = sage_client.lire_fournisseur(code)
|
||||||
|
if not fournisseur:
|
||||||
|
raise HTTPException(404, f"Fournisseur {code} introuvable")
|
||||||
|
return fournisseur
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur lecture fournisseur: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ENDPOINTS - AVOIRS
|
||||||
|
# =====================================================
|
||||||
|
@app.get("/avoirs", tags=["Avoirs"])
|
||||||
|
async def lister_avoirs(
|
||||||
|
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
||||||
|
):
|
||||||
|
"""📋 Liste tous les avoirs via gateway Windows"""
|
||||||
|
try:
|
||||||
|
avoirs = sage_client.lister_avoirs(limit=limit, statut=statut)
|
||||||
|
return avoirs
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur liste avoirs: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/avoirs/{numero}", tags=["Avoirs"])
|
||||||
|
async def lire_avoir(numero: str):
|
||||||
|
"""📄 Lecture d'un avoir avec ses lignes"""
|
||||||
|
try:
|
||||||
|
avoir = sage_client.lire_avoir(numero)
|
||||||
|
if not avoir:
|
||||||
|
raise HTTPException(404, f"Avoir {numero} introuvable")
|
||||||
|
return avoir
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur lecture avoir: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ENDPOINTS - LIVRAISONS
|
||||||
|
# =====================================================
|
||||||
|
@app.get("/livraisons", tags=["Livraisons"])
|
||||||
|
async def lister_livraisons(
|
||||||
|
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
||||||
|
):
|
||||||
|
"""📋 Liste tous les bons de livraison via gateway Windows"""
|
||||||
|
try:
|
||||||
|
livraisons = sage_client.lister_livraisons(limit=limit, statut=statut)
|
||||||
|
return livraisons
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur liste livraisons: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/livraisons/{numero}", tags=["Livraisons"])
|
||||||
|
async def lire_livraison(numero: str):
|
||||||
|
"""📄 Lecture d'une livraison avec ses lignes"""
|
||||||
|
try:
|
||||||
|
livraison = sage_client.lire_livraison(numero)
|
||||||
|
if not livraison:
|
||||||
|
raise HTTPException(404, f"Livraison {numero} introuvable")
|
||||||
|
return livraison
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur lecture livraison: {e}")
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/debug/users", response_model=List[UserResponse], tags=["Debug"])
|
@app.get("/debug/users", response_model=List[UserResponse], tags=["Debug"])
|
||||||
async def lister_utilisateurs_debug(
|
async def lister_utilisateurs_debug(
|
||||||
session: AsyncSession = Depends(get_session),
|
session: AsyncSession = Depends(get_session),
|
||||||
limit: int = Query(100, le=1000),
|
limit: int = Query(100, le=1000),
|
||||||
role: Optional[str] = Query(None),
|
role: Optional[str] = Query(None),
|
||||||
verified_only: bool = Query(False)
|
verified_only: bool = Query(False),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
🔓 **ROUTE DEBUG** - Liste tous les utilisateurs inscrits
|
🔓 **ROUTE DEBUG** - Liste tous les utilisateurs inscrits
|
||||||
|
|
@ -1629,20 +1751,24 @@ async def lister_utilisateurs_debug(
|
||||||
# Conversion en réponse
|
# Conversion en réponse
|
||||||
users_response = []
|
users_response = []
|
||||||
for user in users:
|
for user in users:
|
||||||
users_response.append(UserResponse(
|
users_response.append(
|
||||||
id=user.id,
|
UserResponse(
|
||||||
email=user.email,
|
id=user.id,
|
||||||
nom=user.nom,
|
email=user.email,
|
||||||
prenom=user.prenom,
|
nom=user.nom,
|
||||||
role=user.role,
|
prenom=user.prenom,
|
||||||
is_verified=user.is_verified,
|
role=user.role,
|
||||||
is_active=user.is_active,
|
is_verified=user.is_verified,
|
||||||
created_at=user.created_at.isoformat() if user.created_at else "",
|
is_active=user.is_active,
|
||||||
last_login=user.last_login.isoformat() if user.last_login else None,
|
created_at=user.created_at.isoformat() if user.created_at else "",
|
||||||
failed_login_attempts=user.failed_login_attempts or 0
|
last_login=user.last_login.isoformat() if user.last_login else None,
|
||||||
))
|
failed_login_attempts=user.failed_login_attempts or 0,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
logger.info(f"📋 Liste utilisateurs retournée: {len(users_response)} résultat(s)")
|
logger.info(
|
||||||
|
f"📋 Liste utilisateurs retournée: {len(users_response)} résultat(s)"
|
||||||
|
)
|
||||||
|
|
||||||
return users_response
|
return users_response
|
||||||
|
|
||||||
|
|
@ -1652,9 +1778,7 @@ async def lister_utilisateurs_debug(
|
||||||
|
|
||||||
|
|
||||||
@app.get("/debug/users/stats", tags=["Debug"])
|
@app.get("/debug/users/stats", tags=["Debug"])
|
||||||
async def statistiques_utilisateurs(
|
async def statistiques_utilisateurs(session: AsyncSession = Depends(get_session)):
|
||||||
session: AsyncSession = Depends(get_session)
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
📊 **ROUTE DEBUG** - Statistiques sur les utilisateurs
|
📊 **ROUTE DEBUG** - Statistiques sur les utilisateurs
|
||||||
|
|
||||||
|
|
@ -1690,7 +1814,7 @@ async def statistiques_utilisateurs(
|
||||||
"utilisateurs_actifs": active,
|
"utilisateurs_actifs": active,
|
||||||
"utilisateurs_non_verifies": total - verified,
|
"utilisateurs_non_verifies": total - verified,
|
||||||
"repartition_roles": roles_stats,
|
"repartition_roles": roles_stats,
|
||||||
"taux_verification": f"{(verified/total*100):.1f}%" if total > 0 else "0%"
|
"taux_verification": f"{(verified/total*100):.1f}%" if total > 0 else "0%",
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -1700,8 +1824,7 @@ async def statistiques_utilisateurs(
|
||||||
|
|
||||||
@app.get("/debug/users/{user_id}", response_model=UserResponse, tags=["Debug"])
|
@app.get("/debug/users/{user_id}", response_model=UserResponse, tags=["Debug"])
|
||||||
async def lire_utilisateur_debug(
|
async def lire_utilisateur_debug(
|
||||||
user_id: str,
|
user_id: str, session: AsyncSession = Depends(get_session)
|
||||||
session: AsyncSession = Depends(get_session)
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
👤 **ROUTE DEBUG** - Détails d'un utilisateur par ID
|
👤 **ROUTE DEBUG** - Détails d'un utilisateur par ID
|
||||||
|
|
@ -1729,7 +1852,7 @@ async def lire_utilisateur_debug(
|
||||||
is_active=user.is_active,
|
is_active=user.is_active,
|
||||||
created_at=user.created_at.isoformat() if user.created_at else "",
|
created_at=user.created_at.isoformat() if user.created_at else "",
|
||||||
last_login=user.last_login.isoformat() if user.last_login else None,
|
last_login=user.last_login.isoformat() if user.last_login else None,
|
||||||
failed_login_attempts=user.failed_login_attempts or 0
|
failed_login_attempts=user.failed_login_attempts or 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
|
|
@ -1739,8 +1862,6 @@ async def lire_utilisateur_debug(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
# À ajouter dans api.py dans la section Debug
|
|
||||||
|
|
||||||
@app.get("/debug/database/check", tags=["Debug"])
|
@app.get("/debug/database/check", tags=["Debug"])
|
||||||
async def verifier_integrite_database(session: AsyncSession = Depends(get_session)):
|
async def verifier_integrite_database(session: AsyncSession = Depends(get_session)):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1757,59 +1878,51 @@ async def verifier_integrite_database(session: AsyncSession = Depends(get_sessio
|
||||||
# === TABLE USERS ===
|
# === TABLE USERS ===
|
||||||
# Compter tous les users
|
# Compter tous les users
|
||||||
total_users = await session.execute(select(func.count(User.id)))
|
total_users = await session.execute(select(func.count(User.id)))
|
||||||
diagnostics["users"] = {
|
diagnostics["users"] = {"total": total_users.scalar(), "details": []}
|
||||||
"total": total_users.scalar(),
|
|
||||||
"details": []
|
|
||||||
}
|
|
||||||
|
|
||||||
# Lister tous les users avec détails
|
# Lister tous les users avec détails
|
||||||
all_users = await session.execute(select(User))
|
all_users = await session.execute(select(User))
|
||||||
users_list = all_users.scalars().all()
|
users_list = all_users.scalars().all()
|
||||||
|
|
||||||
for u in users_list:
|
for u in users_list:
|
||||||
diagnostics["users"]["details"].append({
|
diagnostics["users"]["details"].append(
|
||||||
"id": u.id,
|
{
|
||||||
"email": u.email,
|
"id": u.id,
|
||||||
"nom": f"{u.prenom} {u.nom}",
|
"email": u.email,
|
||||||
"role": u.role,
|
"nom": f"{u.prenom} {u.nom}",
|
||||||
"is_active": u.is_active,
|
"role": u.role,
|
||||||
"is_verified": u.is_verified,
|
"is_active": u.is_active,
|
||||||
"created_at": u.created_at.isoformat() if u.created_at else None,
|
"is_verified": u.is_verified,
|
||||||
"has_reset_token": u.reset_token is not None,
|
"created_at": u.created_at.isoformat() if u.created_at else None,
|
||||||
"has_verification_token": u.verification_token is not None,
|
"has_reset_token": u.reset_token is not None,
|
||||||
})
|
"has_verification_token": u.verification_token is not None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# === TABLE REFRESH_TOKENS ===
|
# === TABLE REFRESH_TOKENS ===
|
||||||
total_tokens = await session.execute(select(func.count(RefreshToken.id)))
|
total_tokens = await session.execute(select(func.count(RefreshToken.id)))
|
||||||
diagnostics["refresh_tokens"] = {
|
diagnostics["refresh_tokens"] = {"total": total_tokens.scalar()}
|
||||||
"total": total_tokens.scalar()
|
|
||||||
}
|
|
||||||
|
|
||||||
# === TABLE LOGIN_ATTEMPTS ===
|
# === TABLE LOGIN_ATTEMPTS ===
|
||||||
total_attempts = await session.execute(select(func.count(LoginAttempt.id)))
|
total_attempts = await session.execute(select(func.count(LoginAttempt.id)))
|
||||||
diagnostics["login_attempts"] = {
|
diagnostics["login_attempts"] = {"total": total_attempts.scalar()}
|
||||||
"total": total_attempts.scalar()
|
|
||||||
}
|
|
||||||
|
|
||||||
# === TABLE EMAIL_LOGS ===
|
# === TABLE EMAIL_LOGS ===
|
||||||
total_emails = await session.execute(select(func.count(EmailLog.id)))
|
total_emails = await session.execute(select(func.count(EmailLog.id)))
|
||||||
diagnostics["email_logs"] = {
|
diagnostics["email_logs"] = {"total": total_emails.scalar()}
|
||||||
"total": total_emails.scalar()
|
|
||||||
}
|
|
||||||
|
|
||||||
# === TABLE SIGNATURE_LOGS ===
|
# === TABLE SIGNATURE_LOGS ===
|
||||||
total_signatures = await session.execute(select(func.count(SignatureLog.id)))
|
total_signatures = await session.execute(select(func.count(SignatureLog.id)))
|
||||||
diagnostics["signature_logs"] = {
|
diagnostics["signature_logs"] = {"total": total_signatures.scalar()}
|
||||||
"total": total_signatures.scalar()
|
|
||||||
}
|
|
||||||
|
|
||||||
# === VÉRIFIER LES FICHIERS SQLITE ===
|
# === VÉRIFIER LES FICHIERS SQLITE ===
|
||||||
import os
|
import os
|
||||||
|
|
||||||
db_file = "sage_dataven.db"
|
db_file = "sage_dataven.db"
|
||||||
diagnostics["database_file"] = {
|
diagnostics["database_file"] = {
|
||||||
"exists": os.path.exists(db_file),
|
"exists": os.path.exists(db_file),
|
||||||
"size_bytes": os.path.getsize(db_file) if os.path.exists(db_file) else 0,
|
"size_bytes": os.path.getsize(db_file) if os.path.exists(db_file) else 0,
|
||||||
"path": os.path.abspath(db_file)
|
"path": os.path.abspath(db_file),
|
||||||
}
|
}
|
||||||
|
|
||||||
# === TESTER UNE REQUÊTE RAW SQL ===
|
# === TESTER UNE REQUÊTE RAW SQL ===
|
||||||
|
|
@ -1817,18 +1930,15 @@ async def verifier_integrite_database(session: AsyncSession = Depends(get_sessio
|
||||||
raw_count = await session.execute(text("SELECT COUNT(*) FROM users"))
|
raw_count = await session.execute(text("SELECT COUNT(*) FROM users"))
|
||||||
diagnostics["raw_sql_check"] = {
|
diagnostics["raw_sql_check"] = {
|
||||||
"users_count": raw_count.scalar(),
|
"users_count": raw_count.scalar(),
|
||||||
"status": "✅ Connexion DB OK"
|
"status": "✅ Connexion DB OK",
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
diagnostics["raw_sql_check"] = {
|
diagnostics["raw_sql_check"] = {"status": "❌ Erreur", "error": str(e)}
|
||||||
"status": "❌ Erreur",
|
|
||||||
"error": str(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"timestamp": datetime.now().isoformat(),
|
"timestamp": datetime.now().isoformat(),
|
||||||
"diagnostics": diagnostics
|
"diagnostics": diagnostics,
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -1860,7 +1970,7 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
role="user",
|
role="user",
|
||||||
is_verified=True,
|
is_verified=True,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
created_at=datetime.now()
|
created_at=datetime.now(),
|
||||||
)
|
)
|
||||||
|
|
||||||
session.add(test_user)
|
session.add(test_user)
|
||||||
|
|
@ -1871,16 +1981,14 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
logger.info(f"✅ ÉTAPE 1: User créé - {user_id}")
|
logger.info(f"✅ ÉTAPE 1: User créé - {user_id}")
|
||||||
|
|
||||||
# === ÉTAPE 2: LECTURE ===
|
# === ÉTAPE 2: LECTURE ===
|
||||||
result = await session.execute(
|
result = await session.execute(select(User).where(User.id == user_id))
|
||||||
select(User).where(User.id == user_id)
|
|
||||||
)
|
|
||||||
loaded_user = result.scalar_one_or_none()
|
loaded_user = result.scalar_one_or_none()
|
||||||
|
|
||||||
if not loaded_user:
|
if not loaded_user:
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": "❌ User introuvable après création !",
|
"error": "❌ User introuvable après création !",
|
||||||
"step": "LECTURE"
|
"step": "LECTURE",
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(f"✅ ÉTAPE 2: User chargé - {loaded_user.email}")
|
logger.info(f"✅ ÉTAPE 2: User chargé - {loaded_user.email}")
|
||||||
|
|
@ -1898,9 +2006,7 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
logger.info(f"✅ ÉTAPE 3: User modifié")
|
logger.info(f"✅ ÉTAPE 3: User modifié")
|
||||||
|
|
||||||
# === ÉTAPE 4: RE-LECTURE ===
|
# === ÉTAPE 4: RE-LECTURE ===
|
||||||
result2 = await session.execute(
|
result2 = await session.execute(select(User).where(User.id == user_id))
|
||||||
select(User).where(User.id == user_id)
|
|
||||||
)
|
|
||||||
reloaded_user = result2.scalar_one_or_none()
|
reloaded_user = result2.scalar_one_or_none()
|
||||||
|
|
||||||
if not reloaded_user:
|
if not reloaded_user:
|
||||||
|
|
@ -1908,7 +2014,7 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": "❌ User DISPARU après modification !",
|
"error": "❌ User DISPARU après modification !",
|
||||||
"step": "RE-LECTURE",
|
"step": "RE-LECTURE",
|
||||||
"user_id": user_id
|
"user_id": user_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(f"✅ ÉTAPE 4: User re-chargé - {reloaded_user.email}")
|
logger.info(f"✅ ÉTAPE 4: User re-chargé - {reloaded_user.email}")
|
||||||
|
|
@ -1929,8 +2035,8 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
"2. Lecture",
|
"2. Lecture",
|
||||||
"3. Modification (reset password simulé)",
|
"3. Modification (reset password simulé)",
|
||||||
"4. Re-lecture (vérification persistance)",
|
"4. Re-lecture (vérification persistance)",
|
||||||
"5. Suppression (cleanup)"
|
"5. Suppression (cleanup)",
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -1942,9 +2048,10 @@ async def tester_persistance_utilisateur(session: AsyncSession = Depends(get_ses
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": str(e),
|
"error": str(e),
|
||||||
"traceback": str(e.__class__.__name__)
|
"traceback": str(e.__class__.__name__),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# LANCEMENT
|
# LANCEMENT
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,60 @@ class SageGatewayClient:
|
||||||
logger.error(f"Erreur génération PDF: {e}")
|
logger.error(f"Erreur génération PDF: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# PROSPECTS
|
||||||
|
# =====================================================
|
||||||
|
def lister_prospects(self, filtre: str = "") -> List[Dict]:
|
||||||
|
"""Liste tous les prospects avec filtre optionnel"""
|
||||||
|
return self._post("/sage/prospects/list", {"filtre": filtre}).get("data", [])
|
||||||
|
|
||||||
|
def lire_prospect(self, code: str) -> Optional[Dict]:
|
||||||
|
"""Lecture d'un prospect par code"""
|
||||||
|
return self._post("/sage/prospects/get", {"code": code}).get("data")
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# FOURNISSEURS
|
||||||
|
# =====================================================
|
||||||
|
def lister_fournisseurs(self, filtre: str = "") -> List[Dict]:
|
||||||
|
"""Liste tous les fournisseurs avec filtre optionnel"""
|
||||||
|
return self._post("/sage/fournisseurs/list", {"filtre": filtre}).get("data", [])
|
||||||
|
|
||||||
|
def lire_fournisseur(self, code: str) -> Optional[Dict]:
|
||||||
|
"""Lecture d'un fournisseur par code"""
|
||||||
|
return self._post("/sage/fournisseurs/get", {"code": code}).get("data")
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# AVOIRS
|
||||||
|
# =====================================================
|
||||||
|
def lister_avoirs(
|
||||||
|
self, limit: int = 100, statut: Optional[int] = None
|
||||||
|
) -> List[Dict]:
|
||||||
|
"""Liste tous les avoirs"""
|
||||||
|
payload = {"limit": limit}
|
||||||
|
if statut is not None:
|
||||||
|
payload["statut"] = statut
|
||||||
|
return self._post("/sage/avoirs/list", payload).get("data", [])
|
||||||
|
|
||||||
|
def lire_avoir(self, numero: str) -> Optional[Dict]:
|
||||||
|
"""Lecture d'un avoir avec ses lignes"""
|
||||||
|
return self._post("/sage/avoirs/get", {"code": numero}).get("data")
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# LIVRAISONS
|
||||||
|
# =====================================================
|
||||||
|
def lister_livraisons(
|
||||||
|
self, limit: int = 100, statut: Optional[int] = None
|
||||||
|
) -> List[Dict]:
|
||||||
|
"""Liste tous les bons de livraison"""
|
||||||
|
payload = {"limit": limit}
|
||||||
|
if statut is not None:
|
||||||
|
payload["statut"] = statut
|
||||||
|
return self._post("/sage/livraisons/list", payload).get("data", [])
|
||||||
|
|
||||||
|
def lire_livraison(self, numero: str) -> Optional[Dict]:
|
||||||
|
"""Lecture d'une livraison avec ses lignes"""
|
||||||
|
return self._post("/sage/livraisons/get", {"code": numero}).get("data")
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# CACHE (ADMIN)
|
# CACHE (ADMIN)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue