refactor(models): improve client models structure and documentation

This commit is contained in:
Fanilo-Nantenaina 2025-12-09 11:20:01 +03:00
parent 60a9d90955
commit 8f4c4f97a7

192
api.py
View file

@ -111,59 +111,125 @@ class StatutEmail(str, Enum):
# MODÈLES PYDANTIC
# =====================================================
class ClientResponse(BaseModel):
"""Modèle de réponse client simplifié (pour listes)"""
numero: Optional[str] = None
intitule: Optional[str] = None
adresse: Optional[str] = None
code_postal: Optional[str] = None
ville: Optional[str] = None
email: Optional[str] = None
telephone: Optional[str] = None
telephone: Optional[str] = None # Téléphone principal (fixe ou mobile)
class ClientDetails(ClientResponse):
type: Optional[int] = None
qualite: Optional[str] = None
est_prospect: Optional[bool] = None
est_fournisseur: Optional[bool] = None
est_actif: Optional[bool] = None
est_en_sommeil: Optional[bool] = None
class ClientDetails(BaseModel):
"""Modèle de réponse client complet (pour GET /clients/{code})"""
civilite: Optional[str] = None
nom: Optional[str] = None
prenom: Optional[str] = None
nom_complet: Optional[str] = None
contact: Optional[str] = None
# === IDENTIFICATION ===
numero: Optional[str] = Field(None, description="Code client (CT_Num)")
intitule: Optional[str] = Field(None, description="Raison sociale ou Nom complet (CT_Intitule)")
complement: Optional[str] = None
region: Optional[str] = None
pays: Optional[str] = None
# === TYPE DE TIERS ===
type_tiers: Optional[str] = Field(
None,
description="Type : 'client', 'prospect', 'fournisseur' ou 'client_fournisseur'"
)
qualite: Optional[str] = Field(
None,
description="Qualité Sage : CLI (Client), FOU (Fournisseur), PRO (Prospect)"
)
est_prospect: Optional[bool] = Field(None, description="True si prospect (CT_Prospect=1)")
est_fournisseur: Optional[bool] = Field(None, description="True si fournisseur (CT_Qualite=2 ou 3)")
portable: Optional[str] = None
telecopie: Optional[str] = None
site_web: Optional[str] = None
# === TYPE DE PERSONNE (ENTREPRISE VS PARTICULIER) ===
forme_juridique: Optional[str] = Field(
None,
description="Forme juridique (SA, SARL, SAS, EI, etc.) - Vide si particulier"
)
est_entreprise: Optional[bool] = Field(
None,
description="True si entreprise (forme_juridique renseignée)"
)
est_particulier: Optional[bool] = Field(
None,
description="True si particulier (pas de forme juridique)"
)
siret: Optional[str] = None
siren: Optional[str] = None
tva_intra: Optional[str] = None
code_naf: Optional[str] = None
forme_juridique: Optional[str] = None
# === STATUT ===
est_actif: Optional[bool] = Field(None, description="True si actif (CT_Sommeil=0)")
est_en_sommeil: Optional[bool] = Field(None, description="True si en sommeil (CT_Sommeil=1)")
secteur: Optional[str] = None
effectif: Optional[int] = None
ca_annuel: Optional[float] = None
commercial_code: Optional[str] = None
commercial_nom: Optional[str] = None
# === IDENTITÉ (POUR PARTICULIERS) ===
civilite: Optional[str] = Field(None, description="M., Mme, Mlle (CT_Civilite)")
nom: Optional[str] = Field(None, description="Nom de famille (CT_Nom)")
prenom: Optional[str] = Field(None, description="Prénom (CT_Prenom)")
nom_complet: Optional[str] = Field(
None,
description="Nom complet formaté : 'Civilité Prénom Nom'"
)
categorie_tarifaire: Optional[int] = None
categorie_comptable: Optional[int] = None
# === CONTACT ===
contact: Optional[str] = Field(None, description="Nom du contact principal (CT_Contact)")
encours_autorise: Optional[float] = None
assurance_credit: Optional[float] = None
compte_general: Optional[str] = None
# === ADRESSE ===
adresse: Optional[str] = Field(None, description="Adresse ligne 1")
complement: Optional[str] = Field(None, description="Complément d'adresse")
code_postal: Optional[str] = Field(None, description="Code postal")
ville: Optional[str] = Field(None, description="Ville")
region: Optional[str] = Field(None, description="Région/État")
pays: Optional[str] = Field(None, description="Pays")
date_creation: Optional[str] = None
date_modification: Optional[str] = None
# === TÉLÉCOMMUNICATIONS ===
telephone: Optional[str] = Field(None, description="Téléphone fixe")
portable: Optional[str] = Field(None, description="Téléphone mobile")
telecopie: Optional[str] = Field(None, description="Fax")
email: Optional[str] = Field(None, description="Email principal")
site_web: Optional[str] = Field(None, description="Site web")
# === INFORMATIONS JURIDIQUES (ENTREPRISES) ===
siret: Optional[str] = Field(None, description="N° SIRET (14 chiffres)")
siren: Optional[str] = Field(None, description="N° SIREN (9 chiffres)")
tva_intra: Optional[str] = Field(None, description="N° TVA intracommunautaire")
code_naf: Optional[str] = Field(None, description="Code NAF/APE")
# === INFORMATIONS COMMERCIALES ===
secteur: Optional[str] = Field(None, description="Secteur d'activité")
effectif: Optional[int] = Field(None, description="Nombre d'employés")
ca_annuel: Optional[float] = Field(None, description="Chiffre d'affaires annuel")
commercial_code: Optional[str] = Field(None, description="Code du commercial rattaché")
commercial_nom: Optional[str] = Field(None, description="Nom du commercial")
# === CATÉGORIES ===
categorie_tarifaire: Optional[int] = Field(None, description="Catégorie tarifaire (N_CatTarif)")
categorie_comptable: Optional[int] = Field(None, description="Catégorie comptable (N_CatCompta)")
# === INFORMATIONS FINANCIÈRES ===
encours_autorise: Optional[float] = Field(None, description="Encours maximum autorisé")
assurance_credit: Optional[float] = Field(None, description="Montant assurance crédit")
compte_general: Optional[str] = Field(None, description="Compte général principal")
# === DATES ===
date_creation: Optional[str] = Field(None, description="Date de création")
date_modification: Optional[str] = Field(None, description="Date de dernière modification")
class Config:
json_schema_extra = {
"example": {
"numero": "CLI000001",
"intitule": "SARL EXEMPLE",
"type_tiers": "client",
"qualite": "CLI",
"est_entreprise": True,
"forme_juridique": "SARL",
"adresse": "123 Rue de la Paix",
"code_postal": "75001",
"ville": "Paris",
"telephone": "0123456789",
"portable": "0612345678",
"email": "contact@exemple.fr",
"siret": "12345678901234",
"tva_intra": "FR12345678901"
}
}
class ArticleResponse(BaseModel):
reference: str
@ -229,18 +295,43 @@ class BaremeRemiseResponse(BaseModel):
class ClientCreateAPIRequest(BaseModel):
intitule: str = Field(..., min_length=1, description="Raison sociale ou Nom")
compte_collectif: str = Field("411000", description="Compte Comptable (ex: 411000)")
num: Optional[str] = Field(None, description="Code client souhaité (optionnel)")
adresse: Optional[str] = None
code_postal: Optional[str] = None
ville: Optional[str] = None
pays: Optional[str] = None
email: Optional[EmailStr] = None
telephone: Optional[str] = None
siret: Optional[str] = None
tva_intra: Optional[str] = None
"""Modèle pour création d'un nouveau client"""
intitule: str = Field(..., min_length=1, max_length=69, description="Raison sociale ou Nom complet")
compte_collectif: str = Field("411000", description="Compte comptable (411000 par défaut)")
num: Optional[str] = Field(None, max_length=17, description="Code client souhaité (auto si vide)")
# Adresse
adresse: Optional[str] = Field(None, max_length=35)
code_postal: Optional[str] = Field(None, max_length=9)
ville: Optional[str] = Field(None, max_length=35)
pays: Optional[str] = Field(None, max_length=35)
# Contact
email: Optional[EmailStr] = None
telephone: Optional[str] = Field(None, max_length=21, description="Téléphone fixe")
portable: Optional[str] = Field(None, max_length=21, description="Téléphone mobile")
# Juridique
forme_juridique: Optional[str] = Field(None, max_length=50, description="SARL, SA, SAS, EI, etc.")
siret: Optional[str] = Field(None, max_length=14)
tva_intra: Optional[str] = Field(None, max_length=25)
class Config:
json_schema_extra = {
"example": {
"intitule": "SARL NOUVELLE ENTREPRISE",
"forme_juridique": "SARL",
"adresse": "10 Avenue des Champs",
"code_postal": "75008",
"ville": "Paris",
"telephone": "0123456789",
"portable": "0612345678",
"email": "contact@nouvelle-entreprise.fr",
"siret": "12345678901234",
"tva_intra": "FR12345678901"
}
}
class ClientUpdateRequest(BaseModel):
"""Modèle pour modification d'un client existant"""
@ -252,18 +343,17 @@ class ClientUpdateRequest(BaseModel):
pays: Optional[str] = Field(None, max_length=35)
email: Optional[EmailStr] = None
telephone: Optional[str] = Field(None, max_length=21)
portable: Optional[str] = Field(None, max_length=21)
forme_juridique: Optional[str] = Field(None, max_length=50)
siret: Optional[str] = Field(None, max_length=14)
tva_intra: Optional[str] = Field(None, max_length=25)
class Config:
json_schema_extra = {
"example": {
"intitule": "SARL TEST MODIFIÉ",
"adresse": "456 Avenue des Champs",
"code_postal": "75008",
"ville": "Paris",
"email": "nouveau@email.fr",
"telephone": "0198765432",
"portable": "0687654321"
}
}