from pydantic import BaseModel, Field, EmailStr from typing import List, Optional from schemas.tiers.contact import Contact class FournisseurDetails(BaseModel): numero: Optional[str] = Field(None, description="Code fournisseur (CT_Num)") 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)" ) qualite: Optional[str] = Field( None, description="Qualité Sage : CLI, FOU, PRO (CT_Qualite)" ) classement: Optional[str] = Field( None, description="Code de classement (CT_Classement)" ) raccourci: Optional[str] = Field( None, description="Code raccourci 7 car. (CT_Raccourci)" ) siret: Optional[str] = Field(None, description="N° SIRET 14 chiffres (CT_Siret)") tva_intra: Optional[str] = Field( None, description="N° TVA intracommunautaire (CT_Identifiant)" ) code_naf: Optional[str] = Field(None, description="Code NAF/APE (CT_Ape)") contact: Optional[str] = Field( None, description="Nom du contact principal (CT_Contact)" ) adresse: Optional[str] = Field(None, description="Adresse ligne 1 (CT_Adresse)") complement: Optional[str] = Field( None, description="Complément d'adresse (CT_Complement)" ) code_postal: Optional[str] = Field(None, description="Code postal (CT_CodePostal)") ville: Optional[str] = Field(None, description="Ville (CT_Ville)") region: Optional[str] = Field(None, description="Région/État (CT_CodeRegion)") pays: Optional[str] = Field(None, description="Pays (CT_Pays)") telephone: Optional[str] = Field(None, description="Téléphone fixe (CT_Telephone)") telecopie: Optional[str] = Field(None, description="Fax (CT_Telecopie)") email: Optional[str] = Field(None, description="Email principal (CT_EMail)") site_web: Optional[str] = Field(None, description="Site web (CT_Site)") facebook: Optional[str] = Field(None, description="Profil Facebook (CT_Facebook)") linkedin: Optional[str] = Field(None, description="Profil LinkedIn (CT_LinkedIn)") taux01: Optional[float] = Field(None, description="Taux personnalisé 1 (CT_Taux01)") taux02: Optional[float] = Field(None, description="Taux personnalisé 2 (CT_Taux02)") taux03: Optional[float] = Field(None, description="Taux personnalisé 3 (CT_Taux03)") taux04: Optional[float] = Field(None, description="Taux personnalisé 4 (CT_Taux04)") statistique01: Optional[str] = Field( None, description="Statistique 1 (CT_Statistique01)" ) statistique02: Optional[str] = Field( None, description="Statistique 2 (CT_Statistique02)" ) statistique03: Optional[str] = Field( None, description="Statistique 3 (CT_Statistique03)" ) statistique04: Optional[str] = Field( None, description="Statistique 4 (CT_Statistique04)" ) statistique05: Optional[str] = Field( None, description="Statistique 5 (CT_Statistique05)" ) statistique06: Optional[str] = Field( None, description="Statistique 6 (CT_Statistique06)" ) statistique07: Optional[str] = Field( None, description="Statistique 7 (CT_Statistique07)" ) statistique08: Optional[str] = Field( None, description="Statistique 8 (CT_Statistique08)" ) statistique09: Optional[str] = Field( None, description="Statistique 9 (CT_Statistique09)" ) statistique10: Optional[str] = Field( None, description="Statistique 10 (CT_Statistique10)" ) 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)" ) 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)" ) lettrage_auto: Optional[bool] = Field( None, description="Lettrage automatique (CT_Lettrage)" ) 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)" ) est_prospect: Optional[bool] = Field( None, description="True si prospect (CT_Prospect=1)" ) bl_en_facture: Optional[int] = Field( None, description="Imprimer BL en facture (CT_BLFact)" ) saut_page: Optional[int] = Field( None, description="Saut de page sur documents (CT_Saut)" ) validation_echeance: Optional[int] = Field( None, description="Valider les échéances (CT_ValidEch)" ) controle_encours: Optional[int] = Field( None, description="Contrôler l'encours (CT_ControlEnc)" ) exclure_relance: Optional[bool] = Field( None, description="Exclure des relances (CT_NotRappel)" ) 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)" ) priorite_livraison: Optional[int] = Field( None, description="Priorité livraison (CT_PrioriteLivr)" ) 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_appro: Optional[int] = Field( None, description="Délai appro jours (CT_DelaiAppro)" ) commentaire: Optional[str] = Field( None, description="Commentaire libre (CT_Commentaire)" ) section_analytique: Optional[str] = Field( None, description="Section analytique (CA_Num)" ) 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)" ) coface: Optional[str] = Field(None, description="Code Coface 25 car. (CT_Coface)") forme_juridique: Optional[str] = Field( None, description="Forme juridique SA, SARL (CT_SvFormeJuri)" ) effectif: Optional[str] = Field( None, description="Nombre d'employés (CT_SvEffectif)" ) sv_regularite: Optional[str] = Field( None, description="Régularité paiements (CT_SvRegul)" ) sv_cotation: Optional[str] = Field( None, description="Cotation crédit (CT_SvCotation)" ) sv_objet_maj: Optional[str] = Field( None, description="Objet dernière MAJ (CT_SvObjetMaj)" ) 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)" ) 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_compta: Optional[int] = Field( None, description="Catégorie comptable (N_CatCompta)" ) contacts: Optional[List[Contact]] = Field( default_factory=list, description="Liste des contacts du fournisseur" ) class Config: json_schema_extra = { "example": { "numero": "FOU000001", "intitule": "SARL FOURNISSEUR EXEMPLE", "type_tiers": 1, "qualite": "FOU", "classement": "A", "raccourci": "EXEMPL", "siret": "12345678901234", "tva_intra": "FR12345678901", "code_naf": "6201Z", "contact": "Jean Dupont", "adresse": "123 Rue de la Paix", "complement": "Bâtiment B", "code_postal": "75001", "ville": "Paris", "region": "Île-de-France", "pays": "France", "telephone": "0123456789", "telecopie": "0123456788", "email": "contact@exemple.fr", "site_web": "https://www.exemple.fr", "facebook": "https://facebook.com/exemple", "linkedin": "https://linkedin.com/company/exemple", "taux01": 0.0, "taux02": 0.0, "taux03": 0.0, "taux04": 0.0, "statistique01": "Informatique", "statistique02": "", "statistique03": "", "statistique04": "", "statistique05": "", "statistique06": "", "statistique07": "", "statistique08": "", "statistique09": "", "statistique10": "", "encours_autorise": 50000.0, "assurance_credit": 40000.0, "langue": 0, "commercial_code": 1, "lettrage_auto": True, "est_actif": True, "type_facture": 1, "est_prospect": False, "bl_en_facture": 0, "saut_page": 0, "validation_echeance": 0, "controle_encours": 1, "exclure_relance": False, "exclure_penalites": False, "bon_a_payer": 0, "priorite_livraison": 1, "livraison_partielle": 1, "delai_transport": 2, "delai_appro": 0, "commentaire": "Client important", "section_analytique": "", "mode_reglement_code": 1, "surveillance_active": True, "coface": "COF12345", "forme_juridique": "SARL", "effectif": "50-99", "sv_regularite": "", "sv_cotation": "", "sv_objet_maj": "", "sv_chiffre_affaires": 2500000.0, "sv_resultat": 150000.0, "compte_general": "4110000", "categorie_tarif": 0, "categorie_compta": 0, } } class FournisseurCreateAPIRequest(BaseModel): intitule: str = Field( ..., min_length=1, max_length=69, description="Raison sociale du fournisseur" ) compte_collectif: str = Field( "401000", description="Compte comptable fournisseur (ex: 401000)" ) num: Optional[str] = Field( None, max_length=17, description="Code fournisseur souhaité (optionnel)" ) 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) email: Optional[EmailStr] = None telephone: Optional[str] = Field(None, max_length=21) siret: Optional[str] = Field(None, max_length=14) tva_intra: Optional[str] = Field(None, max_length=25) class Config: json_schema_extra = { "example": { "intitule": "ACME SUPPLIES SARL", "compte_collectif": "401000", "num": "FOUR001", "adresse": "15 Rue du Commerce", "code_postal": "75001", "ville": "Paris", "pays": "France", "email": "contact@acmesupplies.fr", "telephone": "0145678901", "siret": "12345678901234", "tva_intra": "FR12345678901", } } class FournisseurUpdateRequest(BaseModel): """Modèle pour modification d'un fournisseur existant""" intitule: Optional[str] = Field(None, min_length=1, max_length=69) 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) email: Optional[EmailStr] = None telephone: Optional[str] = Field(None, max_length=21) siret: Optional[str] = Field(None, max_length=14) tva_intra: Optional[str] = Field(None, max_length=25) class Config: json_schema_extra = { "example": { "intitule": "ACME SUPPLIES MODIFIÉ", "email": "nouveau@acme.fr", "telephone": "0198765432", } }