Add Polaris FastAPI backend: models/schemas, pricing+scoring+order router, importer, Celery tasks, API routers, seed script
This commit is contained in:
72
backend/app/engines/inventory.py
Normal file
72
backend/app/engines/inventory.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""Inventory sync engine.
|
||||
|
||||
Refreshes supplier_products inventory from each adapter, writes inventory_history,
|
||||
and flags zero/unavailable stock (pauses published products + audit log alert).
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from app.engines.suppliers.base import build_adapter
|
||||
from app.models import AuditLog, InventoryHistory, Supplier, SupplierProduct
|
||||
|
||||
|
||||
def sync_inventory(db, supplier=None):
|
||||
if supplier is not None:
|
||||
suppliers = [supplier]
|
||||
else:
|
||||
suppliers = db.query(Supplier).filter(Supplier.status == "active").all()
|
||||
|
||||
stats = {"suppliers": len(suppliers), "checked": 0, "changed": 0, "zeroed": 0}
|
||||
|
||||
for s in suppliers:
|
||||
try:
|
||||
adapter = build_adapter(s)
|
||||
current = {r["supplier_sku"]: int(r["inventory"]) for r in adapter.get_inventory()}
|
||||
except Exception as exc: # noqa: BLE001 — log and continue to next supplier
|
||||
db.add(
|
||||
AuditLog(
|
||||
actor="inventory",
|
||||
action="sync_failed",
|
||||
entity="supplier",
|
||||
entity_id=str(s.id),
|
||||
detail={"supplier": s.name, "error": str(exc)},
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
||||
for sp in db.query(SupplierProduct).filter(SupplierProduct.supplier_id == s.id).all():
|
||||
stats["checked"] += 1
|
||||
new_value = current.get(sp.supplier_sku)
|
||||
if new_value is None:
|
||||
continue
|
||||
|
||||
if sp.supplier_inventory != new_value:
|
||||
stats["changed"] += 1
|
||||
sp.supplier_inventory = new_value
|
||||
sp.last_updated = datetime.now(timezone.utc)
|
||||
db.add(InventoryHistory(supplier_product_id=sp.id, inventory=new_value))
|
||||
|
||||
if new_value <= 0:
|
||||
stats["zeroed"] += 1
|
||||
db.add(
|
||||
AuditLog(
|
||||
actor="inventory",
|
||||
action="inventory_zero",
|
||||
entity="supplier_product",
|
||||
entity_id=str(sp.id),
|
||||
detail={"supplier_sku": sp.supplier_sku, "inventory": 0},
|
||||
)
|
||||
)
|
||||
if sp.product is not None and sp.product.status == "published":
|
||||
sp.product.status = "paused"
|
||||
db.add(
|
||||
AuditLog(
|
||||
actor="inventory",
|
||||
action="product_paused_zero_inventory",
|
||||
entity="product",
|
||||
entity_id=str(sp.product.id),
|
||||
detail={"sku": sp.product.sku},
|
||||
)
|
||||
)
|
||||
|
||||
db.commit()
|
||||
return stats
|
||||
Reference in New Issue
Block a user