feat(stock): add lot number and stock min/max validation to movement line

This commit is contained in:
Fanilo-Nantenaina 2025-12-17 17:08:37 +03:00
parent b799efef75
commit a729b812eb
2 changed files with 815 additions and 662 deletions

48
main.py
View file

@ -1,6 +1,6 @@
from fastapi import FastAPI, HTTPException, Header, Depends, Query from fastapi import FastAPI, HTTPException, Header, Depends, Query
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field from pydantic import BaseModel, Field, validator
from typing import Optional, List, Dict from typing import Optional, List, Dict
from datetime import datetime, date from datetime import datetime, date
from enum import Enum from enum import Enum
@ -234,8 +234,6 @@ class ArticleUpdateGatewayRequest(BaseModel):
class MouvementStockLigneRequest(BaseModel): class MouvementStockLigneRequest(BaseModel):
"""Ligne de mouvement de stock"""
article_ref: str = Field(..., description="Référence de l'article") article_ref: str = Field(..., description="Référence de l'article")
quantite: float = Field(..., gt=0, description="Quantité (>0)") quantite: float = Field(..., gt=0, description="Quantité (>0)")
depot_code: Optional[str] = Field(None, description="Code du dépôt (ex: '01')") depot_code: Optional[str] = Field(None, description="Code du dépôt (ex: '01')")
@ -243,6 +241,50 @@ class MouvementStockLigneRequest(BaseModel):
None, ge=0, description="Prix unitaire (optionnel)" None, ge=0, description="Prix unitaire (optionnel)"
) )
commentaire: Optional[str] = Field(None, description="Commentaire ligne") 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): class EntreeStockRequest(BaseModel):

File diff suppressed because it is too large Load diff