feat(dashboard): implement floating waterfall inventory bridge with step-line balance
This commit is contained in:
@@ -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),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user