This commit is contained in:
2026-01-19 06:16:38 +01:00
parent 4ff5d3ee79
commit dcb25e0163
74 changed files with 232377 additions and 177 deletions

View File

@@ -20,7 +20,14 @@ def list_products(db: Session, skip: int = 0, limit: int = 100) -> list[models.P
def create_product(db: Session, data: schemas.ProductCreate) -> models.Product:
product = models.Product(**data.dict())
# Convertir les HttpUrl en strings pour SQLite
data_dict = data.model_dump()
if data_dict.get("url"):
data_dict["url"] = str(data_dict["url"])
if data_dict.get("url_image"):
data_dict["url_image"] = str(data_dict["url_image"])
product = models.Product(**data_dict)
db.add(product)
try:
db.commit()
@@ -62,3 +69,63 @@ def get_latest_snapshot(db: Session, product_id: int) -> models.ProductSnapshot
.order_by(models.ProductSnapshot.scrape_le.desc())
.first()
)
def get_product_with_snapshot(db: Session, product_id: int) -> dict | None:
"""Retourne un produit enrichi avec les données du dernier snapshot."""
product = get_product(db, product_id)
if not product:
return None
return _enrich_product_with_snapshot(db, product)
def list_products_with_snapshots(db: Session, skip: int = 0, limit: int = 100) -> list[dict]:
"""Retourne la liste des produits enrichis avec leurs derniers snapshots."""
products = list_products(db, skip=skip, limit=limit)
return [_enrich_product_with_snapshot(db, p) for p in products]
def _enrich_product_with_snapshot(db: Session, product: models.Product) -> dict:
"""Ajoute les données du dernier snapshot au produit."""
snapshot = get_latest_snapshot(db, product.id)
result = {
"id": product.id,
"boutique": product.boutique,
"url": str(product.url),
"asin": product.asin,
"titre": product.titre,
"url_image": str(product.url_image) if product.url_image else None,
"categorie": product.categorie,
"type": product.type,
"actif": product.actif,
"cree_le": product.cree_le,
"modifie_le": product.modifie_le,
}
if snapshot:
# Calcul de la réduction en pourcentage
reduction = None
if snapshot.prix_actuel and snapshot.prix_conseille:
reduction = round((1 - snapshot.prix_actuel / snapshot.prix_conseille) * 100)
result.update(
{
"prix_actuel": snapshot.prix_actuel,
"prix_conseille": snapshot.prix_conseille,
"prix_min_30j": snapshot.prix_min_30j,
"reduction_pourcent": reduction,
"etat_stock": snapshot.etat_stock,
"en_stock": snapshot.en_stock,
"note": snapshot.note,
"nombre_avis": snapshot.nombre_avis,
"prime": snapshot.prime,
"choix_amazon": snapshot.choix_amazon,
"offre_limitee": snapshot.offre_limitee,
"exclusivite_amazon": snapshot.exclusivite_amazon,
"dernier_scrape": snapshot.scrape_le,
"statut_scrap": snapshot.statut_scrap,
}
)
return result

View File

@@ -61,3 +61,29 @@ class ProductSnapshotRead(ProductSnapshotBase):
class Config:
orm_mode = True
class ProductWithSnapshot(ProductBase):
"""Produit enrichi avec les données du dernier snapshot."""
id: int
cree_le: datetime
modifie_le: datetime
# Données du dernier snapshot
prix_actuel: Optional[float] = None
prix_conseille: Optional[float] = None
prix_min_30j: Optional[float] = None
reduction_pourcent: Optional[int] = None
etat_stock: Optional[str] = None
en_stock: Optional[bool] = None
note: Optional[float] = None
nombre_avis: Optional[int] = None
prime: Optional[bool] = None
choix_amazon: Optional[bool] = None
offre_limitee: Optional[bool] = None
exclusivite_amazon: Optional[bool] = None
dernier_scrape: Optional[datetime] = None
statut_scrap: Optional[str] = None
class Config:
orm_mode = True