213 lines
7.3 KiB
Python
213 lines
7.3 KiB
Python
from typing import Any, TypeVar
|
|
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from common.vo import PageModel
|
|
from exceptions.exception import ServiceException
|
|
from module_admin.entity.vo.user_vo import CurrentUserModel
|
|
from module_business.dao.access_dao import AccessDao
|
|
from module_business.dao.report_dao import ReportDao
|
|
from module_business.domain.test_batch_scope import TestBatchScope
|
|
from module_business.entity.vo.report_vo import (
|
|
ConsumptionReportModel,
|
|
ConsumptionReportQueryModel,
|
|
FillingReportModel,
|
|
FillingReportQueryModel,
|
|
PalletInventoryReportModel,
|
|
PalletInventoryReportQueryModel,
|
|
PalletTraceReportModel,
|
|
PalletTraceReportQueryModel,
|
|
ReturnReportModel,
|
|
ReturnReportQueryModel,
|
|
ShipmentReportModel,
|
|
ShipmentReportQueryModel,
|
|
)
|
|
|
|
RowModelT = TypeVar('RowModelT', bound=BaseModel)
|
|
|
|
|
|
class ReportService:
|
|
"""六类只读业务报表服务。"""
|
|
|
|
@staticmethod
|
|
def _is_admin(current_user: CurrentUserModel) -> bool:
|
|
return bool(current_user.user and current_user.user.admin)
|
|
|
|
@classmethod
|
|
def _user_id(cls, current_user: CurrentUserModel) -> int:
|
|
if current_user.user is None or current_user.user.user_id is None:
|
|
raise ServiceException(message='当前用户信息无效')
|
|
return current_user.user.user_id
|
|
|
|
@classmethod
|
|
async def _warehouse_scope(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> list[int] | None:
|
|
if cls._is_admin(current_user):
|
|
return None
|
|
warehouse_ids = await AccessDao.list_user_warehouse_ids(query_db, cls._user_id(current_user), test_scope)
|
|
return sorted(set(warehouse_ids))
|
|
|
|
@classmethod
|
|
async def _site_scope(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> list[int] | None:
|
|
if cls._is_admin(current_user):
|
|
return None
|
|
site_ids = await AccessDao.list_user_site_ids(query_db, cls._user_id(current_user), test_scope)
|
|
return sorted(set(site_ids))
|
|
|
|
@classmethod
|
|
async def _scopes(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> tuple[list[int] | None, list[int] | None]:
|
|
if cls._is_admin(current_user):
|
|
return None, None
|
|
return (
|
|
await cls._warehouse_scope(query_db, current_user, test_scope),
|
|
await cls._site_scope(query_db, current_user, test_scope),
|
|
)
|
|
|
|
@staticmethod
|
|
def _empty_page(query_object: Any) -> PageModel:
|
|
return PageModel(
|
|
rows=[],
|
|
pageNum=query_object.page_num,
|
|
pageSize=query_object.page_size,
|
|
total=0,
|
|
hasNext=False,
|
|
)
|
|
|
|
@staticmethod
|
|
def _convert_page(page: PageModel, row_model: type[RowModelT]) -> PageModel[RowModelT]:
|
|
rows = [row_model.model_validate(row) for row in page.rows]
|
|
return page.model_copy(update={'rows': rows})
|
|
|
|
@classmethod
|
|
async def get_pallet_inventory_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: PalletInventoryReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[PalletInventoryReportModel]:
|
|
warehouse_ids, site_ids = await cls._scopes(query_db, current_user, test_scope)
|
|
if warehouse_ids == [] and site_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_pallet_inventory_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
warehouse_ids=warehouse_ids,
|
|
site_ids=site_ids,
|
|
)
|
|
return cls._convert_page(page, PalletInventoryReportModel)
|
|
|
|
@classmethod
|
|
async def get_filling_report_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: FillingReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[FillingReportModel]:
|
|
warehouse_ids = await cls._warehouse_scope(query_db, current_user, test_scope)
|
|
if warehouse_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_filling_report_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
warehouse_ids=warehouse_ids,
|
|
)
|
|
return cls._convert_page(page, FillingReportModel)
|
|
|
|
@classmethod
|
|
async def get_shipment_report_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: ShipmentReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[ShipmentReportModel]:
|
|
warehouse_ids, site_ids = await cls._scopes(query_db, current_user, test_scope)
|
|
if warehouse_ids == [] or site_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_shipment_report_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
warehouse_ids=warehouse_ids,
|
|
site_ids=site_ids,
|
|
)
|
|
return cls._convert_page(page, ShipmentReportModel)
|
|
|
|
@classmethod
|
|
async def get_consumption_report_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: ConsumptionReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[ConsumptionReportModel]:
|
|
site_ids = await cls._site_scope(query_db, current_user, test_scope)
|
|
if site_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_consumption_report_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
site_ids=site_ids,
|
|
)
|
|
return cls._convert_page(page, ConsumptionReportModel)
|
|
|
|
@classmethod
|
|
async def get_return_report_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: ReturnReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[ReturnReportModel]:
|
|
warehouse_ids, site_ids = await cls._scopes(query_db, current_user, test_scope)
|
|
if warehouse_ids == [] and site_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_return_report_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
site_ids=site_ids,
|
|
warehouse_ids=warehouse_ids,
|
|
)
|
|
return cls._convert_page(page, ReturnReportModel)
|
|
|
|
@classmethod
|
|
async def get_pallet_trace_list_services(
|
|
cls,
|
|
query_db: AsyncSession,
|
|
query_object: PalletTraceReportQueryModel,
|
|
current_user: CurrentUserModel,
|
|
test_scope: TestBatchScope,
|
|
) -> PageModel[PalletTraceReportModel]:
|
|
warehouse_ids, site_ids = await cls._scopes(query_db, current_user, test_scope)
|
|
if warehouse_ids == [] and site_ids == []:
|
|
return cls._empty_page(query_object)
|
|
page = await ReportDao.get_pallet_trace_list(
|
|
query_db,
|
|
query_object,
|
|
test_scope,
|
|
warehouse_ids=warehouse_ids,
|
|
site_ids=site_ids,
|
|
)
|
|
return cls._convert_page(page, PalletTraceReportModel)
|