feat(client): add Contact model and contacts field to ClientDetails
This commit is contained in:
parent
61869f3293
commit
f414a2889e
1 changed files with 53 additions and 12 deletions
65
api.py
65
api.py
|
|
@ -124,13 +124,60 @@ class ClientResponse(BaseModel):
|
||||||
telephone: Optional[str] = None # Téléphone principal (fixe ou mobile)
|
telephone: Optional[str] = None # Téléphone principal (fixe ou mobile)
|
||||||
|
|
||||||
|
|
||||||
|
class Contact(BaseModel):
|
||||||
|
"""
|
||||||
|
Contact associé à un tiers (client/fournisseur)
|
||||||
|
Tous les champs de F_CONTACTT
|
||||||
|
"""
|
||||||
|
|
||||||
|
ct_num: Optional[str] = Field(None, description="Code du tiers parent (CT_Num)")
|
||||||
|
ct_no: Optional[int] = Field(None, description="Numéro unique du contact (CT_No)")
|
||||||
|
n_contact: Optional[int] = Field(None, description="Numéro de référence contact (N_Contact)")
|
||||||
|
|
||||||
|
civilite: Optional[str] = Field(None, description="Civilité : 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)")
|
||||||
|
fonction: Optional[str] = Field(None, description="Fonction/Titre (CT_Fonction)")
|
||||||
|
|
||||||
|
service_code: Optional[int] = Field(None, description="Code du service (N_Service)")
|
||||||
|
|
||||||
|
telephone: Optional[str] = Field(None, description="Téléphone fixe (CT_Telephone)")
|
||||||
|
portable: Optional[str] = Field(None, description="Téléphone mobile (CT_TelPortable)")
|
||||||
|
telecopie: Optional[str] = Field(None, description="Fax (CT_Telecopie)")
|
||||||
|
email: Optional[str] = Field(None, description="Adresse email (CT_EMail)")
|
||||||
|
|
||||||
|
facebook: Optional[str] = Field(None, description="Profil Facebook (CT_Facebook)")
|
||||||
|
linkedin: Optional[str] = Field(None, description="Profil LinkedIn (CT_LinkedIn)")
|
||||||
|
skype: Optional[str] = Field(None, description="Identifiant Skype (CT_Skype)")
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
json_schema_extra = {
|
||||||
|
"example": {
|
||||||
|
"ct_num": "CLI000001",
|
||||||
|
"ct_no": 1,
|
||||||
|
"n_contact": 1,
|
||||||
|
"civilite": "M.",
|
||||||
|
"nom": "Dupont",
|
||||||
|
"prenom": "Jean",
|
||||||
|
"fonction": "Directeur Commercial",
|
||||||
|
"service_code": 1,
|
||||||
|
"telephone": "0123456789",
|
||||||
|
"portable": "0612345678",
|
||||||
|
"telecopie": "0123456788",
|
||||||
|
"email": "j.dupont@exemple.fr",
|
||||||
|
"facebook": "https://facebook.com/jean.dupont",
|
||||||
|
"linkedin": "https://linkedin.com/in/jeandupont",
|
||||||
|
"skype": "jean.dupont.pro"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ClientDetails(BaseModel):
|
class ClientDetails(BaseModel):
|
||||||
"""
|
"""
|
||||||
Modèle de réponse client complet (GET /clients/{code})
|
Modèle de réponse client complet (GET /clients/{code})
|
||||||
Strictement aligné avec les champs retournés par lister_tous_clients
|
Strictement aligné avec les champs retournés par lister_tous_clients
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# IDENTIFICATION (9 champs)
|
|
||||||
numero: Optional[str] = Field(None, description="Code client (CT_Num)")
|
numero: Optional[str] = Field(None, description="Code client (CT_Num)")
|
||||||
intitule: Optional[str] = Field(None, description="Raison sociale ou Nom complet (CT_Intitule)")
|
intitule: Optional[str] = Field(None, description="Raison sociale ou Nom complet (CT_Intitule)")
|
||||||
type_tiers: Optional[int] = Field(None, description="Type : 0=Client, 1=Fournisseur (CT_Type)")
|
type_tiers: Optional[int] = Field(None, description="Type : 0=Client, 1=Fournisseur (CT_Type)")
|
||||||
|
|
@ -141,7 +188,6 @@ class ClientDetails(BaseModel):
|
||||||
tva_intra: Optional[str] = Field(None, description="N° TVA intracommunautaire (CT_Identifiant)")
|
tva_intra: Optional[str] = Field(None, description="N° TVA intracommunautaire (CT_Identifiant)")
|
||||||
code_naf: Optional[str] = Field(None, description="Code NAF/APE (CT_Ape)")
|
code_naf: Optional[str] = Field(None, description="Code NAF/APE (CT_Ape)")
|
||||||
|
|
||||||
# ADRESSE (7 champs)
|
|
||||||
contact: Optional[str] = Field(None, description="Nom du contact principal (CT_Contact)")
|
contact: Optional[str] = Field(None, description="Nom du contact principal (CT_Contact)")
|
||||||
adresse: Optional[str] = Field(None, description="Adresse ligne 1 (CT_Adresse)")
|
adresse: Optional[str] = Field(None, description="Adresse ligne 1 (CT_Adresse)")
|
||||||
complement: Optional[str] = Field(None, description="Complément d'adresse (CT_Complement)")
|
complement: Optional[str] = Field(None, description="Complément d'adresse (CT_Complement)")
|
||||||
|
|
@ -150,7 +196,6 @@ class ClientDetails(BaseModel):
|
||||||
region: Optional[str] = Field(None, description="Région/État (CT_CodeRegion)")
|
region: Optional[str] = Field(None, description="Région/État (CT_CodeRegion)")
|
||||||
pays: Optional[str] = Field(None, description="Pays (CT_Pays)")
|
pays: Optional[str] = Field(None, description="Pays (CT_Pays)")
|
||||||
|
|
||||||
# TELECOM (6 champs - pas de portable dans le SQL)
|
|
||||||
telephone: Optional[str] = Field(None, description="Téléphone fixe (CT_Telephone)")
|
telephone: Optional[str] = Field(None, description="Téléphone fixe (CT_Telephone)")
|
||||||
telecopie: Optional[str] = Field(None, description="Fax (CT_Telecopie)")
|
telecopie: Optional[str] = Field(None, description="Fax (CT_Telecopie)")
|
||||||
email: Optional[str] = Field(None, description="Email principal (CT_EMail)")
|
email: Optional[str] = Field(None, description="Email principal (CT_EMail)")
|
||||||
|
|
@ -158,13 +203,11 @@ class ClientDetails(BaseModel):
|
||||||
facebook: Optional[str] = Field(None, description="Profil Facebook (CT_Facebook)")
|
facebook: Optional[str] = Field(None, description="Profil Facebook (CT_Facebook)")
|
||||||
linkedin: Optional[str] = Field(None, description="Profil LinkedIn (CT_LinkedIn)")
|
linkedin: Optional[str] = Field(None, description="Profil LinkedIn (CT_LinkedIn)")
|
||||||
|
|
||||||
# TAUX (4 champs)
|
|
||||||
taux01: Optional[float] = Field(None, description="Taux personnalisé 1 (CT_Taux01)")
|
taux01: Optional[float] = Field(None, description="Taux personnalisé 1 (CT_Taux01)")
|
||||||
taux02: Optional[float] = Field(None, description="Taux personnalisé 2 (CT_Taux02)")
|
taux02: Optional[float] = Field(None, description="Taux personnalisé 2 (CT_Taux02)")
|
||||||
taux03: Optional[float] = Field(None, description="Taux personnalisé 3 (CT_Taux03)")
|
taux03: Optional[float] = Field(None, description="Taux personnalisé 3 (CT_Taux03)")
|
||||||
taux04: Optional[float] = Field(None, description="Taux personnalisé 4 (CT_Taux04)")
|
taux04: Optional[float] = Field(None, description="Taux personnalisé 4 (CT_Taux04)")
|
||||||
|
|
||||||
# STATISTIQUES (10 champs - utiliser les noms exacts du SQL)
|
|
||||||
statistique01: Optional[str] = Field(None, description="Statistique 1 (CT_Statistique01)")
|
statistique01: Optional[str] = Field(None, description="Statistique 1 (CT_Statistique01)")
|
||||||
statistique02: Optional[str] = Field(None, description="Statistique 2 (CT_Statistique02)")
|
statistique02: Optional[str] = Field(None, description="Statistique 2 (CT_Statistique02)")
|
||||||
statistique03: Optional[str] = Field(None, description="Statistique 3 (CT_Statistique03)")
|
statistique03: Optional[str] = Field(None, description="Statistique 3 (CT_Statistique03)")
|
||||||
|
|
@ -176,13 +219,11 @@ class ClientDetails(BaseModel):
|
||||||
statistique09: Optional[str] = Field(None, description="Statistique 9 (CT_Statistique09)")
|
statistique09: Optional[str] = Field(None, description="Statistique 9 (CT_Statistique09)")
|
||||||
statistique10: Optional[str] = Field(None, description="Statistique 10 (CT_Statistique10)")
|
statistique10: Optional[str] = Field(None, description="Statistique 10 (CT_Statistique10)")
|
||||||
|
|
||||||
# COMMERCIAL (4 champs)
|
|
||||||
encours_autorise: Optional[float] = Field(None, description="Encours maximum autorisé (CT_Encours)")
|
encours_autorise: Optional[float] = Field(None, description="Encours maximum autorisé (CT_Encours)")
|
||||||
assurance_credit: Optional[float] = Field(None, description="Montant assurance crédit (CT_Assurance)")
|
assurance_credit: Optional[float] = Field(None, description="Montant assurance crédit (CT_Assurance)")
|
||||||
langue: Optional[int] = Field(None, description="Code langue 0=FR, 1=EN (CT_Langue)")
|
langue: Optional[int] = Field(None, description="Code langue 0=FR, 1=EN (CT_Langue)")
|
||||||
commercial_code: Optional[int] = Field(None, description="Code du commercial (CO_No)")
|
commercial_code: Optional[int] = Field(None, description="Code du commercial (CO_No)")
|
||||||
|
|
||||||
# FACTURATION (11 champs)
|
|
||||||
lettrage_auto: Optional[bool] = Field(None, description="Lettrage automatique (CT_Lettrage)")
|
lettrage_auto: Optional[bool] = Field(None, description="Lettrage automatique (CT_Lettrage)")
|
||||||
est_actif: Optional[bool] = Field(None, description="True si actif (CT_Sommeil=0)")
|
est_actif: Optional[bool] = Field(None, description="True si actif (CT_Sommeil=0)")
|
||||||
type_facture: Optional[int] = Field(None, description="Type facture 0=Facture, 1=BL (CT_Facture)")
|
type_facture: Optional[int] = Field(None, description="Type facture 0=Facture, 1=BL (CT_Facture)")
|
||||||
|
|
@ -195,19 +236,15 @@ class ClientDetails(BaseModel):
|
||||||
exclure_penalites: Optional[bool] = Field(None, description="Exclure des pénalités (CT_NotPenal)")
|
exclure_penalites: Optional[bool] = Field(None, description="Exclure des pénalités (CT_NotPenal)")
|
||||||
bon_a_payer: Optional[int] = Field(None, description="Bon à payer obligatoire (CT_BonAPayer)")
|
bon_a_payer: Optional[int] = Field(None, description="Bon à payer obligatoire (CT_BonAPayer)")
|
||||||
|
|
||||||
# LOGISTIQUE (4 champs)
|
|
||||||
priorite_livraison: Optional[int] = Field(None, description="Priorité livraison (CT_PrioriteLivr)")
|
priorite_livraison: Optional[int] = Field(None, description="Priorité livraison (CT_PrioriteLivr)")
|
||||||
livraison_partielle: Optional[int] = Field(None, description="Livraison partielle (CT_LivrPartielle)")
|
livraison_partielle: Optional[int] = Field(None, description="Livraison partielle (CT_LivrPartielle)")
|
||||||
delai_transport: Optional[int] = Field(None, description="Délai transport jours (CT_DelaiTransport)")
|
delai_transport: Optional[int] = Field(None, description="Délai transport jours (CT_DelaiTransport)")
|
||||||
delai_appro: Optional[int] = Field(None, description="Délai appro jours (CT_DelaiAppro)")
|
delai_appro: Optional[int] = Field(None, description="Délai appro jours (CT_DelaiAppro)")
|
||||||
|
|
||||||
# COMMENTAIRE (1 champ)
|
|
||||||
commentaire: Optional[str] = Field(None, description="Commentaire libre (CT_Commentaire)")
|
commentaire: Optional[str] = Field(None, description="Commentaire libre (CT_Commentaire)")
|
||||||
|
|
||||||
# ANALYTIQUE (1 champ)
|
|
||||||
section_analytique: Optional[str] = Field(None, description="Section analytique (CA_Num)")
|
section_analytique: Optional[str] = Field(None, description="Section analytique (CA_Num)")
|
||||||
|
|
||||||
# ORGANISATION / SURVEILLANCE (10 champs)
|
|
||||||
mode_reglement_code: Optional[int] = Field(None, description="Code mode règlement (MR_No)")
|
mode_reglement_code: Optional[int] = Field(None, description="Code mode règlement (MR_No)")
|
||||||
surveillance_active: Optional[bool] = Field(None, description="Surveillance financière (CT_Surveillance)")
|
surveillance_active: Optional[bool] = Field(None, description="Surveillance financière (CT_Surveillance)")
|
||||||
coface: Optional[str] = Field(None, description="Code Coface 25 car. (CT_Coface)")
|
coface: Optional[str] = Field(None, description="Code Coface 25 car. (CT_Coface)")
|
||||||
|
|
@ -219,11 +256,15 @@ class ClientDetails(BaseModel):
|
||||||
sv_chiffre_affaires: Optional[float] = Field(None, description="Chiffre d'affaires (CT_SvCA)")
|
sv_chiffre_affaires: Optional[float] = Field(None, description="Chiffre d'affaires (CT_SvCA)")
|
||||||
sv_resultat: Optional[float] = Field(None, description="Résultat financier (CT_SvResultat)")
|
sv_resultat: Optional[float] = Field(None, description="Résultat financier (CT_SvResultat)")
|
||||||
|
|
||||||
# COMPTE GENERAL ET CATEGORIES (3 champs)
|
|
||||||
compte_general: Optional[str] = Field(None, description="Compte général principal (CG_NumPrinc)")
|
compte_general: Optional[str] = Field(None, description="Compte général principal (CG_NumPrinc)")
|
||||||
categorie_tarif: Optional[int] = Field(None, description="Catégorie tarifaire (N_CatTarif)")
|
categorie_tarif: Optional[int] = Field(None, description="Catégorie tarifaire (N_CatTarif)")
|
||||||
categorie_compta: Optional[int] = Field(None, description="Catégorie comptable (N_CatCompta)")
|
categorie_compta: Optional[int] = Field(None, description="Catégorie comptable (N_CatCompta)")
|
||||||
|
|
||||||
|
contacts: Optional[List[Contact]] = Field(
|
||||||
|
default_factory=list,
|
||||||
|
description="Liste des contacts du client"
|
||||||
|
)
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
json_schema_extra = {
|
json_schema_extra = {
|
||||||
"example": {
|
"example": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue