style: Improve code readability and formatting in main.py by adding empty lines and trailing commas.

This commit is contained in:
Fanilo-Nantenaina 2025-12-08 17:59:18 +03:00
parent 51f49298c2
commit bf986bef5a
2 changed files with 1666 additions and 1137 deletions

190
main.py
View file

@ -89,11 +89,14 @@ class ClientCreateRequest(BaseModel):
siret: Optional[str] = None siret: Optional[str] = None
tva_intra: Optional[str] = None tva_intra: Optional[str] = None
class ClientUpdateGatewayRequest(BaseModel): class ClientUpdateGatewayRequest(BaseModel):
"""Modèle pour modification client côté gateway""" """Modèle pour modification client côté gateway"""
code: str code: str
client_data: Dict client_data: Dict
class FournisseurCreateRequest(BaseModel): class FournisseurCreateRequest(BaseModel):
intitule: str = Field(..., description="Raison sociale du fournisseur") intitule: str = Field(..., description="Raison sociale du fournisseur")
compte_collectif: str = Field("401000", description="Compte général rattaché") compte_collectif: str = Field("401000", description="Compte général rattaché")
@ -124,17 +127,21 @@ class FournisseurCreateRequest(BaseModel):
class FournisseurUpdateGatewayRequest(BaseModel): class FournisseurUpdateGatewayRequest(BaseModel):
"""Modèle pour modification fournisseur côté gateway""" """Modèle pour modification fournisseur côté gateway"""
code: str code: str
fournisseur_data: Dict fournisseur_data: Dict
class DevisUpdateGatewayRequest(BaseModel): class DevisUpdateGatewayRequest(BaseModel):
"""Modèle pour modification devis côté gateway""" """Modèle pour modification devis côté gateway"""
numero: str numero: str
devis_data: Dict devis_data: Dict
class CommandeCreateRequest(BaseModel): class CommandeCreateRequest(BaseModel):
"""Création d'une commande""" """Création d'une commande"""
client_id: str client_id: str
date_commande: Optional[date] = None date_commande: Optional[date] = None
reference: Optional[str] = None reference: Optional[str] = None
@ -143,11 +150,14 @@ class CommandeCreateRequest(BaseModel):
class CommandeUpdateGatewayRequest(BaseModel): class CommandeUpdateGatewayRequest(BaseModel):
"""Modèle pour modification commande côté gateway""" """Modèle pour modification commande côté gateway"""
numero: str numero: str
commande_data: Dict commande_data: Dict
class LivraisonCreateGatewayRequest(BaseModel): class LivraisonCreateGatewayRequest(BaseModel):
"""Création d'une livraison côté gateway""" """Création d'une livraison côté gateway"""
client_id: str client_id: str
date_livraison: Optional[date] = None date_livraison: Optional[date] = None
lignes: List[Dict] lignes: List[Dict]
@ -156,11 +166,14 @@ class LivraisonCreateGatewayRequest(BaseModel):
class LivraisonUpdateGatewayRequest(BaseModel): class LivraisonUpdateGatewayRequest(BaseModel):
"""Modèle pour modification livraison côté gateway""" """Modèle pour modification livraison côté gateway"""
numero: str numero: str
livraison_data: Dict livraison_data: Dict
class AvoirCreateGatewayRequest(BaseModel): class AvoirCreateGatewayRequest(BaseModel):
"""Création d'un avoir côté gateway""" """Création d'un avoir côté gateway"""
client_id: str client_id: str
date_avoir: Optional[date] = None date_avoir: Optional[date] = None
lignes: List[Dict] lignes: List[Dict]
@ -169,11 +182,14 @@ class AvoirCreateGatewayRequest(BaseModel):
class AvoirUpdateGatewayRequest(BaseModel): class AvoirUpdateGatewayRequest(BaseModel):
"""Modèle pour modification avoir côté gateway""" """Modèle pour modification avoir côté gateway"""
numero: str numero: str
avoir_data: Dict avoir_data: Dict
class FactureCreateGatewayRequest(BaseModel): class FactureCreateGatewayRequest(BaseModel):
"""Création d'une facture côté gateway""" """Création d'une facture côté gateway"""
client_id: str client_id: str
date_facture: Optional[date] = None date_facture: Optional[date] = None
lignes: List[Dict] lignes: List[Dict]
@ -182,14 +198,18 @@ class FactureCreateGatewayRequest(BaseModel):
class FactureUpdateGatewayRequest(BaseModel): class FactureUpdateGatewayRequest(BaseModel):
"""Modèle pour modification facture côté gateway""" """Modèle pour modification facture côté gateway"""
numero: str numero: str
facture_data: Dict facture_data: Dict
class PDFGenerationRequest(BaseModel): class PDFGenerationRequest(BaseModel):
"""Modèle pour génération PDF""" """Modèle pour génération PDF"""
doc_id: str = Field(..., description="Numéro du document") doc_id: str = Field(..., description="Numéro du document")
type_doc: int = Field(..., ge=0, le=60, description="Type de document Sage") type_doc: int = Field(..., ge=0, le=60, description="Type de document Sage")
# ===================================================== # =====================================================
# SÉCURITÉ # SÉCURITÉ
# ===================================================== # =====================================================
@ -283,6 +303,7 @@ def clients_list(req: FiltreRequest):
logger.error(f"Erreur liste clients: {e}") logger.error(f"Erreur liste clients: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/clients/update", dependencies=[Depends(verify_token)]) @app.post("/sage/clients/update", dependencies=[Depends(verify_token)])
def modifier_client_endpoint(req: ClientUpdateGatewayRequest): def modifier_client_endpoint(req: ClientUpdateGatewayRequest):
""" """
@ -291,7 +312,7 @@ def modifier_client_endpoint(req: ClientUpdateGatewayRequest):
try: try:
resultat = sage.modifier_client(req.code, req.client_data) resultat = sage.modifier_client(req.code, req.client_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification client: {e}") logger.warning(f"Erreur métier modification client: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
@ -299,6 +320,7 @@ def modifier_client_endpoint(req: ClientUpdateGatewayRequest):
logger.error(f"Erreur technique modification client: {e}") logger.error(f"Erreur technique modification client: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/clients/get", dependencies=[Depends(verify_token)]) @app.post("/sage/clients/get", dependencies=[Depends(verify_token)])
def client_get(req: CodeRequest): def client_get(req: CodeRequest):
"""Lecture d'un client par code""" """Lecture d'un client par code"""
@ -330,7 +352,8 @@ def create_client_endpoint(req: ClientCreateRequest):
logger.error(f"Erreur technique création client: {e}") logger.error(f"Erreur technique création client: {e}")
# Erreur technique (ex: COM) -> 500 Internal Server Error # Erreur technique (ex: COM) -> 500 Internal Server Error
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
# ===================================================== # =====================================================
# ENDPOINTS - ARTICLES # ENDPOINTS - ARTICLES
# ===================================================== # =====================================================
@ -385,7 +408,7 @@ def creer_devis(req: DevisRequest):
def lire_devis(req: CodeRequest): def lire_devis(req: CodeRequest):
""" """
📄 Lecture d'un devis AVEC ses lignes (lecture Sage directe) 📄 Lecture d'un devis AVEC ses lignes (lecture Sage directe)
Plus lent que /list car charge les lignes depuis Sage Plus lent que /list car charge les lignes depuis Sage
💡 Utiliser /list pour afficher une table rapide 💡 Utiliser /list pour afficher une table rapide
""" """
@ -406,33 +429,34 @@ def lire_devis(req: CodeRequest):
def devis_list( def devis_list(
limit: int = Query(100, description="Nombre max de devis"), limit: int = Query(100, description="Nombre max de devis"),
statut: Optional[int] = Query(None, description="Filtrer par statut"), statut: Optional[int] = Query(None, description="Filtrer par statut"),
filtre: str = Query("", description="Filtre texte (numero, client)") filtre: str = Query("", description="Filtre texte (numero, client)"),
): ):
""" """
📋 Liste rapide des devis depuis le CACHE (sans lignes) 📋 Liste rapide des devis depuis le CACHE (sans lignes)
ULTRA-RAPIDE: Utilise le cache mémoire au lieu de scanner Sage ULTRA-RAPIDE: Utilise le cache mémoire au lieu de scanner Sage
💡 Pour les détails avec lignes, utiliser GET /sage/devis/get 💡 Pour les détails avec lignes, utiliser GET /sage/devis/get
""" """
try: try:
# ✅ Récupération depuis le cache (instantané) # ✅ Récupération depuis le cache (instantané)
devis_list = sage.lister_tous_devis_cache(filtre) devis_list = sage.lister_tous_devis_cache(filtre)
# Filtrer par statut si demandé # Filtrer par statut si demandé
if statut is not None: if statut is not None:
devis_list = [d for d in devis_list if d.get("statut") == statut] devis_list = [d for d in devis_list if d.get("statut") == statut]
# Limiter le nombre de résultats # Limiter le nombre de résultats
devis_list = devis_list[:limit] devis_list = devis_list[:limit]
logger.info(f"{len(devis_list)} devis retournés depuis le cache") logger.info(f"{len(devis_list)} devis retournés depuis le cache")
return {"success": True, "data": devis_list} return {"success": True, "data": devis_list}
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur liste devis: {e}", exc_info=True) logger.error(f"❌ Erreur liste devis: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/devis/statut", dependencies=[Depends(verify_token)]) @app.post("/sage/devis/statut", dependencies=[Depends(verify_token)])
def changer_statut_devis_endpoint(numero: str, nouveau_statut: int): def changer_statut_devis_endpoint(numero: str, nouveau_statut: int):
"""Change le statut d'un devis""" """Change le statut d'un devis"""
@ -604,57 +628,59 @@ def contact_read(req: CodeRequest):
def commandes_list( def commandes_list(
limit: int = Query(100, description="Nombre max de commandes"), limit: int = Query(100, description="Nombre max de commandes"),
statut: Optional[int] = Query(None, description="Filtrer par statut"), statut: Optional[int] = Query(None, description="Filtrer par statut"),
filtre: str = Query("", description="Filtre texte") filtre: str = Query("", description="Filtre texte"),
): ):
""" """
📋 Liste rapide des commandes depuis le CACHE (sans lignes) 📋 Liste rapide des commandes depuis le CACHE (sans lignes)
ULTRA-RAPIDE: Utilise le cache mémoire ULTRA-RAPIDE: Utilise le cache mémoire
""" """
try: try:
commandes = sage.lister_toutes_commandes_cache(filtre) commandes = sage.lister_toutes_commandes_cache(filtre)
if statut is not None: if statut is not None:
commandes = [c for c in commandes if c.get("statut") == statut] commandes = [c for c in commandes if c.get("statut") == statut]
commandes = commandes[:limit] commandes = commandes[:limit]
logger.info(f"{len(commandes)} commandes retournées depuis le cache") logger.info(f"{len(commandes)} commandes retournées depuis le cache")
return {"success": True, "data": commandes} return {"success": True, "data": commandes}
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur liste commandes: {e}", exc_info=True) logger.error(f"❌ Erreur liste commandes: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/factures/list", dependencies=[Depends(verify_token)]) @app.post("/sage/factures/list", dependencies=[Depends(verify_token)])
def factures_list( def factures_list(
limit: int = Query(100, description="Nombre max de factures"), limit: int = Query(100, description="Nombre max de factures"),
statut: Optional[int] = Query(None, description="Filtrer par statut"), statut: Optional[int] = Query(None, description="Filtrer par statut"),
filtre: str = Query("", description="Filtre texte") filtre: str = Query("", description="Filtre texte"),
): ):
""" """
📋 Liste rapide des factures depuis le CACHE (sans lignes) 📋 Liste rapide des factures depuis le CACHE (sans lignes)
ULTRA-RAPIDE: Utilise le cache mémoire ULTRA-RAPIDE: Utilise le cache mémoire
💡 Pour les détails avec lignes, utiliser /sage/documents/get 💡 Pour les détails avec lignes, utiliser /sage/documents/get
""" """
try: try:
factures = sage.lister_toutes_factures_cache(filtre) factures = sage.lister_toutes_factures_cache(filtre)
if statut is not None: if statut is not None:
factures = [f for f in factures if f.get("statut") == statut] factures = [f for f in factures if f.get("statut") == statut]
factures = factures[:limit] factures = factures[:limit]
logger.info(f"{len(factures)} factures retournées depuis le cache") logger.info(f"{len(factures)} factures retournées depuis le cache")
return {"success": True, "data": factures} return {"success": True, "data": factures}
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur liste factures: {e}", exc_info=True) logger.error(f"❌ Erreur liste factures: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/client/remise-max", dependencies=[Depends(verify_token)]) @app.post("/sage/client/remise-max", dependencies=[Depends(verify_token)])
def lire_remise_max_client(code: str): def lire_remise_max_client(code: str):
"""Récupère la remise max autorisée pour un client""" """Récupère la remise max autorisée pour un client"""
@ -2370,50 +2396,49 @@ def prospect_get(req: CodeRequest):
def fournisseurs_list(req: FiltreRequest): def fournisseurs_list(req: FiltreRequest):
""" """
Liste rapide des fournisseurs depuis le CACHE Liste rapide des fournisseurs depuis le CACHE
Utilise le cache mémoire pour une réponse instantanée Utilise le cache mémoire pour une réponse instantanée
🔄 Cache actualisé automatiquement toutes les 15 minutes 🔄 Cache actualisé automatiquement toutes les 15 minutes
""" """
try: try:
# ✅ Utiliser le cache au lieu de la lecture directe # ✅ Utiliser le cache au lieu de la lecture directe
fournisseurs = sage.lister_tous_fournisseurs_cache(req.filtre) fournisseurs = sage.lister_tous_fournisseurs_cache(req.filtre)
logger.info(f"{len(fournisseurs)} fournisseurs retournés depuis le cache") logger.info(f"{len(fournisseurs)} fournisseurs retournés depuis le cache")
return {"success": True, "data": fournisseurs} return {"success": True, "data": fournisseurs}
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur liste fournisseurs: {e}", exc_info=True) logger.error(f"❌ Erreur liste fournisseurs: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/fournisseurs/create", dependencies=[Depends(verify_token)]) @app.post("/sage/fournisseurs/create", dependencies=[Depends(verify_token)])
def create_fournisseur_endpoint(req: FournisseurCreateRequest): def create_fournisseur_endpoint(req: FournisseurCreateRequest):
""" """
Création d'un fournisseur dans Sage Création d'un fournisseur dans Sage
Utilise FactoryFournisseur.Create() directement Utilise FactoryFournisseur.Create() directement
""" """
try: try:
# Appel au connecteur Sage # Appel au connecteur Sage
resultat = sage.creer_fournisseur(req.dict()) resultat = sage.creer_fournisseur(req.dict())
logger.info(f"✅ Fournisseur créé: {resultat.get('numero')}") logger.info(f"✅ Fournisseur créé: {resultat.get('numero')}")
return { return {"success": True, "data": resultat}
"success": True,
"data": resultat
}
except ValueError as e: except ValueError as e:
# Erreur métier (ex: doublon) # Erreur métier (ex: doublon)
logger.warning(f"⚠️ Erreur métier création fournisseur: {e}") logger.warning(f"⚠️ Erreur métier création fournisseur: {e}")
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
except Exception as e: except Exception as e:
# Erreur technique (ex: COM) # Erreur technique (ex: COM)
logger.error(f"❌ Erreur technique création fournisseur: {e}") logger.error(f"❌ Erreur technique création fournisseur: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/fournisseurs/update", dependencies=[Depends(verify_token)]) @app.post("/sage/fournisseurs/update", dependencies=[Depends(verify_token)])
def modifier_fournisseur_endpoint(req: FournisseurUpdateGatewayRequest): def modifier_fournisseur_endpoint(req: FournisseurUpdateGatewayRequest):
""" """
@ -2422,7 +2447,7 @@ def modifier_fournisseur_endpoint(req: FournisseurUpdateGatewayRequest):
try: try:
resultat = sage.modifier_fournisseur(req.code, req.fournisseur_data) resultat = sage.modifier_fournisseur(req.code, req.fournisseur_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification fournisseur: {e}") logger.warning(f"Erreur métier modification fournisseur: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
@ -2430,6 +2455,7 @@ def modifier_fournisseur_endpoint(req: FournisseurUpdateGatewayRequest):
logger.error(f"Erreur technique modification fournisseur: {e}") logger.error(f"Erreur technique modification fournisseur: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/fournisseurs/get", dependencies=[Depends(verify_token)]) @app.post("/sage/fournisseurs/get", dependencies=[Depends(verify_token)])
def fournisseur_get(req: CodeRequest): def fournisseur_get(req: CodeRequest):
""" """
@ -2504,11 +2530,12 @@ def livraison_get(req: CodeRequest):
logger.error(f"Erreur lecture livraison: {e}") logger.error(f"Erreur lecture livraison: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/devis/update", dependencies=[Depends(verify_token)]) @app.post("/sage/devis/update", dependencies=[Depends(verify_token)])
def modifier_devis_endpoint(req: DevisUpdateGatewayRequest): def modifier_devis_endpoint(req: DevisUpdateGatewayRequest):
""" """
Modification d'un devis dans Sage Modification d'un devis dans Sage
Permet de modifier: Permet de modifier:
- La date du devis - La date du devis
- Les lignes (remplace toutes les lignes) - Les lignes (remplace toutes les lignes)
@ -2517,7 +2544,7 @@ def modifier_devis_endpoint(req: DevisUpdateGatewayRequest):
try: try:
resultat = sage.modifier_devis(req.numero, req.devis_data) resultat = sage.modifier_devis(req.numero, req.devis_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification devis: {e}") logger.warning(f"Erreur métier modification devis: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
@ -2530,6 +2557,7 @@ def modifier_devis_endpoint(req: DevisUpdateGatewayRequest):
# ENDPOINTS - CRÉATION ET MODIFICATION COMMANDES # ENDPOINTS - CRÉATION ET MODIFICATION COMMANDES
# ===================================================== # =====================================================
@app.post("/sage/commandes/create", dependencies=[Depends(verify_token)]) @app.post("/sage/commandes/create", dependencies=[Depends(verify_token)])
def creer_commande_endpoint(req: CommandeCreateRequest): def creer_commande_endpoint(req: CommandeCreateRequest):
""" """
@ -2543,10 +2571,10 @@ def creer_commande_endpoint(req: CommandeCreateRequest):
"reference": req.reference, "reference": req.reference,
"lignes": req.lignes, "lignes": req.lignes,
} }
resultat = sage.creer_commande_enrichi(commande_data) resultat = sage.creer_commande_enrichi(commande_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier création commande: {e}") logger.warning(f"Erreur métier création commande: {e}")
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
@ -2559,7 +2587,7 @@ def creer_commande_endpoint(req: CommandeCreateRequest):
def modifier_commande_endpoint(req: CommandeUpdateGatewayRequest): def modifier_commande_endpoint(req: CommandeUpdateGatewayRequest):
""" """
Modification d'une commande dans Sage Modification d'une commande dans Sage
Permet de modifier: Permet de modifier:
- La date de la commande - La date de la commande
- Les lignes (remplace toutes les lignes) - Les lignes (remplace toutes les lignes)
@ -2569,7 +2597,7 @@ def modifier_commande_endpoint(req: CommandeUpdateGatewayRequest):
try: try:
resultat = sage.modifier_commande(req.numero, req.commande_data) resultat = sage.modifier_commande(req.numero, req.commande_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification commande: {e}") logger.warning(f"Erreur métier modification commande: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
@ -2588,7 +2616,7 @@ def creer_livraison_endpoint(req: LivraisonCreateGatewayRequest):
client = sage.lire_client(req.client_id) client = sage.lire_client(req.client_id)
if not client: if not client:
raise HTTPException(404, f"Client {req.client_id} introuvable") raise HTTPException(404, f"Client {req.client_id} introuvable")
# Préparer les données pour le connecteur # Préparer les données pour le connecteur
livraison_data = { livraison_data = {
"client": {"code": req.client_id, "intitule": ""}, "client": {"code": req.client_id, "intitule": ""},
@ -2596,10 +2624,10 @@ def creer_livraison_endpoint(req: LivraisonCreateGatewayRequest):
"reference": req.reference, "reference": req.reference,
"lignes": req.lignes, "lignes": req.lignes,
} }
resultat = sage.creer_livraison_enrichi(livraison_data) resultat = sage.creer_livraison_enrichi(livraison_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier création livraison: {e}") logger.warning(f"Erreur métier création livraison: {e}")
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
@ -2616,7 +2644,7 @@ def modifier_livraison_endpoint(req: LivraisonUpdateGatewayRequest):
try: try:
resultat = sage.modifier_livraison(req.numero, req.livraison_data) resultat = sage.modifier_livraison(req.numero, req.livraison_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification livraison: {e}") logger.warning(f"Erreur métier modification livraison: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
@ -2624,6 +2652,7 @@ def modifier_livraison_endpoint(req: LivraisonUpdateGatewayRequest):
logger.error(f"Erreur technique modification livraison: {e}") logger.error(f"Erreur technique modification livraison: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/avoirs/create", dependencies=[Depends(verify_token)]) @app.post("/sage/avoirs/create", dependencies=[Depends(verify_token)])
def creer_avoir_endpoint(req: AvoirCreateGatewayRequest): def creer_avoir_endpoint(req: AvoirCreateGatewayRequest):
""" """
@ -2634,7 +2663,7 @@ def creer_avoir_endpoint(req: AvoirCreateGatewayRequest):
client = sage.lire_client(req.client_id) client = sage.lire_client(req.client_id)
if not client: if not client:
raise HTTPException(404, f"Client {req.client_id} introuvable") raise HTTPException(404, f"Client {req.client_id} introuvable")
# Préparer les données pour le connecteur # Préparer les données pour le connecteur
avoir_data = { avoir_data = {
"client": {"code": req.client_id, "intitule": ""}, "client": {"code": req.client_id, "intitule": ""},
@ -2642,10 +2671,10 @@ def creer_avoir_endpoint(req: AvoirCreateGatewayRequest):
"reference": req.reference, "reference": req.reference,
"lignes": req.lignes, "lignes": req.lignes,
} }
resultat = sage.creer_avoir_enrichi(avoir_data) resultat = sage.creer_avoir_enrichi(avoir_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier création avoir: {e}") logger.warning(f"Erreur métier création avoir: {e}")
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
@ -2662,19 +2691,20 @@ def modifier_avoir_endpoint(req: AvoirUpdateGatewayRequest):
try: try:
resultat = sage.modifier_avoir(req.numero, req.avoir_data) resultat = sage.modifier_avoir(req.numero, req.avoir_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification avoir: {e}") logger.warning(f"Erreur métier modification avoir: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
except Exception as e: except Exception as e:
logger.error(f"Erreur technique modification avoir: {e}") logger.error(f"Erreur technique modification avoir: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/factures/create", dependencies=[Depends(verify_token)]) @app.post("/sage/factures/create", dependencies=[Depends(verify_token)])
def creer_facture_endpoint(req: FactureCreateGatewayRequest): def creer_facture_endpoint(req: FactureCreateGatewayRequest):
""" """
Création d'une facture dans Sage Création d'une facture dans Sage
NOTE: Les factures peuvent avoir des champs obligatoires supplémentaires NOTE: Les factures peuvent avoir des champs obligatoires supplémentaires
selon la configuration Sage (DO_CodeJournal, DO_Souche, etc.) selon la configuration Sage (DO_CodeJournal, DO_Souche, etc.)
""" """
@ -2683,7 +2713,7 @@ def creer_facture_endpoint(req: FactureCreateGatewayRequest):
client = sage.lire_client(req.client_id) client = sage.lire_client(req.client_id)
if not client: if not client:
raise HTTPException(404, f"Client {req.client_id} introuvable") raise HTTPException(404, f"Client {req.client_id} introuvable")
# Préparer les données pour le connecteur # Préparer les données pour le connecteur
facture_data = { facture_data = {
"client": {"code": req.client_id, "intitule": ""}, "client": {"code": req.client_id, "intitule": ""},
@ -2691,10 +2721,10 @@ def creer_facture_endpoint(req: FactureCreateGatewayRequest):
"reference": req.reference, "reference": req.reference,
"lignes": req.lignes, "lignes": req.lignes,
} }
resultat = sage.creer_facture_enrichi(facture_data) resultat = sage.creer_facture_enrichi(facture_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier création facture: {e}") logger.warning(f"Erreur métier création facture: {e}")
raise HTTPException(400, str(e)) raise HTTPException(400, str(e))
@ -2707,41 +2737,41 @@ def creer_facture_endpoint(req: FactureCreateGatewayRequest):
def modifier_facture_endpoint(req: FactureUpdateGatewayRequest): def modifier_facture_endpoint(req: FactureUpdateGatewayRequest):
""" """
Modification d'une facture dans Sage Modification d'une facture dans Sage
ATTENTION: Les factures comptabilisées peuvent être verrouillées ATTENTION: Les factures comptabilisées peuvent être verrouillées
""" """
try: try:
resultat = sage.modifier_facture(req.numero, req.facture_data) resultat = sage.modifier_facture(req.numero, req.facture_data)
return {"success": True, "data": resultat} return {"success": True, "data": resultat}
except ValueError as e: except ValueError as e:
logger.warning(f"Erreur métier modification facture: {e}") logger.warning(f"Erreur métier modification facture: {e}")
raise HTTPException(404, str(e)) raise HTTPException(404, str(e))
except Exception as e: except Exception as e:
logger.error(f"Erreur technique modification facture: {e}") logger.error(f"Erreur technique modification facture: {e}")
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.post("/sage/documents/generate-pdf", dependencies=[Depends(verify_token)]) @app.post("/sage/documents/generate-pdf", dependencies=[Depends(verify_token)])
def generer_pdf_document(req: PDFGenerationRequest): def generer_pdf_document(req: PDFGenerationRequest):
""" """
📄 Génération PDF d'un document (endpoint généralisé) 📄 Génération PDF d'un document (endpoint généralisé)
**Supporte tous les types de documents Sage:** **Supporte tous les types de documents Sage:**
- Devis (0) - Devis (0)
- Bons de commande (10) - Bons de commande (10)
- Bons de livraison (30) - Bons de livraison (30)
- Factures (60) - Factures (60)
- Avoirs (50) - Avoirs (50)
**Process:** **Process:**
1. Charge le document depuis Sage 1. Charge le document depuis Sage
2. Génère le PDF via l'état Sage correspondant 2. Génère le PDF via l'état Sage correspondant
3. Retourne le PDF en base64 3. Retourne le PDF en base64
Args: Args:
req: Requête contenant doc_id et type_doc req: Requête contenant doc_id et type_doc
Returns: Returns:
{ {
"success": true, "success": true,
@ -2755,35 +2785,37 @@ def generer_pdf_document(req: PDFGenerationRequest):
""" """
try: try:
logger.info(f"📄 Génération PDF: {req.doc_id} (type={req.type_doc})") logger.info(f"📄 Génération PDF: {req.doc_id} (type={req.type_doc})")
# Appel au connecteur Sage # Appel au connecteur Sage
pdf_bytes = sage.generer_pdf_document(req.doc_id, req.type_doc) pdf_bytes = sage.generer_pdf_document(req.doc_id, req.type_doc)
if not pdf_bytes: if not pdf_bytes:
raise HTTPException(500, "PDF vide généré") raise HTTPException(500, "PDF vide généré")
# Encoder en base64 pour le transport JSON # Encoder en base64 pour le transport JSON
import base64 import base64
pdf_base64 = base64.b64encode(pdf_bytes).decode('utf-8')
pdf_base64 = base64.b64encode(pdf_bytes).decode("utf-8")
logger.info(f"✅ PDF généré: {len(pdf_bytes)} octets") logger.info(f"✅ PDF généré: {len(pdf_bytes)} octets")
return { return {
"success": True, "success": True,
"data": { "data": {
"pdf_base64": pdf_base64, "pdf_base64": pdf_base64,
"taille_octets": len(pdf_bytes), "taille_octets": len(pdf_bytes),
"type_doc": req.type_doc, "type_doc": req.type_doc,
"numero": req.doc_id "numero": req.doc_id,
} },
} }
except HTTPException: except HTTPException:
raise raise
except Exception as e: except Exception as e:
logger.error(f"❌ Erreur génération PDF: {e}", exc_info=True) logger.error(f"❌ Erreur génération PDF: {e}", exc_info=True)
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
# ===================================================== # =====================================================
# LANCEMENT # LANCEMENT
# ===================================================== # =====================================================

File diff suppressed because it is too large Load diff