Added collaborator

This commit is contained in:
Fanilo-Nantenaina 2026-01-05 18:19:11 +03:00
parent 8850c7c266
commit c97db9b058
4 changed files with 233 additions and 0 deletions

94
api.py
View file

@ -71,6 +71,12 @@ from schemas import (
ContactCreate,
ContactUpdate,
)
from schemas.tiers.commercial import (
CollaborateurCreate,
CollaborateurDetails,
CollaborateurListe,
CollaborateurUpdate,
)
from utils.normalization import normaliser_type_tiers
from routes.sage_gateway import router as sage_gateway_router
from core.sage_context import (
@ -3141,6 +3147,94 @@ async def get_current_sage_config(
}
# Routes Collaborateurs
@app.get(
"/collaborateurs", response_model=List[CollaborateurListe], tags=["Collaborateurs"]
)
async def lister_collaborateurs(
filtre: Optional[str] = Query(None, description="Filtre sur nom/prénom"),
actifs_seulement: bool = Query(
True, description="Exclure les collaborateurs en sommeil"
),
):
"""Liste tous les collaborateurs"""
try:
collaborateurs = sage_client.lister_collaborateurs(filtre, actifs_seulement)
return [CollaborateurListe(**c) for c in collaborateurs]
except Exception as e:
logger.error(f"Erreur liste collaborateurs: {e}")
raise HTTPException(500, str(e))
@app.get(
"/collaborateurs/{numero}",
response_model=CollaborateurDetails,
tags=["Collaborateurs"],
)
async def lire_collaborateur_detail(numero: int):
"""Lit un collaborateur par son numéro"""
try:
collaborateur = sage_client.lire_collaborateur(numero)
if not collaborateur:
raise HTTPException(404, f"Collaborateur {numero} introuvable")
return CollaborateurDetails(**collaborateur)
except HTTPException:
raise
except Exception as e:
logger.error(f"Erreur lecture collaborateur {numero}: {e}")
raise HTTPException(500, str(e))
@app.post(
"/collaborateurs",
response_model=CollaborateurDetails,
tags=["Collaborateurs"],
status_code=201,
)
async def creer_collaborateur(collaborateur: CollaborateurCreate):
"""Crée un nouveau collaborateur"""
try:
nouveau = sage_client.creer_collaborateur(collaborateur.model_dump())
if not nouveau:
raise HTTPException(500, "Échec création collaborateur")
return CollaborateurDetails(**nouveau)
except HTTPException:
raise
except Exception as e:
logger.error(f"Erreur création collaborateur: {e}")
raise HTTPException(500, str(e))
@app.put(
"/collaborateurs/{numero}",
response_model=CollaborateurDetails,
tags=["Collaborateurs"],
)
async def modifier_collaborateur(numero: int, collaborateur: CollaborateurUpdate):
"""Modifie un collaborateur existant"""
try:
modifie = sage_client.modifier_collaborateur(
numero, collaborateur.model_dump(exclude_unset=True)
)
if not modifie:
raise HTTPException(404, f"Collaborateur {numero} introuvable")
return CollaborateurDetails(**modifie)
except HTTPException:
raise
except Exception as e:
logger.error(f"Erreur modification collaborateur {numero}: {e}")
raise HTTPException(500, str(e))
@app.get("/health", tags=["System"])
async def health_check(
sage: SageGatewayClient = Depends(get_sage_client_for_user),

View file

@ -401,6 +401,29 @@ class SageGatewayClient:
result = self._post("/sage/client/remise-max", {"code": code_client})
return result.get("data", {}).get("remise_max", 10.0)
def lister_collaborateurs(
self, filtre: str = "", actifs_seulement: bool = True
) -> List[Dict]:
"""Liste tous les collaborateurs"""
return self._post(
"/sage/collaborateurs/list",
{"filtre": filtre, "actifs_seulement": actifs_seulement},
).get("data", [])
def lire_collaborateur(self, numero: int) -> Optional[Dict]:
"""Lit un collaborateur par numéro"""
return self._post("/sage/collaborateurs/get", {"numero": numero}).get("data")
def creer_collaborateur(self, data: Dict) -> Optional[Dict]:
"""Crée un nouveau collaborateur"""
return self._post("/sage/collaborateurs/create", data).get("data")
def modifier_collaborateur(self, numero: int, data: Dict) -> Optional[Dict]:
"""Modifie un collaborateur existant"""
return self._post(
"/sage/collaborateurs/update", {"numero": numero, **data}
).get("data")
def refresh_cache(self) -> Dict:
return self._post("/sage/cache/refresh")

View file

116
schemas/tiers/commercial.py Normal file
View file

@ -0,0 +1,116 @@
from pydantic import BaseModel, EmailStr, Field
from typing import Optional
class CollaborateurBase(BaseModel):
"""Champs communs collaborateur"""
nom: str = Field(..., max_length=50)
prenom: Optional[str] = Field(None, max_length=50)
fonction: Optional[str] = Field(None, max_length=50)
# Adresse
adresse: Optional[str] = Field(None, max_length=100)
complement: Optional[str] = Field(None, max_length=100)
code_postal: Optional[str] = Field(None, max_length=10)
ville: Optional[str] = Field(None, max_length=50)
code_region: Optional[str] = Field(None, max_length=50)
pays: Optional[str] = Field(None, max_length=50)
# Services
service: Optional[str] = Field(None, max_length=50)
vendeur: bool = Field(default=False)
caissier: bool = Field(default=False)
acheteur: bool = Field(default=False)
chef_ventes: bool = Field(default=False)
numero_chef_ventes: Optional[int] = None
# Contact
telephone: Optional[str] = Field(None, max_length=20)
telecopie: Optional[str] = Field(None, max_length=20)
email: Optional[EmailStr] = None
tel_portable: Optional[str] = Field(None, max_length=20)
# Réseaux sociaux
facebook: Optional[str] = Field(None, max_length=100)
linkedin: Optional[str] = Field(None, max_length=100)
skype: Optional[str] = Field(None, max_length=100)
# Autres
matricule: Optional[str] = Field(None, max_length=20)
sommeil: bool = Field(default=False)
class CollaborateurCreate(CollaborateurBase):
"""Création d'un collaborateur"""
pass
class CollaborateurUpdate(BaseModel):
"""Modification d'un collaborateur (tous champs optionnels)"""
nom: Optional[str] = Field(None, max_length=50)
prenom: Optional[str] = Field(None, max_length=50)
fonction: Optional[str] = Field(None, max_length=50)
adresse: Optional[str] = Field(None, max_length=100)
complement: Optional[str] = Field(None, max_length=100)
code_postal: Optional[str] = Field(None, max_length=10)
ville: Optional[str] = Field(None, max_length=50)
code_region: Optional[str] = Field(None, max_length=50)
pays: Optional[str] = Field(None, max_length=50)
service: Optional[str] = Field(None, max_length=50)
vendeur: Optional[bool] = None
caissier: Optional[bool] = None
acheteur: Optional[bool] = None
chef_ventes: Optional[bool] = None
numero_chef_ventes: Optional[int] = None
telephone: Optional[str] = Field(None, max_length=20)
telecopie: Optional[str] = Field(None, max_length=20)
email: Optional[EmailStr] = None
tel_portable: Optional[str] = Field(None, max_length=20)
facebook: Optional[str] = Field(None, max_length=100)
linkedin: Optional[str] = Field(None, max_length=100)
skype: Optional[str] = Field(None, max_length=100)
matricule: Optional[str] = Field(None, max_length=20)
sommeil: Optional[bool] = None
class CollaborateurListe(BaseModel):
"""Vue liste simplifiée"""
numero: int
nom: str
prenom: Optional[str]
fonction: Optional[str]
service: Optional[str]
email: Optional[str]
telephone: Optional[str]
vendeur: bool
sommeil: bool
class CollaborateurDetails(CollaborateurBase):
"""Détails complets d'un collaborateur"""
numero: int
class Config:
json_schema_extra = {
"example": {
"numero": 1,
"nom": "DUPONT",
"prenom": "Jean",
"fonction": "Directeur Commercial",
"service": "Commercial",
"vendeur": True,
"email": "j.dupont@entreprise.fr",
"telephone": "0123456789",
"sommeil": False,
}
}