Sage100-ws/schemas/documents/reglements.py
fanilo b6416487c0 Modified implicit error on converting type int into varchar in SQL Query in articles_data_sql
Added settle logics for invoice and trying to gather society's profile image
2026-01-15 06:38:49 +01:00

236 lines
6.1 KiB
Python

"""
Schémas Pydantic pour les règlements de factures
Module: schemas/reglements.py
"""
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"
)
@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)",
)
@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"),
]