diff --git a/api.py b/api.py index e670b2d..c4d0cb4 100644 --- a/api.py +++ b/api.py @@ -2134,88 +2134,130 @@ class FamilleCreateRequest(BaseModel): } -class FamilleResponse(BaseModel): - """Modèle de réponse pour une famille d'articles - aligné sur lister_toutes_familles""" +class FamilleResponse(BaseModel): + """Modèle complet d'une famille avec données comptables et fournisseur""" + + # ========== IDENTIFICATION ========== code: str = Field(..., description="Code famille") intitule: str = Field(..., description="Intitulé") type: int = Field(..., description="Type (0=Détail, 1=Total)") type_libelle: str = Field(..., description="Libellé du type") est_total: bool = Field(..., description="True si type Total") - est_detail: Optional[bool] = Field(None, description="True si type Détail") + est_detail: bool = Field(..., description="True si type Détail") - unite_vente: Optional[str] = Field(None, description="Unité de vente") + # ========== UNITÉS ET COEFFICIENTS ========== + unite_vente: Optional[str] = Field(None, description="Unité de vente par défaut") unite_poids: Optional[str] = Field(None, description="Unité de poids") - coef: Optional[float] = Field(None, description="Coefficient") + coef: Optional[float] = Field(None, description="Coefficient multiplicateur") + # ========== GESTION STOCK ========== suivi_stock: Optional[bool] = Field(None, description="Suivi du stock activé") garantie: Optional[int] = Field(None, description="Durée de garantie (mois)") delai: Optional[int] = Field(None, description="Délai de livraison (jours)") nb_colis: Optional[int] = Field(None, description="Nombre de colis") - compte_achat: Optional[str] = Field(None, description="Compte général achat") - compte_vente: Optional[str] = Field(None, description="Compte général vente") - code_fiscal: Optional[str] = Field(None, description="Code fiscal") + # ========== FISCAL ET COMPTABLE ========== + code_fiscal: Optional[str] = Field(None, description="Code fiscal par défaut") escompte: Optional[bool] = Field(None, description="Escompte autorisé") - est_centrale: Optional[bool] = Field(None, description="Famille centrale") + # ========== CARACTÉRISTIQUES ========== + est_centrale: Optional[bool] = Field(None, description="Famille d'achat centralisé") nature: Optional[int] = Field(None, description="Nature de la famille") pays: Optional[str] = Field(None, description="Pays d'origine") - categorie_1: Optional[int] = Field(None, description="Catégorie 1") - categorie_2: Optional[int] = Field(None, description="Catégorie 2") - categorie_3: Optional[int] = Field(None, description="Catégorie 3") - categorie_4: Optional[int] = Field(None, description="Catégorie 4") + # ========== CATÉGORIES COMPTABLES ========== + categorie_1: Optional[int] = Field(None, description="Catégorie comptable 1 (CL_No1)") + categorie_2: Optional[int] = Field(None, description="Catégorie comptable 2 (CL_No2)") + categorie_3: Optional[int] = Field(None, description="Catégorie comptable 3 (CL_No3)") + categorie_4: Optional[int] = Field(None, description="Catégorie comptable 4 (CL_No4)") - stat_01: Optional[str] = Field(None, description="Statistique 1") - stat_02: Optional[str] = Field(None, description="Statistique 2") - stat_03: Optional[str] = Field(None, description="Statistique 3") - stat_04: Optional[str] = Field(None, description="Statistique 4") - stat_05: Optional[str] = Field(None, description="Statistique 5") + # ========== STATISTIQUES ========== + stat_01: Optional[str] = Field(None, description="Statistique libre 1") + stat_02: Optional[str] = Field(None, description="Statistique libre 2") + stat_03: Optional[str] = Field(None, description="Statistique libre 3") + stat_04: Optional[str] = Field(None, description="Statistique libre 4") + stat_05: Optional[str] = Field(None, description="Statistique libre 5") hors_statistique: Optional[bool] = Field(None, description="Exclue des statistiques") - est_statistique: Optional[bool] = Field(None, description="Incluse dans les statistiques (legacy)") + # ========== OPTIONS DIVERSES ========== vente_debit: Optional[bool] = Field(None, description="Vente au débit") - non_imprimable: Optional[bool] = Field(None, description="Non imprimable") - contremarque: Optional[bool] = Field(None, description="Contremarque") + non_imprimable: Optional[bool] = Field(None, description="Non imprimable sur documents") + contremarque: Optional[bool] = Field(None, description="Article en contremarque") fact_poids: Optional[bool] = Field(None, description="Facturation au poids") fact_forfait: Optional[bool] = Field(None, description="Facturation forfaitaire") - publie: Optional[bool] = Field(None, description="Publié") + publie: Optional[bool] = Field(None, description="Publié (e-commerce)") - racine_reference: Optional[str] = Field(None, description="Racine référence article") - racine_code_barre: Optional[str] = Field(None, description="Racine code-barres") + # ========== RÉFÉRENCES ET RACCOURCIS ========== + racine_reference: Optional[str] = Field(None, description="Racine pour génération auto de références") + racine_code_barre: Optional[str] = Field(None, description="Racine pour génération auto de codes-barres") raccourci: Optional[str] = Field(None, description="Raccourci clavier") - sous_traitance: Optional[bool] = Field(None, description="Sous-traitance") - fictif: Optional[bool] = Field(None, description="Famille fictive") - criticite: Optional[int] = Field(None, description="Niveau de criticité") + # ========== GESTION AVANCÉE ========== + sous_traitance: Optional[bool] = Field(None, description="Famille en sous-traitance") + fictif: Optional[bool] = Field(None, description="Famille fictive (nomenclature)") + criticite: Optional[int] = Field(None, description="Niveau de criticité (0-5)") - avertissement: Optional[str] = Field(None, description="Avertissement si famille Total") - index_com: Optional[int] = Field(None, description="Index COM (lire_famille uniquement)") - date_creation: Optional[str] = Field(None, description="Date de création") - date_modification: Optional[str] = Field(None, description="Date de modification") + # ========== COMPTABILITÉ VENTE (F_FAMCOMPTA Type=0) ========== + compte_vente: Optional[str] = Field(None, description="Compte général de vente") + compte_auxiliaire_vente: Optional[str] = Field(None, description="Compte auxiliaire de vente") + tva_vente_1: Optional[str] = Field(None, description="Code TVA vente principal") + tva_vente_2: Optional[str] = Field(None, description="Code TVA vente secondaire") + tva_vente_3: Optional[str] = Field(None, description="Code TVA vente tertiaire") + type_facture_vente: Optional[int] = Field(None, description="Type de facture vente") + + # ========== COMPTABILITÉ ACHAT (F_FAMCOMPTA Type=1) ========== + compte_achat: Optional[str] = Field(None, description="Compte général d'achat") + compte_auxiliaire_achat: Optional[str] = Field(None, description="Compte auxiliaire d'achat") + tva_achat_1: Optional[str] = Field(None, description="Code TVA achat principal") + tva_achat_2: Optional[str] = Field(None, description="Code TVA achat secondaire") + tva_achat_3: Optional[str] = Field(None, description="Code TVA achat tertiaire") + type_facture_achat: Optional[int] = Field(None, description="Type de facture achat") + + # ========== COMPTABILITÉ STOCK (F_FAMCOMPTA Type=2) ========== + compte_stock: Optional[str] = Field(None, description="Compte de stock") + compte_auxiliaire_stock: Optional[str] = Field(None, description="Compte auxiliaire de stock") + + # ========== FOURNISSEUR PRINCIPAL (F_FAMFOURNISS) ========== + fournisseur_principal: Optional[str] = Field(None, description="N° compte fournisseur principal") + fournisseur_unite: Optional[str] = Field(None, description="Unité d'achat fournisseur") + fournisseur_conversion: Optional[float] = Field(None, description="Coefficient de conversion") + fournisseur_delai_appro: Optional[int] = Field(None, description="Délai d'approvisionnement (jours)") + fournisseur_garantie: Optional[int] = Field(None, description="Garantie fournisseur (mois)") + fournisseur_colisage: Optional[int] = Field(None, description="Colisage fournisseur") + fournisseur_qte_mini: Optional[float] = Field(None, description="Quantité minimum de commande") + fournisseur_qte_mont: Optional[float] = Field(None, description="Quantité montant") + fournisseur_devise: Optional[int] = Field(None, description="Devise fournisseur (0=Euro)") + fournisseur_remise: Optional[float] = Field(None, description="Remise fournisseur (%)") + fournisseur_type_remise: Optional[int] = Field(None, description="Type de remise (0=%, 1=Montant)") + + # ========== INFORMATIONS COMPLÉMENTAIRES ========== nb_articles: Optional[int] = Field(None, description="Nombre d'articles dans la famille") - + + # ========== CHAMPS LEGACY (rétrocompatibilité) ========== + FA_CodeFamille: Optional[str] = Field(None, description="[Legacy] Code famille") + FA_Intitule: Optional[str] = Field(None, description="[Legacy] Intitulé") + FA_Type: Optional[int] = Field(None, description="[Legacy] Type") + CG_NumVte: Optional[str] = Field(None, description="[Legacy] Compte vente") + CG_NumAch: Optional[str] = Field(None, description="[Legacy] Compte achat") class Config: json_schema_extra = { "example": { - "code": "ZDIVERS", - "intitule": "Frais et accessoires", + "code": "ELECT", + "intitule": "Électronique et Informatique", "type": 0, "type_libelle": "Détail", "est_total": False, "est_detail": True, "unite_vente": "U", "unite_poids": "KG", - "coef": 2.0, + "coef": 2.5, "suivi_stock": True, - "garantie": 12, - "delai": 7, + "garantie": 24, + "delai": 5, "nb_colis": 1, - "compte_achat": "607000", - "compte_vente": "707000", - "code_fiscal": "TVA20", + "code_fiscal": "C19", "escompte": True, "est_centrale": False, "nature": 0, @@ -2224,37 +2266,71 @@ class FamilleResponse(BaseModel): "categorie_2": 0, "categorie_3": 0, "categorie_4": 0, - "nb_articles": 45 + "stat_01": "HIGH_TECH", + "stat_02": "", + "stat_03": "", + "stat_04": "", + "stat_05": "", + "hors_statistique": False, + "vente_debit": False, + "non_imprimable": False, + "contremarque": False, + "fact_poids": False, + "fact_forfait": False, + "publie": True, + "racine_reference": "ELEC", + "racine_code_barre": "339", + "raccourci": "F5", + "sous_traitance": False, + "fictif": False, + "criticite": 2, + "compte_vente": "707100", + "compte_auxiliaire_vente": "", + "tva_vente_1": "C19", + "tva_vente_2": "", + "tva_vente_3": "", + "type_facture_vente": 0, + "compte_achat": "607100", + "compte_auxiliaire_achat": "", + "tva_achat_1": "C19", + "tva_achat_2": "", + "tva_achat_3": "", + "type_facture_achat": 0, + "compte_stock": "350000", + "compte_auxiliaire_stock": "", + "fournisseur_principal": "FTECH001", + "fournisseur_unite": "U", + "fournisseur_conversion": 1.0, + "fournisseur_delai_appro": 7, + "fournisseur_garantie": 12, + "fournisseur_colisage": 10, + "fournisseur_qte_mini": 5.0, + "fournisseur_qte_mont": 100.0, + "fournisseur_devise": 0, + "fournisseur_remise": 5.0, + "fournisseur_type_remise": 0, + "nb_articles": 156 } } class FamilleListResponse(BaseModel): - """Modèle de réponse pour une liste de familles""" - - familles: list[FamilleResponse] = Field(..., description="Liste des familles") - total: int = Field(..., description="Nombre total de familles") - filtre_applique: Optional[str] = Field(None, description="Filtre appliqué") - inclut_totaux: bool = Field(..., description="Inclut les familles de type Total") + """Réponse pour la liste des familles""" + familles: list[FamilleResponse] + total: int + filtre: Optional[str] = None + inclure_totaux: bool = True class Config: json_schema_extra = { "example": { - "familles": [ - { - "code": "ZDIVERS", - "intitule": "Frais et accessoires", - "type": 0, - "type_libelle": "Détail", - "est_total": False, - "nb_articles": 45 - } - ], - "total": 1, - "filtre_applique": "frais", - "inclut_totaux": False + "familles": [], + "total": 42, + "filtre": "ELECT", + "inclure_totaux": False } } + class MouvementStockLigneRequest(BaseModel): article_ref: str = Field(..., description="Référence de l'article")