update FlowChart

This commit is contained in:
fatemeh sane
2026-10-20 21:05:37 +03:30
parent 692343423c
commit 41f93acec5
6 changed files with 644 additions and 272 deletions
+28 -10
View File
@@ -96,14 +96,29 @@ async def dashboard_scope(
def _what_filters(
material_id: uuid.UUID | None,
material_id: str | None,
brand_id: uuid.UUID | None,
specs_hash: str | None,
spec_id: str | None = None,
) -> dict:
"""دامنه‌ی «چه چیزی» را به پارامترهای سرویس تبدیل می‌کند.
شناسه‌ی ماده اگر UUID معتبر باشد → دامنه‌ی همان ماده (همه‌ی مشخصات آن).
اگر مقدار ارسالی UUID نباشد (یعنی شناسه‌ی مشخصه فرستاده شده) یا spec_id
صریح بیاید → دامنه به همان مشخصه محدود می‌شود (specs_hash).
"""
resolved_material: uuid.UUID | None = None
resolved_specs = specs_hash or spec_id
if material_id:
try:
resolved_material = uuid.UUID(str(material_id))
except (ValueError, AttributeError, TypeError):
# شناسه‌ی مشخصه (نه UUID ماده) — به‌عنوان دامنه‌ی مشخصه استفاده می‌شود
resolved_specs = resolved_specs or str(material_id)
return {
"material_id": material_id,
"material_id": resolved_material,
"brand_id": brand_id,
"specs_hash": specs_hash,
"specs_hash": resolved_specs,
}
@@ -117,16 +132,17 @@ async def dashboard_filters(db: AsyncSession = Depends(get_db)):
async def inventory_drilldown(
scope: DashboardScope = Depends(dashboard_scope),
db: AsyncSession = Depends(get_db),
material_id: uuid.UUID | None = Query(default=None),
material_id: str | None = Query(default=None, description="UUID ماده یا شناسه‌ی مشخصه"),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
spec_id: str | None = Query(default=None, description="دامنه‌ی یک مشخصه‌ی خاص"),
):
"""Drill-down matrix: کل سازمان → پروژه → انبار (per-unit aggregates)."""
return await dashboard_service.inventory_drilldown(
db,
project_ids=scope.project_ids,
project_id=scope.project_id,
**_what_filters(material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash, spec_id),
)
@@ -136,9 +152,10 @@ 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),
material_id: uuid.UUID | None = Query(default=None),
material_id: str | None = Query(default=None, description="UUID ماده یا شناسه‌ی مشخصه"),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
spec_id: str | None = Query(default=None, description="دامنه‌ی یک مشخصه‌ی خاص"),
):
"""Dead stock: موجودی مثبت بدون هیچ تراکنشی در بازه‌ی رکود."""
return await dashboard_service.dead_stock(
@@ -147,7 +164,7 @@ async def dead_stock(
project_id=scope.project_id,
idle_days=idle_days,
limit=limit,
**_what_filters(material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash, spec_id),
)
@@ -157,10 +174,11 @@ async def inventory_flow(
db: AsyncSession = Depends(get_db),
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),
material_id: uuid.UUID | None = Query(default=None),
warehouse_id: uuid.UUID | None = Query(default=None, description="اختیاری — بدون آن همه‌ی انبارها"),
material_id: str | None = Query(default=None, description="UUID ماده یا شناسه‌ی مشخصه"),
brand_id: uuid.UUID | None = Query(default=None),
specs_hash: str | None = Query(default=None),
spec_id: str | None = Query(default=None, description="دامنه‌ی یک مشخصه‌ی خاص"),
):
"""Daily flow series: ورود / خروج (با لایه‌ی ضایعات) / برگشت / مانده."""
today = datetime.now(dashboard_service.TEHRAN).date()
@@ -177,7 +195,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(material_id, brand_id, specs_hash),
**_what_filters(material_id, brand_id, specs_hash, spec_id),
)