feat(dashboard): implement floating waterfall inventory bridge with step-line balance

This commit is contained in:
fatemeh sane
2026-10-15 15:21:08 +03:30
parent eedb821e3b
commit 692343423c
8 changed files with 492 additions and 230 deletions
+4 -9
View File
@@ -96,13 +96,11 @@ async def dashboard_scope(
def _what_filters(
category_id: uuid.UUID | None,
material_id: uuid.UUID | None,
brand_id: uuid.UUID | None,
specs_hash: str | None,
) -> dict:
return {
"category_id": category_id,
"material_id": material_id,
"brand_id": brand_id,
"specs_hash": specs_hash,
@@ -111,7 +109,7 @@ def _what_filters(
@router.get("/filters")
async def dashboard_filters(db: AsyncSession = Depends(get_db)):
"""Cascading options for the global filter bar (Category→Material→Brand→Specs)."""
"""Options for the global filter bar (Material→Brand→Specs)."""
return await dashboard_service.filter_options(db)
@@ -119,7 +117,6 @@ async def dashboard_filters(db: AsyncSession = Depends(get_db)):
async def inventory_drilldown(
scope: DashboardScope = Depends(dashboard_scope),
db: AsyncSession = Depends(get_db),
category_id: uuid.UUID | None = Query(default=None),
material_id: uuid.UUID | None = Query(default=None),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
@@ -129,7 +126,7 @@ async def inventory_drilldown(
db,
project_ids=scope.project_ids,
project_id=scope.project_id,
**_what_filters(category_id, material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash),
)
@@ -139,7 +136,6 @@ async def dead_stock(
db: AsyncSession = Depends(get_db),
idle_days: int = Query(default=60, ge=1, le=365, description="آستانه رکود (روز)"),
limit: int = Query(default=200, ge=1, le=1000),
category_id: uuid.UUID | None = Query(default=None),
material_id: uuid.UUID | None = Query(default=None),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
@@ -151,7 +147,7 @@ async def dead_stock(
project_id=scope.project_id,
idle_days=idle_days,
limit=limit,
**_what_filters(category_id, material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash),
)
@@ -162,7 +158,6 @@ async def inventory_flow(
date_from: date_cls | None = Query(default=None, description="از تاریخ (ISO، پیش‌فرض ۳۰ روز اخیر)"),
date_to: date_cls | None = Query(default=None, description="تا تاریخ (ISO، انحصاری)"),
warehouse_id: uuid.UUID | None = Query(default=None),
category_id: uuid.UUID | None = Query(default=None),
material_id: uuid.UUID | None = Query(default=None),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
@@ -182,7 +177,7 @@ async def inventory_flow(
date_from=datetime.combine(date_from, datetime.min.time(), tzinfo=dashboard_service.TEHRAN),
date_to=datetime.combine(date_to, datetime.min.time(), tzinfo=dashboard_service.TEHRAN),
warehouse_id=warehouse_id,
**_what_filters(category_id, material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash),
)