from pydantic import BaseModel, Field, field_validator from typing import List, Optional import logging from decimal import Decimal from datetime import date logger = logging.getLogger(__name__) class ReglementFactureCreate(BaseModel): """Requête de règlement d'une facture côté VPS""" # Montant et devise montant: Decimal = Field(..., gt=0, description="Montant à régler") devise_code: Optional[int] = Field(0, description="Code devise (0=EUR par défaut)") cours_devise: Optional[Decimal] = Field(1.0, description="Cours de la devise") # Mode et journal mode_reglement: int = Field( ..., ge=0, description="Code mode règlement depuis /reglements/modes" ) code_journal: str = Field( ..., min_length=1, description="Code journal depuis /journaux/tresorerie" ) # Dates date_reglement: Optional[date] = Field( None, description="Date du règlement (défaut: aujourd'hui)" ) date_echeance: Optional[date] = Field(None, description="Date d'échéance") # Références reference: Optional[str] = Field( "", max_length=17, description="Référence pièce règlement" ) libelle: Optional[str] = Field( "", max_length=35, description="Libellé du règlement" ) # TVA sur encaissement tva_encaissement: Optional[bool] = Field( False, description="Appliquer TVA sur encaissement" ) compte_general: Optional[str] = Field(None) @field_validator("montant") def validate_montant(cls, v): if v <= 0: raise ValueError("Le montant doit être positif") return round(v, 2) class Config: json_schema_extra = { "example": { "montant": 375.12, "mode_reglement": 2, "reference": "CHQ-001", "code_journal": "BEU", "date_reglement": "2024-01-01", "libelle": "Règlement multiple", "tva_encaissement": False, "devise_code": 0, "cours_devise": 1.0, "date_echeance": "2024-01-31", } } class ReglementMultipleCreate(BaseModel): """Requête de règlement multiple côté VPS""" client_id: str = Field(..., description="Code client") montant_total: Decimal = Field(..., gt=0) devise_code: Optional[int] = Field(0) cours_devise: Optional[Decimal] = Field(1.0) mode_reglement: int = Field(...) code_journal: str = Field(...) date_reglement: Optional[date] = None reference: Optional[str] = Field("") libelle: Optional[str] = Field("") tva_encaissement: Optional[bool] = Field(False) # Factures spécifiques (optionnel) numeros_factures: Optional[List[str]] = Field( None, description="Si vide, règle les plus anciennes en premier" ) @field_validator("client_id", mode="before") def strip_client_id(cls, v): return v.replace("\xa0", "").strip() if v else v @field_validator("montant_total") def validate_montant(cls, v): if v <= 0: raise ValueError("Le montant doit être positif") return round(v, 2) class Config: json_schema_extra = { "example": { "client_id": "CLI000001", "montant_total": 1000.00, "mode_reglement": 2, "numeros_factures": ["FA00081", "FA00082"], "reference": "CHQ-001", "code_journal": "BEU", "date_reglement": "2024-01-01", "libelle": "Règlement multiple", "tva_encaissement": False, "devise_code": 0, "cours_devise": 1.0, "date_echeance": "2024-01-31", } }