feat(society): add logo support and preview endpoint

This commit is contained in:
Fanilo-Nantenaina 2026-01-14 15:20:16 +03:00
parent d5273a0786
commit 671d5bac15
2 changed files with 95 additions and 8 deletions

93
api.py
View file

@ -1,6 +1,6 @@
from fastapi import FastAPI, HTTPException, Path, Query, Depends, status, Body from fastapi import FastAPI, HTTPException, Path, Query, Depends, status, Body
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse, HTMLResponse, Response
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel, Field, EmailStr from pydantic import BaseModel, Field, EmailStr
from typing import List, Optional from typing import List, Optional
@ -2874,6 +2874,97 @@ async def obtenir_informations_societe():
raise HTTPException(500, str(e)) raise HTTPException(500, str(e))
@app.get("/societe/logo", tags=["Société"])
async def obtenir_logo_societe():
"""Retourne le logo en tant qu'image directe"""
try:
societe = sage_client.lire_informations_societe()
if not societe or not societe.get("logo_base64"):
raise HTTPException(404, "Logo introuvable")
import base64
image_data = base64.b64decode(societe["logo_base64"])
return Response(content=image_data, media_type=societe["logo_content_type"])
except HTTPException:
raise
except Exception as e:
logger.error(f"Erreur récupération logo: {e}")
raise HTTPException(500, str(e))
@app.get("/societe/preview", response_class=HTMLResponse, tags=["Société"])
async def preview_societe():
"""Page HTML pour visualiser les infos société avec logo"""
try:
societe = sage_client.lire_informations_societe()
if not societe:
return "<h1>Société introuvable</h1>"
logo_html = ""
if societe.get("logo_base64"):
logo_html = f'<img src="data:{societe["logo_content_type"]};base64,{societe["logo_base64"]}" style="max-width: 300px; border: 1px solid #ccc; padding: 10px;">'
else:
logo_html = "<p>Aucun logo disponible</p>"
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Informations Société</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; }}
.container {{ max-width: 800px; }}
.logo {{ margin: 20px 0; }}
.info {{ margin: 10px 0; }}
.label {{ font-weight: bold; }}
</style>
</head>
<body>
<div class="container">
<h1>Informations Société</h1>
<div class="logo">
<h2>Logo</h2>
{logo_html}
</div>
<div class="info">
<span class="label">Raison sociale:</span> {societe["raison_sociale"]}
</div>
<div class="info">
<span class="label">SIRET:</span> {societe["siret"] or "N/A"}
</div>
<div class="info">
<span class="label">Adresse:</span> {societe["adresse"] or "N/A"}
</div>
<div class="info">
<span class="label">Code postal:</span> {societe["code_postal"] or "N/A"}
</div>
<div class="info">
<span class="label">Ville:</span> {societe["ville"] or "N/A"}
</div>
<div class="info">
<span class="label">Email:</span> {societe["email"] or "N/A"}
</div>
<div class="info">
<span class="label">Téléphone:</span> {societe["telephone"] or "N/A"}
</div>
</div>
</body>
</html>
"""
return html
except Exception as e:
return f"<h1>Erreur</h1><p>{str(e)}</p>"
@app.get("/health", tags=["System"]) @app.get("/health", tags=["System"])
async def health_check( async def health_check(
sage: SageGatewayClient = Depends(get_sage_client_for_user), sage: SageGatewayClient = Depends(get_sage_client_for_user),

View file

@ -9,14 +9,12 @@ class ExerciceComptable(BaseModel):
class SocieteInfo(BaseModel): class SocieteInfo(BaseModel):
# Identification
raison_sociale: str raison_sociale: str
numero_dossier: str numero_dossier: str
siret: Optional[str] = None siret: Optional[str] = None
code_ape: Optional[str] = None code_ape: Optional[str] = None
numero_tva: Optional[str] = None numero_tva: Optional[str] = None
# Adresse
adresse: Optional[str] = None adresse: Optional[str] = None
complement_adresse: Optional[str] = None complement_adresse: Optional[str] = None
code_postal: Optional[str] = None code_postal: Optional[str] = None
@ -24,27 +22,25 @@ class SocieteInfo(BaseModel):
code_region: Optional[str] = None code_region: Optional[str] = None
pays: Optional[str] = None pays: Optional[str] = None
# Contacts
telephone: Optional[str] = None telephone: Optional[str] = None
telecopie: Optional[str] = None telecopie: Optional[str] = None
email: Optional[str] = None email: Optional[str] = None
email_societe: Optional[str] = None email_societe: Optional[str] = None
site_web: Optional[str] = None site_web: Optional[str] = None
# Informations juridiques
capital: float = 0.0 capital: float = 0.0
forme_juridique: Optional[str] = None forme_juridique: Optional[str] = None
# Exercices comptables
exercices: List[ExerciceComptable] = [] exercices: List[ExerciceComptable] = []
# Configuration
devise_compte: int = 0 devise_compte: int = 0
devise_equivalent: int = 0 devise_equivalent: int = 0
longueur_compte_general: int = 0 longueur_compte_general: int = 0
longueur_compte_analytique: int = 0 longueur_compte_analytique: int = 0
regime_fec: int = 0 regime_fec: int = 0
# Autres
base_modele: Optional[str] = None base_modele: Optional[str] = None
marqueur: int = 0 marqueur: int = 0
logo_base64: Optional[str] = None
logo_content_type: Optional[str] = None