from typing import Annotated from fastapi import Path, Query, Request, Response from sqlalchemy.ext.asyncio import AsyncSession from common.annotation.log_annotation import Log from common.aspect.db_seesion import DBSessionDependency from common.aspect.interface_auth import UserInterfaceAuthDependency from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency from common.enums import BusinessType from common.router import APIRouterPro from common.vo import DataResponseModel, PageResponseModel, ResponseBaseModel from module_admin.entity.vo.user_vo import CurrentUserModel from module_business.dependency.test_batch_dependency import TestBatchScopeDependency from module_business.domain.test_batch_scope import TestBatchScope from module_business.entity.vo.operation_vo import ( BusinessOptionModel, ConfirmCommandModel, InboundCreateModel, InboundModel, InboundPageQueryModel, InboundScanQueryModel, InboundUpdateModel, PalletScanResponseModel, ) from module_business.service.inbound_service import InboundService from utils.response_util import ResponseUtil inbound_controller = APIRouterPro( prefix='/business/inbound', tags=['业务管理-仓库入库'], dependencies=[PreAuthDependency()], ) @inbound_controller.get( '/list', summary='获取首次入库单分页列表接口', description='按当前用户仓库数据范围获取首次入库单分页列表', response_model=PageResponseModel[InboundModel], dependencies=[UserInterfaceAuthDependency('business:inbound:list')], ) async def get_business_inbound_list( request: Request, inbound_page_query: Annotated[InboundPageQueryModel, Query()], query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency()], ) -> Response: result = await InboundService.get_inbound_list_services( query_db, inbound_page_query, current_user, test_scope, is_page=True, ) return ResponseUtil.success(model_content=result) @inbound_controller.get( '/warehouse-options', summary='获取首次入库仓库选项接口', description='仅返回当前用户有权访问的启用仓库', response_model=DataResponseModel[list[BusinessOptionModel]], dependencies=[UserInterfaceAuthDependency('business:inbound:query')], ) async def get_business_inbound_warehouse_options( request: Request, query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency()], ) -> Response: result = await InboundService.get_warehouse_options_services(query_db, current_user, test_scope) return ResponseUtil.success(data=result) @inbound_controller.get( '/scan/{qr_token:path}', summary='扫描首次入库托盘接口', description='查询托盘是否可加入所选仓库的首次入库单', response_model=DataResponseModel[PalletScanResponseModel], dependencies=[UserInterfaceAuthDependency('business:inbound:query')], ) @Log( title='扫码操作', business_type=BusinessType.OTHER, request_log_mode='none', response_log_mode='summary', oper_url_mode='route', ) async def scan_business_inbound_pallet( request: Request, qr_token: Annotated[ str, Path(min_length=1, max_length=128, pattern=r'\S', description='二维码固定标识'), ], inbound_scan_query: Annotated[InboundScanQueryModel, Query()], query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency()], ) -> Response: result = await InboundService.scan_inbound_pallet_services( query_db, qr_token, inbound_scan_query, current_user, test_scope, ) return ResponseUtil.success(data=result) @inbound_controller.get( '/{inbound_id}', summary='获取首次入库单详情接口', description='按仓库数据范围获取指定首次入库单详情', response_model=DataResponseModel[InboundModel], dependencies=[UserInterfaceAuthDependency('business:inbound:query')], ) async def query_detail_business_inbound( request: Request, inbound_id: Annotated[int, Path(gt=0, description='入库单ID')], query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency()], ) -> Response: result = await InboundService.inbound_detail_services(query_db, inbound_id, current_user, test_scope) return ResponseUtil.success(data=result) @inbound_controller.post( '', summary='新增首次入库草稿接口', description='新增空托盘首次入库草稿', response_model=ResponseBaseModel, dependencies=[UserInterfaceAuthDependency('business:inbound:add')], ) @Log(title='仓库入库', business_type=BusinessType.INSERT) async def add_business_inbound( request: Request, add_inbound: InboundCreateModel, query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency(write=True)], ) -> Response: result = await InboundService.add_inbound_services(query_db, add_inbound, current_user, test_scope) return ResponseUtil.success(msg=result.message) @inbound_controller.put( '', summary='编辑首次入库草稿接口', description='编辑尚未确认的首次入库草稿', response_model=ResponseBaseModel, dependencies=[UserInterfaceAuthDependency('business:inbound:edit')], ) @Log(title='仓库入库', business_type=BusinessType.UPDATE) async def edit_business_inbound( request: Request, edit_inbound: InboundUpdateModel, query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency(write=True)], ) -> Response: result = await InboundService.edit_inbound_services(query_db, edit_inbound, current_user, test_scope) return ResponseUtil.success(msg=result.message) @inbound_controller.delete( '/{inbound_ids}', summary='不支持单条物理删除,请通过测试数据批次清理', description='不支持单条物理删除,请通过测试数据批次清理', response_model=ResponseBaseModel, dependencies=[UserInterfaceAuthDependency('business:inbound:list')], ) @Log(title='仓库入库', business_type=BusinessType.DELETE) async def delete_business_inbound( request: Request, inbound_ids: Annotated[ str, Path(pattern=r'^[1-9]\d*(,[1-9]\d*)*$', description='需要删除的入库单ID'), ], query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency(write=True)], ) -> Response: result = await InboundService.delete_inbound_services( query_db, [int(inbound_id) for inbound_id in inbound_ids.split(',')], current_user, test_scope, ) return ResponseUtil.success(msg=result.message) @inbound_controller.put( '/{inbound_id}/confirm', summary='确认首次入库单接口', description='原子确认整张首次入库单并追加托盘流转事件', response_model=ResponseBaseModel, dependencies=[UserInterfaceAuthDependency('business:inbound:confirm')], ) @Log(title='仓库入库', business_type=BusinessType.UPDATE) async def confirm_business_inbound( request: Request, inbound_id: Annotated[int, Path(gt=0, description='入库单ID')], confirm_command: ConfirmCommandModel, query_db: Annotated[AsyncSession, DBSessionDependency()], current_user: Annotated[CurrentUserModel, CurrentUserDependency()], test_scope: Annotated[TestBatchScope, TestBatchScopeDependency(write=True)], ) -> Response: result = await InboundService.confirm_inbound_services( query_db, inbound_id, confirm_command, current_user, test_scope, ) return ResponseUtil.success(msg=result.message)