238 lines
6.4 KiB
Python
238 lines
6.4 KiB
Python
from pydantic import BaseModel, Field, field_validator
|
|
from typing import List, Optional
|
|
from datetime import datetime
|
|
from enum import IntEnum
|
|
|
|
|
|
class ModeReglement:
|
|
"""Modes de règlement Sage 100c"""
|
|
|
|
VIREMENT = 1
|
|
CHEQUE = 2
|
|
TRAITE = 3
|
|
CARTE_BANCAIRE = 4
|
|
LCR = 5
|
|
PRELEVEMENT = 6
|
|
ESPECES = 7
|
|
|
|
LIBELLES = {
|
|
1: "Virement",
|
|
2: "Chèque",
|
|
3: "Traite",
|
|
4: "Carte bancaire",
|
|
5: "LCR",
|
|
6: "Prélèvement",
|
|
7: "Espèces",
|
|
}
|
|
|
|
@classmethod
|
|
def get_libelle(cls, code: int) -> str:
|
|
return cls.LIBELLES.get(code, f"Mode {code}")
|
|
|
|
|
|
class ModeReglementEnum(IntEnum):
|
|
"""Modes de règlement Sage 100c"""
|
|
|
|
VIREMENT = 1
|
|
CHEQUE = 2
|
|
TRAITE = 3
|
|
CARTE_BANCAIRE = 4
|
|
LCR = 5
|
|
PRELEVEMENT = 6
|
|
ESPECES = 7
|
|
|
|
|
|
class ReglementFactureRequest(BaseModel):
|
|
"""Requête de règlement d'une facture"""
|
|
|
|
montant: float = Field(..., gt=0, description="Montant du règlement")
|
|
mode_reglement: int = Field(
|
|
default=2,
|
|
ge=1,
|
|
le=7,
|
|
description="Mode de règlement (1=Virement, 2=Chèque, 3=Traite, 4=CB, 5=LCR, 6=Prélèvement, 7=Espèces)",
|
|
)
|
|
date_reglement: Optional[datetime] = Field(
|
|
default=None, description="Date du règlement (défaut: aujourd'hui)"
|
|
)
|
|
reference: Optional[str] = Field(
|
|
default="", max_length=35, description="Référence du règlement"
|
|
)
|
|
libelle: Optional[str] = Field(
|
|
default="", max_length=69, description="Libellé du règlement"
|
|
)
|
|
code_journal: str = Field(
|
|
default="BEU", max_length=6, description="Code journal comptable"
|
|
)
|
|
devise_code: Optional[int] = Field(0)
|
|
cours_devise: Optional[float] = Field(1.0)
|
|
tva_encaissement: Optional[bool] = Field(False)
|
|
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,
|
|
"date_reglement": "2026-01-06T00:00:00",
|
|
"reference": "CHQ-001",
|
|
"libelle": "Règlement facture",
|
|
"code_journal": "BEU",
|
|
}
|
|
}
|
|
|
|
|
|
class ReglementMultipleRequest(BaseModel):
|
|
"""Requête de règlement multiple pour un client"""
|
|
|
|
client_code: str = Field(..., description="Code client")
|
|
montant_total: float = Field(..., gt=0, description="Montant total à régler")
|
|
mode_reglement: int = Field(default=2, ge=1, le=7)
|
|
date_reglement: Optional[datetime] = None
|
|
reference: Optional[str] = Field(default="", max_length=35)
|
|
libelle: Optional[str] = Field(default="", max_length=69)
|
|
code_journal: str = Field(default="BEU", max_length=6)
|
|
numeros_factures: Optional[List[str]] = Field(
|
|
default=None,
|
|
description="Liste des factures à régler (sinon: plus anciennes d'abord)",
|
|
)
|
|
devise_code: Optional[int] = Field(0)
|
|
cours_devise: Optional[float] = Field(1.0)
|
|
tva_encaissement: Optional[bool] = Field(False)
|
|
|
|
@field_validator("client_code", mode="before")
|
|
def strip_client_code(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_code": "CLI000001",
|
|
"montant_total": 1000.00,
|
|
"mode_reglement": 2,
|
|
"reference": "VIR-MULTI-001",
|
|
"numeros_factures": ["FA00081", "FA00082"],
|
|
}
|
|
}
|
|
|
|
|
|
class ReglementResponse(BaseModel):
|
|
"""Réponse d'un règlement effectué"""
|
|
|
|
numero_facture: str
|
|
numero_reglement: Optional[str]
|
|
montant_regle: float
|
|
date_reglement: str
|
|
mode_reglement: int
|
|
mode_reglement_libelle: str
|
|
reference: str
|
|
libelle: str
|
|
code_journal: str
|
|
total_facture: float
|
|
solde_restant: float
|
|
facture_soldee: bool
|
|
client_code: str
|
|
|
|
|
|
class ReglementMultipleResponse(BaseModel):
|
|
"""Réponse d'un règlement multiple"""
|
|
|
|
client_code: str
|
|
montant_demande: float
|
|
montant_effectif: float
|
|
nb_factures_reglees: int
|
|
nb_factures_soldees: int
|
|
date_reglement: str
|
|
mode_reglement: int
|
|
mode_reglement_libelle: str
|
|
reference: str
|
|
reglements: List[ReglementResponse]
|
|
|
|
|
|
class ReglementDetail(BaseModel):
|
|
"""Détail d'un règlement"""
|
|
|
|
id: int
|
|
date: Optional[str]
|
|
montant: float
|
|
reference: str
|
|
libelle: str
|
|
mode_reglement: int
|
|
mode_reglement_libelle: str
|
|
code_journal: str
|
|
|
|
|
|
class ReglementsFactureResponse(BaseModel):
|
|
"""Réponse: tous les règlements d'une facture"""
|
|
|
|
numero_facture: str
|
|
client_code: str
|
|
date_facture: Optional[str]
|
|
reference: str
|
|
total_ttc: float
|
|
total_regle: float
|
|
solde_restant: float
|
|
est_soldee: bool
|
|
nb_reglements: int
|
|
reglements: List[ReglementDetail]
|
|
|
|
|
|
class FactureAvecReglements(BaseModel):
|
|
"""Facture avec ses règlements"""
|
|
|
|
numero_facture: str
|
|
date_facture: Optional[str]
|
|
total_ttc: float
|
|
reference: str
|
|
total_regle: float
|
|
solde_restant: float
|
|
est_soldee: bool
|
|
nb_reglements: int
|
|
reglements: List[ReglementDetail]
|
|
|
|
|
|
class ReglementsClientResponse(BaseModel):
|
|
"""Réponse: tous les règlements d'un client"""
|
|
|
|
client_code: str
|
|
client_intitule: str
|
|
nb_factures: int
|
|
nb_factures_soldees: int
|
|
nb_factures_en_cours: int
|
|
total_factures: float
|
|
total_regle: float
|
|
solde_global: float
|
|
factures: List[FactureAvecReglements]
|
|
|
|
|
|
class ModeReglementInfo(BaseModel):
|
|
"""Information sur un mode de règlement"""
|
|
|
|
code: int
|
|
libelle: str
|
|
|
|
|
|
class ModesReglementResponse(BaseModel):
|
|
"""Liste des modes de règlement disponibles"""
|
|
|
|
modes: List[ModeReglementInfo] = [
|
|
ModeReglementInfo(code=1, libelle="Virement"),
|
|
ModeReglementInfo(code=2, libelle="Chèque"),
|
|
ModeReglementInfo(code=3, libelle="Traite"),
|
|
ModeReglementInfo(code=4, libelle="Carte bancaire"),
|
|
ModeReglementInfo(code=5, libelle="LCR"),
|
|
ModeReglementInfo(code=6, libelle="Prélèvement"),
|
|
ModeReglementInfo(code=7, libelle="Espèces"),
|
|
]
|