feat(api): add OpenAPI tags metadata and update endpoint tags
This commit is contained in:
parent
5a6a721f16
commit
fafd5222a6
1 changed files with 112 additions and 44 deletions
156
api.py
156
api.py
|
|
@ -42,6 +42,73 @@ from email_queue import email_queue
|
||||||
from sage_client import sage_client
|
from sage_client import sage_client
|
||||||
|
|
||||||
|
|
||||||
|
TAGS_METADATA = [
|
||||||
|
{
|
||||||
|
"name": "Clients",
|
||||||
|
"description": "Gestion des clients (recherche, création, modification)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Articles",
|
||||||
|
"description": "Gestion des articles et produits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Devis",
|
||||||
|
"description": "Création, consultation et gestion des devis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Commandes",
|
||||||
|
"description": "Création, consultation et gestion des commandes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Livraisons",
|
||||||
|
"description": "Création, consultation et gestion des bons de livraison"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Factures",
|
||||||
|
"description": "Création, consultation et gestion des factures"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Avoirs",
|
||||||
|
"description": "Création, consultation et gestion des avoirs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Fournisseurs",
|
||||||
|
"description": "Gestion des fournisseurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Prospects",
|
||||||
|
"description": "Gestion des prospects"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Workflows",
|
||||||
|
"description": "Transformations de documents (devis→commande, commande→facture, etc.)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Signatures",
|
||||||
|
"description": "Signature électronique via Universign"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Emails",
|
||||||
|
"description": "Envoi d'emails, templates et logs d'envoi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Validation",
|
||||||
|
"description": "Validation de données (remises, etc.)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Admin",
|
||||||
|
"description": "🔧 Administration système (cache, queue)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "System",
|
||||||
|
"description": "🏥 Health checks et informations système"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug",
|
||||||
|
"description": "🐛 Routes de debug et diagnostics"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# ENUMS
|
# ENUMS
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
@ -674,6 +741,7 @@ app = FastAPI(
|
||||||
version="2.0.0",
|
version="2.0.0",
|
||||||
description="API de gestion commerciale - VPS Linux",
|
description="API de gestion commerciale - VPS Linux",
|
||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
|
openapi_tags=TAGS_METADATA
|
||||||
)
|
)
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
|
|
@ -691,7 +759,7 @@ app.include_router(auth_router)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# ENDPOINTS - US-A1 (CRÉATION RAPIDE DEVIS)
|
# ENDPOINTS - US-A1 (CRÉATION RAPIDE DEVIS)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
@app.get("/clients", response_model=List[ClientResponse], tags=["US-A1"])
|
@app.get("/clients", response_model=List[ClientResponse], tags=["Clients"])
|
||||||
async def rechercher_clients(query: Optional[str] = Query(None)):
|
async def rechercher_clients(query: Optional[str] = Query(None)):
|
||||||
"""🔍 Recherche clients via gateway Windows"""
|
"""🔍 Recherche clients via gateway Windows"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -701,7 +769,7 @@ async def rechercher_clients(query: Optional[str] = Query(None)):
|
||||||
logger.error(f"Erreur recherche clients: {e}")
|
logger.error(f"Erreur recherche clients: {e}")
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
@app.get("/clients/{code}", tags=["US-A1"])
|
@app.get("/clients/{code}", tags=["Clients"])
|
||||||
async def lire_client_detail(code: str):
|
async def lire_client_detail(code: str):
|
||||||
"""
|
"""
|
||||||
📄 Lecture détaillée d'un client par son code
|
📄 Lecture détaillée d'un client par son code
|
||||||
|
|
@ -730,7 +798,7 @@ async def lire_client_detail(code: str):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/clients/{code}", tags=["US-A1"])
|
@app.put("/clients/{code}", tags=["Clients"])
|
||||||
async def modifier_client(
|
async def modifier_client(
|
||||||
code: str,
|
code: str,
|
||||||
client_update: ClientUpdateRequest,
|
client_update: ClientUpdateRequest,
|
||||||
|
|
@ -774,7 +842,7 @@ async def modifier_client(
|
||||||
logger.error(f"Erreur technique modification client {code}: {e}")
|
logger.error(f"Erreur technique modification client {code}: {e}")
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
@app.post("/clients", status_code=201, tags=["US-A8"])
|
@app.post("/clients", status_code=201, tags=["Clients"])
|
||||||
async def ajouter_client(
|
async def ajouter_client(
|
||||||
client: ClientCreateAPIRequest,
|
client: ClientCreateAPIRequest,
|
||||||
session: AsyncSession = Depends(get_session)
|
session: AsyncSession = Depends(get_session)
|
||||||
|
|
@ -799,7 +867,7 @@ async def ajouter_client(
|
||||||
status = 400 if "existe déjà" in str(e) else 500
|
status = 400 if "existe déjà" in str(e) else 500
|
||||||
raise HTTPException(status, str(e))
|
raise HTTPException(status, str(e))
|
||||||
|
|
||||||
@app.get("/articles", response_model=List[ArticleResponse], tags=["US-A1"])
|
@app.get("/articles", response_model=List[ArticleResponse], tags=["Articles"])
|
||||||
async def rechercher_articles(query: Optional[str] = Query(None)):
|
async def rechercher_articles(query: Optional[str] = Query(None)):
|
||||||
"""🔍 Recherche articles via gateway Windows"""
|
"""🔍 Recherche articles via gateway Windows"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -810,7 +878,7 @@ async def rechercher_articles(query: Optional[str] = Query(None)):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/devis", response_model=DevisResponse, status_code=201, tags=["US-A1"])
|
@app.post("/devis", response_model=DevisResponse, status_code=201, tags=["Devis"])
|
||||||
async def creer_devis(devis: DevisRequest):
|
async def creer_devis(devis: DevisRequest):
|
||||||
"""📝 Création de devis via gateway Windows"""
|
"""📝 Création de devis via gateway Windows"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -848,7 +916,7 @@ async def creer_devis(devis: DevisRequest):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/devis/{id}", tags=["US-A1"])
|
@app.put("/devis/{id}", tags=["Devis"])
|
||||||
async def modifier_devis(
|
async def modifier_devis(
|
||||||
id: str,
|
id: str,
|
||||||
devis_update: DevisUpdateRequest,
|
devis_update: DevisUpdateRequest,
|
||||||
|
|
@ -925,7 +993,7 @@ async def modifier_devis(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/commandes", status_code=201, tags=["US-A2"])
|
@app.post("/commandes", status_code=201, tags=["Commandes"])
|
||||||
async def creer_commande(
|
async def creer_commande(
|
||||||
commande: CommandeCreateRequest,
|
commande: CommandeCreateRequest,
|
||||||
session: AsyncSession = Depends(get_session)
|
session: AsyncSession = Depends(get_session)
|
||||||
|
|
@ -1003,7 +1071,7 @@ async def creer_commande(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/commandes/{id}", tags=["US-A2"])
|
@app.put("/commandes/{id}", tags=["Commandes"])
|
||||||
async def modifier_commande(
|
async def modifier_commande(
|
||||||
id: str,
|
id: str,
|
||||||
commande_update: CommandeUpdateRequest,
|
commande_update: CommandeUpdateRequest,
|
||||||
|
|
@ -1098,7 +1166,7 @@ async def modifier_commande(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/devis", tags=["US-A1"])
|
@app.get("/devis", tags=["Devis"])
|
||||||
async def lister_devis(
|
async def lister_devis(
|
||||||
limit: int = Query(100, le=1000),
|
limit: int = Query(100, le=1000),
|
||||||
statut: Optional[int] = Query(None),
|
statut: Optional[int] = Query(None),
|
||||||
|
|
@ -1127,7 +1195,7 @@ async def lister_devis(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/devis/{id}", tags=["US-A1"])
|
@app.get("/devis/{id}", tags=["Devis"])
|
||||||
async def lire_devis(id: str):
|
async def lire_devis(id: str):
|
||||||
"""
|
"""
|
||||||
📄 Lecture d'un devis via gateway Windows
|
📄 Lecture d'un devis via gateway Windows
|
||||||
|
|
@ -1167,7 +1235,7 @@ async def lire_devis(id: str):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/devis/{id}/pdf", tags=["US-A1"])
|
@app.get("/devis/{id}/pdf", tags=["Devis"])
|
||||||
async def telecharger_devis_pdf(id: str):
|
async def telecharger_devis_pdf(id: str):
|
||||||
"""📄 Téléchargement PDF (généré via email_queue)"""
|
"""📄 Téléchargement PDF (généré via email_queue)"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -1185,7 +1253,7 @@ async def telecharger_devis_pdf(id: str):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/devis/{id}/envoyer", tags=["US-A1"])
|
@app.post("/devis/{id}/envoyer", tags=["Devis"])
|
||||||
async def envoyer_devis_email(
|
async def envoyer_devis_email(
|
||||||
id: str, request: EmailEnvoiRequest, session: AsyncSession = Depends(get_session)
|
id: str, request: EmailEnvoiRequest, session: AsyncSession = Depends(get_session)
|
||||||
):
|
):
|
||||||
|
|
@ -1239,7 +1307,7 @@ async def envoyer_devis_email(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/devis/{id}/statut", tags=["US-A1"])
|
@app.put("/devis/{id}/statut", tags=["Devis"])
|
||||||
async def changer_statut_devis(
|
async def changer_statut_devis(
|
||||||
id: str,
|
id: str,
|
||||||
nouveau_statut: int = Query(..., ge=0, le=6, description="0=Brouillon, 2=Accepté, 5=Transformé, 6=Annulé")
|
nouveau_statut: int = Query(..., ge=0, le=6, description="0=Brouillon, 2=Accepté, 5=Transformé, 6=Annulé")
|
||||||
|
|
@ -1305,10 +1373,10 @@ async def changer_statut_devis(
|
||||||
|
|
||||||
|
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# ENDPOINTS - US-A2 (WORKFLOW SANS RESSAISIE)
|
# ENDPOINTS - Commandes (WORKFLOW SANS RESSAISIE)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
||||||
@app.get("/commandes/{id}", tags=["US-A2"])
|
@app.get("/commandes/{id}", tags=["Commandes"])
|
||||||
async def lire_commande(id: str):
|
async def lire_commande(id: str):
|
||||||
"""📄 Lecture d'une commande avec ses lignes"""
|
"""📄 Lecture d'une commande avec ses lignes"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -1323,7 +1391,7 @@ async def lire_commande(id: str):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/commandes", tags=["US-A2"])
|
@app.get("/commandes", tags=["Commandes"])
|
||||||
async def lister_commandes(
|
async def lister_commandes(
|
||||||
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
||||||
):
|
):
|
||||||
|
|
@ -1397,7 +1465,7 @@ async def devis_vers_commande(id: str, session: AsyncSession = Depends(get_sessi
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/workflow/commande/{id}/to-facture", tags=["US-A2"])
|
@app.post("/workflow/commande/{id}/to-facture", tags=["Commandes"])
|
||||||
async def commande_vers_facture(id: str, session: AsyncSession = Depends(get_session)):
|
async def commande_vers_facture(id: str, session: AsyncSession = Depends(get_session)):
|
||||||
"""
|
"""
|
||||||
🔧 Transformation Commande → Facture
|
🔧 Transformation Commande → Facture
|
||||||
|
|
@ -1443,7 +1511,7 @@ async def commande_vers_facture(id: str, session: AsyncSession = Depends(get_ses
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# ENDPOINTS - US-A3 (SIGNATURE ÉLECTRONIQUE)
|
# ENDPOINTS - US-A3 (SIGNATURE ÉLECTRONIQUE)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
@app.post("/signature/universign/send", tags=["US-A3"])
|
@app.post("/signature/universign/send", tags=["Universign"])
|
||||||
async def envoyer_signature(
|
async def envoyer_signature(
|
||||||
demande: SignatureRequest, session: AsyncSession = Depends(get_session)
|
demande: SignatureRequest, session: AsyncSession = Depends(get_session)
|
||||||
):
|
):
|
||||||
|
|
@ -1496,7 +1564,7 @@ async def envoyer_signature(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/signature/universign/status", tags=["US-A3"])
|
@app.get("/signature/universign/status", tags=["Universign"])
|
||||||
async def statut_signature(docId: str = Query(...)):
|
async def statut_signature(docId: str = Query(...)):
|
||||||
"""🔍 Récupération du statut de signature en temps réel"""
|
"""🔍 Récupération du statut de signature en temps réel"""
|
||||||
# Chercher dans la DB locale
|
# Chercher dans la DB locale
|
||||||
|
|
@ -1524,7 +1592,7 @@ async def statut_signature(docId: str = Query(...)):
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/signatures", tags=["US-A3"])
|
@app.get("/signatures", tags=["Universign"])
|
||||||
async def lister_signatures(
|
async def lister_signatures(
|
||||||
statut: Optional[StatutSignature] = Query(None),
|
statut: Optional[StatutSignature] = Query(None),
|
||||||
limit: int = Query(100, le=1000),
|
limit: int = Query(100, le=1000),
|
||||||
|
|
@ -1562,7 +1630,7 @@ async def lister_signatures(
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@app.get("/signatures/{transaction_id}/status", tags=["US-A3"])
|
@app.get("/signatures/{transaction_id}/status", tags=["Universign"])
|
||||||
async def statut_signature_detail(
|
async def statut_signature_detail(
|
||||||
transaction_id: str, session: AsyncSession = Depends(get_session)
|
transaction_id: str, session: AsyncSession = Depends(get_session)
|
||||||
):
|
):
|
||||||
|
|
@ -1616,7 +1684,7 @@ async def statut_signature_detail(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/signatures/refresh-all", tags=["US-A3"])
|
@app.post("/signatures/refresh-all", tags=["Universign"])
|
||||||
async def rafraichir_statuts_signatures(session: AsyncSession = Depends(get_session)):
|
async def rafraichir_statuts_signatures(session: AsyncSession = Depends(get_session)):
|
||||||
"""🔄 Rafraîchit TOUS les statuts des signatures en attente"""
|
"""🔄 Rafraîchit TOUS les statuts des signatures en attente"""
|
||||||
query = select(SignatureLog).where(
|
query = select(SignatureLog).where(
|
||||||
|
|
@ -1665,7 +1733,7 @@ async def rafraichir_statuts_signatures(session: AsyncSession = Depends(get_sess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/devis/{id}/signer", tags=["US-A3"])
|
@app.post("/devis/{id}/signer", tags=["Devis"])
|
||||||
async def envoyer_devis_signature(
|
async def envoyer_devis_signature(
|
||||||
id: str, request: SignatureRequest, session: AsyncSession = Depends(get_session)
|
id: str, request: SignatureRequest, session: AsyncSession = Depends(get_session)
|
||||||
):
|
):
|
||||||
|
|
@ -1788,7 +1856,7 @@ async def envoyer_emails_lot(
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
||||||
|
|
||||||
@app.post("/devis/valider-remise", response_model=BaremeRemiseResponse, tags=["US-A5"])
|
@app.post("/devis/valider-remise", response_model=BaremeRemiseResponse, tags=["Devis"])
|
||||||
async def valider_remise(
|
async def valider_remise(
|
||||||
client_id: str = Query(..., min_length=1),
|
client_id: str = Query(..., min_length=1),
|
||||||
remise_pourcentage: float = Query(0.0, ge=0, le=100),
|
remise_pourcentage: float = Query(0.0, ge=0, le=100),
|
||||||
|
|
@ -1826,7 +1894,7 @@ async def valider_remise(
|
||||||
# =====================================================
|
# =====================================================
|
||||||
# ENDPOINTS - US-A6 (RELANCE DEVIS)
|
# ENDPOINTS - US-A6 (RELANCE DEVIS)
|
||||||
# =====================================================
|
# =====================================================
|
||||||
@app.post("/devis/{id}/relancer-signature", tags=["US-A6"])
|
@app.post("/devis/{id}/relancer-signature", tags=["Devis"])
|
||||||
async def relancer_devis_signature(
|
async def relancer_devis_signature(
|
||||||
id: str, relance: RelanceDevisRequest, session: AsyncSession = Depends(get_session)
|
id: str, relance: RelanceDevisRequest, session: AsyncSession = Depends(get_session)
|
||||||
):
|
):
|
||||||
|
|
@ -1897,7 +1965,7 @@ class ContactClientResponse(BaseModel):
|
||||||
peut_etre_relance: bool
|
peut_etre_relance: bool
|
||||||
|
|
||||||
|
|
||||||
@app.get("/devis/{id}/contact", response_model=ContactClientResponse, tags=["US-A6"])
|
@app.get("/devis/{id}/contact", response_model=ContactClientResponse, tags=["Devis"])
|
||||||
async def recuperer_contact_devis(id: str):
|
async def recuperer_contact_devis(id: str):
|
||||||
"""👤 US-A6: Récupération du contact client associé au devis"""
|
"""👤 US-A6: Récupération du contact client associé au devis"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -1928,7 +1996,7 @@ async def recuperer_contact_devis(id: str):
|
||||||
# =====================================================
|
# =====================================================
|
||||||
|
|
||||||
|
|
||||||
@app.get("/factures", tags=["US-A7"])
|
@app.get("/factures", tags=["Factures"])
|
||||||
async def lister_factures(
|
async def lister_factures(
|
||||||
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
limit: int = Query(100, le=1000), statut: Optional[int] = Query(None)
|
||||||
):
|
):
|
||||||
|
|
@ -1947,7 +2015,7 @@ async def lister_factures(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/factures/{numero}", tags=["US-A7"])
|
@app.get("/factures/{numero}", tags=["Factures"])
|
||||||
async def lire_facture_detail(numero: str):
|
async def lire_facture_detail(numero: str):
|
||||||
"""
|
"""
|
||||||
📄 Lecture détaillée d'une facture avec ses lignes
|
📄 Lecture détaillée d'une facture avec ses lignes
|
||||||
|
|
@ -1979,7 +2047,7 @@ class RelanceFactureRequest(BaseModel):
|
||||||
doc_id: str
|
doc_id: str
|
||||||
message_personnalise: Optional[str] = None
|
message_personnalise: Optional[str] = None
|
||||||
|
|
||||||
@app.post("/factures", status_code=201, tags=["US-A7"])
|
@app.post("/factures", status_code=201, tags=["Factures"])
|
||||||
async def creer_facture(
|
async def creer_facture(
|
||||||
facture: FactureCreateRequest,
|
facture: FactureCreateRequest,
|
||||||
session: AsyncSession = Depends(get_session)
|
session: AsyncSession = Depends(get_session)
|
||||||
|
|
@ -2062,7 +2130,7 @@ async def creer_facture(
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/factures/{id}", tags=["US-A7"])
|
@app.put("/factures/{id}", tags=["Factures"])
|
||||||
async def modifier_facture(
|
async def modifier_facture(
|
||||||
id: str,
|
id: str,
|
||||||
facture_update: FactureUpdateRequest,
|
facture_update: FactureUpdateRequest,
|
||||||
|
|
@ -2183,7 +2251,7 @@ templates_email_db = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/factures/{id}/relancer", tags=["US-A7"])
|
@app.post("/factures/{id}/relancer", tags=["Factures"])
|
||||||
async def relancer_facture(
|
async def relancer_facture(
|
||||||
id: str,
|
id: str,
|
||||||
relance: RelanceFactureRequest,
|
relance: RelanceFactureRequest,
|
||||||
|
|
@ -2263,7 +2331,7 @@ async def relancer_facture(
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
|
|
||||||
@app.get("/emails/logs", tags=["US-A9"])
|
@app.get("/emails/logs", tags=["Emails"])
|
||||||
async def journal_emails(
|
async def journal_emails(
|
||||||
statut: Optional[StatutEmail] = Query(None),
|
statut: Optional[StatutEmail] = Query(None),
|
||||||
destinataire: Optional[str] = Query(None),
|
destinataire: Optional[str] = Query(None),
|
||||||
|
|
@ -2300,7 +2368,7 @@ async def journal_emails(
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@app.get("/emails/logs/export", tags=["US-A9"])
|
@app.get("/emails/logs/export", tags=["Emails"])
|
||||||
async def exporter_logs_csv(
|
async def exporter_logs_csv(
|
||||||
statut: Optional[StatutEmail] = Query(None),
|
statut: Optional[StatutEmail] = Query(None),
|
||||||
session: AsyncSession = Depends(get_session),
|
session: AsyncSession = Depends(get_session),
|
||||||
|
|
@ -2362,7 +2430,7 @@ async def exporter_logs_csv(
|
||||||
|
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# US-A10 - MODÈLES D'E-MAILS
|
# Devis0 - MODÈLES D'E-MAILS
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2380,14 +2448,14 @@ class TemplatePreviewRequest(BaseModel):
|
||||||
type_document: TypeDocument
|
type_document: TypeDocument
|
||||||
|
|
||||||
|
|
||||||
@app.get("/templates/emails", response_model=List[TemplateEmail], tags=["US-A10"])
|
@app.get("/templates/emails", response_model=List[TemplateEmail], tags=["Emails"])
|
||||||
async def lister_templates():
|
async def lister_templates():
|
||||||
"""📧 US-A10: Liste tous les templates d'emails"""
|
"""📧 Emails: Liste tous les templates d'emails"""
|
||||||
return [TemplateEmail(**template) for template in templates_email_db.values()]
|
return [TemplateEmail(**template) for template in templates_email_db.values()]
|
||||||
|
|
||||||
|
|
||||||
@app.get(
|
@app.get(
|
||||||
"/templates/emails/{template_id}", response_model=TemplateEmail, tags=["US-A10"]
|
"/templates/emails/{template_id}", response_model=TemplateEmail, tags=["Emails"]
|
||||||
)
|
)
|
||||||
async def lire_template(template_id: str):
|
async def lire_template(template_id: str):
|
||||||
"""📖 Lecture d'un template par ID"""
|
"""📖 Lecture d'un template par ID"""
|
||||||
|
|
@ -2397,7 +2465,7 @@ async def lire_template(template_id: str):
|
||||||
return TemplateEmail(**templates_email_db[template_id])
|
return TemplateEmail(**templates_email_db[template_id])
|
||||||
|
|
||||||
|
|
||||||
@app.post("/templates/emails", response_model=TemplateEmail, tags=["US-A10"])
|
@app.post("/templates/emails", response_model=TemplateEmail, tags=["Emails"])
|
||||||
async def creer_template(template: TemplateEmail):
|
async def creer_template(template: TemplateEmail):
|
||||||
"""➕ Création d'un nouveau template"""
|
"""➕ Création d'un nouveau template"""
|
||||||
template_id = str(uuid.uuid4())
|
template_id = str(uuid.uuid4())
|
||||||
|
|
@ -2416,7 +2484,7 @@ async def creer_template(template: TemplateEmail):
|
||||||
|
|
||||||
|
|
||||||
@app.put(
|
@app.put(
|
||||||
"/templates/emails/{template_id}", response_model=TemplateEmail, tags=["US-A10"]
|
"/templates/emails/{template_id}", response_model=TemplateEmail, tags=["Emails"]
|
||||||
)
|
)
|
||||||
async def modifier_template(template_id: str, template: TemplateEmail):
|
async def modifier_template(template_id: str, template: TemplateEmail):
|
||||||
"""✏️ Modification d'un template existant"""
|
"""✏️ Modification d'un template existant"""
|
||||||
|
|
@ -2440,7 +2508,7 @@ async def modifier_template(template_id: str, template: TemplateEmail):
|
||||||
return TemplateEmail(id=template_id, **template.dict())
|
return TemplateEmail(id=template_id, **template.dict())
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/templates/emails/{template_id}", tags=["US-A10"])
|
@app.delete("/templates/emails/{template_id}", tags=["Emails"])
|
||||||
async def supprimer_template(template_id: str):
|
async def supprimer_template(template_id: str):
|
||||||
"""🗑️ Suppression d'un template"""
|
"""🗑️ Suppression d'un template"""
|
||||||
if template_id not in templates_email_db:
|
if template_id not in templates_email_db:
|
||||||
|
|
@ -2456,7 +2524,7 @@ async def supprimer_template(template_id: str):
|
||||||
return {"success": True, "message": f"Template {template_id} supprimé"}
|
return {"success": True, "message": f"Template {template_id} supprimé"}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/templates/emails/preview", tags=["US-A10"])
|
@app.post("/templates/emails/preview", tags=["Emails"])
|
||||||
async def previsualiser_email(preview: TemplatePreviewRequest):
|
async def previsualiser_email(preview: TemplatePreviewRequest):
|
||||||
"""👁️ US-A10: Prévisualisation email avec fusion variables"""
|
"""👁️ US-A10: Prévisualisation email avec fusion variables"""
|
||||||
if preview.template_id not in templates_email_db:
|
if preview.template_id not in templates_email_db:
|
||||||
|
|
@ -3170,7 +3238,7 @@ async def livraison_vers_facture(id: str, session: AsyncSession = Depends(get_se
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/workflow/devis/{id}/to-facture", tags=["US-A2"])
|
@app.post("/workflow/devis/{id}/to-facture", tags=["Devis"])
|
||||||
async def devis_vers_facture_direct(id: str, session: AsyncSession = Depends(get_session)):
|
async def devis_vers_facture_direct(id: str, session: AsyncSession = Depends(get_session)):
|
||||||
"""
|
"""
|
||||||
🔧 Transformation Devis → Facture (DIRECT, sans commande)
|
🔧 Transformation Devis → Facture (DIRECT, sans commande)
|
||||||
|
|
@ -3257,7 +3325,7 @@ async def devis_vers_facture_direct(id: str, session: AsyncSession = Depends(get
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/workflow/commande/{id}/to-livraison", tags=["US-A2"])
|
@app.post("/workflow/commande/{id}/to-livraison", tags=["Commandes"])
|
||||||
async def commande_vers_livraison(id: str, session: AsyncSession = Depends(get_session)):
|
async def commande_vers_livraison(id: str, session: AsyncSession = Depends(get_session)):
|
||||||
"""
|
"""
|
||||||
🔧 Transformation Commande → Bon de livraison
|
🔧 Transformation Commande → Bon de livraison
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue