111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
|
|
from pydantic import BaseModel, Field, validator, EmailStr, field_validator
|
|
from typing import Optional, List, Dict
|
|
from enum import Enum, IntEnum
|
|
from datetime import datetime, date
|
|
|
|
class ArticleCreateRequest(BaseModel):
|
|
reference: str = Field(..., description="Référence article (max 18 car)")
|
|
designation: str = Field(..., description="Désignation (max 69 car)")
|
|
famille: Optional[str] = Field(None, description="Code famille")
|
|
prix_vente: Optional[float] = Field(None, ge=0, description="Prix vente HT")
|
|
prix_achat: Optional[float] = Field(None, ge=0, description="Prix achat HT")
|
|
stock_reel: Optional[float] = Field(None, ge=0, description="Stock initial")
|
|
stock_mini: Optional[float] = Field(None, ge=0, description="Stock minimum")
|
|
code_ean: Optional[str] = Field(None, description="Code-barres EAN")
|
|
unite_vente: Optional[str] = Field("UN", description="Unité de vente")
|
|
tva_code: Optional[str] = Field(None, description="Code TVA")
|
|
description: Optional[str] = Field(None, description="Description/Commentaire")
|
|
|
|
|
|
class ArticleUpdateGatewayRequest(BaseModel):
|
|
"""Modèle pour modification article côté gateway"""
|
|
|
|
reference: str
|
|
article_data: Dict
|
|
|
|
|
|
class MouvementStockLigneRequest(BaseModel):
|
|
article_ref: str = Field(..., description="Référence de l'article")
|
|
quantite: float = Field(..., gt=0, description="Quantité (>0)")
|
|
depot_code: Optional[str] = Field(None, description="Code du dépôt (ex: '01')")
|
|
prix_unitaire: Optional[float] = Field(
|
|
None, ge=0, description="Prix unitaire (optionnel)"
|
|
)
|
|
commentaire: Optional[str] = Field(None, description="Commentaire ligne")
|
|
numero_lot: Optional[str] = Field(
|
|
None, description="Numéro de lot (pour FIFO/LIFO)"
|
|
)
|
|
stock_mini: Optional[float] = Field(
|
|
None,
|
|
ge=0,
|
|
description="""Stock minimum à définir pour cet article.
|
|
Si fourni, met à jour AS_QteMini dans F_ARTSTOCK.
|
|
Laisser None pour ne pas modifier.""",
|
|
)
|
|
stock_maxi: Optional[float] = Field(
|
|
None,
|
|
ge=0,
|
|
description="""Stock maximum à définir pour cet article.
|
|
Doit être > stock_mini si les deux sont fournis.""",
|
|
)
|
|
|
|
class Config:
|
|
schema_extra = {
|
|
"example": {
|
|
"article_ref": "ARTS-001",
|
|
"quantite": 50.0,
|
|
"depot_code": "01",
|
|
"prix_unitaire": 100.0,
|
|
"commentaire": "Réapprovisionnement",
|
|
"numero_lot": "LOT20241217",
|
|
"stock_mini": 10.0,
|
|
"stock_maxi": 200.0,
|
|
}
|
|
}
|
|
|
|
@validator("stock_maxi")
|
|
def validate_stock_maxi(cls, v, values):
|
|
"""Valide que stock_maxi > stock_mini si les deux sont fournis"""
|
|
if (
|
|
v is not None
|
|
and "stock_mini" in values
|
|
and values["stock_mini"] is not None
|
|
):
|
|
if v <= values["stock_mini"]:
|
|
raise ValueError(
|
|
"stock_maxi doit être strictement supérieur à stock_mini"
|
|
)
|
|
return v
|
|
|
|
|
|
class EntreeStockRequest(BaseModel):
|
|
"""Création d'un bon d'entrée en stock"""
|
|
|
|
date_entree: Optional[date] = Field(
|
|
None, description="Date du mouvement (aujourd'hui par défaut)"
|
|
)
|
|
reference: Optional[str] = Field(None, description="Référence externe")
|
|
depot_code: Optional[str] = Field(
|
|
None, description="Dépôt principal (si applicable)"
|
|
)
|
|
lignes: List[MouvementStockLigneRequest] = Field(
|
|
..., min_items=1, description="Lignes du mouvement"
|
|
)
|
|
commentaire: Optional[str] = Field(None, description="Commentaire général")
|
|
|
|
|
|
class SortieStockRequest(BaseModel):
|
|
"""Création d'un bon de sortie de stock"""
|
|
|
|
date_sortie: Optional[date] = Field(
|
|
None, description="Date du mouvement (aujourd'hui par défaut)"
|
|
)
|
|
reference: Optional[str] = Field(None, description="Référence externe")
|
|
depot_code: Optional[str] = Field(
|
|
None, description="Dépôt principal (si applicable)"
|
|
)
|
|
lignes: List[MouvementStockLigneRequest] = Field(
|
|
..., min_items=1, description="Lignes du mouvement"
|
|
)
|
|
commentaire: Optional[str] = Field(None, description="Commentaire général")
|