ETest-Vue-FastAPI/ruoyi-fastapi-backend/module_admin/service/warehouse_receipt_service.py

228 lines
10 KiB
Python
Raw Normal View History

2025-12-19 10:12:59 +08:00
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.dao.warehouse_receipt_dao import WarehouseReceiptDao
from module_admin.dao.warehouse_sample_dao import WarehouseSampleDao
from module_admin.entity.do.warehouse_receipt_do import WarehouseReceipt
from module_admin.entity.do.warehouse_sample_do import WarehouseSample
from module_admin.entity.vo.warehouse_receipt_vo import (
WarehouseReceiptModel, WarehouseReceiptPageQueryModel,
AddWarehouseReceiptModel, EditWarehouseReceiptModel, DeleteWarehouseReceiptModel
)
from module_admin.entity.vo.common_vo import CrudResponseModel
from exceptions.exception import ServiceException
from utils.common_util import CamelCaseUtil
from datetime import datetime
class WarehouseReceiptService:
"""
入库单业务逻辑层
"""
@classmethod
async def get_receipt_list(cls, db: AsyncSession, query_object: WarehouseReceiptPageQueryModel, is_page: bool = False):
"""
获取入库单列表
"""
try:
receipt_list = await WarehouseReceiptDao.get_receipt_list(db, query_object, is_page)
# 转换为字典并添加样品数量
result_list = []
for receipt in receipt_list:
receipt_dict = CamelCaseUtil.transform_result(receipt)
# 获取样品数量
sample_count = await WarehouseSampleDao.get_sample_count_by_receipt(db, receipt.receipt_id)
receipt_dict['sample_count'] = sample_count if sample_count else 0
result_list.append(receipt_dict)
if is_page:
total = await WarehouseReceiptDao.get_receipt_count(db, query_object)
return {'rows': result_list, 'total': total if total else 0}
else:
return result_list
except Exception as e:
raise ServiceException(message=f'获取入库单列表失败: {str(e)}')
2025-12-19 10:12:59 +08:00
@classmethod
async def get_receipt_detail(cls, db: AsyncSession, receipt_id: int):
"""
获取入库单详情
"""
try:
receipt = await WarehouseReceiptDao.get_receipt_by_id(db, receipt_id)
if not receipt:
raise ServiceException(message='入库单不存在')
receipt_dict = CamelCaseUtil.transform_result(receipt)
# 获取样品列表
from module_admin.entity.vo.warehouse_sample_vo import WarehouseSamplePageQueryModel
sample_query = WarehouseSamplePageQueryModel(receipt_id=receipt.receipt_id, page_num=1, page_size=1000)
samples = await WarehouseSampleDao.get_sample_list(db, sample_query, is_page=False)
# 转换样品列表
samples_list = [CamelCaseUtil.transform_result(sample) for sample in samples] if samples else []
receipt_dict['samples'] = samples_list
receipt_dict['sample_count'] = len(samples_list)
return receipt_dict
except ServiceException:
raise
except Exception as e:
raise ServiceException(message=f'获取入库单详情失败: {str(e)}')
2025-12-19 10:12:59 +08:00
@classmethod
async def add_receipt(cls, db: AsyncSession, receipt_model: AddWarehouseReceiptModel):
"""
新增入库单同时创建关联的样品
"""
try:
# 检查入库单号是否已存在
existing = await WarehouseReceiptDao.get_receipt_by_no(db, receipt_model.receipt_no)
if existing:
raise ServiceException(message=f'入库单号【{receipt_model.receipt_no}】已存在')
# 获取样品数据
samples_data = receipt_model.samples if receipt_model.samples else []
# 创建入库单对象排除samples字段
receipt_dict = receipt_model.model_dump(exclude_unset=True, exclude={'samples'})
receipt = WarehouseReceipt(**receipt_dict)
receipt.create_time = datetime.now()
receipt.update_time = datetime.now()
# 保存入库单
await WarehouseReceiptDao.add_receipt(db, receipt)
await db.flush() # 刷新以获取receipt_id
# 创建样品对象并关联到入库单
for sample_data in samples_data:
sample_dict = sample_data.model_dump(exclude_unset=True)
sample = WarehouseSample(**sample_dict)
sample.receipt_id = receipt.receipt_id
sample.receipt_no = receipt.receipt_no
sample.create_by = receipt.create_by
sample.create_time = datetime.now()
sample.update_time = datetime.now()
await WarehouseSampleDao.add_sample(db, sample)
await db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except ServiceException:
await db.rollback()
raise
except Exception as e:
await db.rollback()
raise ServiceException(message=f'新增入库单失败: {str(e)}')
2025-12-19 10:12:59 +08:00
@classmethod
async def edit_receipt(cls, db: AsyncSession, receipt_model: EditWarehouseReceiptModel):
"""
编辑入库单同时更新关联的样品
"""
try:
# 检查入库单是否存在
receipt = await WarehouseReceiptDao.get_receipt_by_id(db, receipt_model.receipt_id)
if not receipt:
raise ServiceException(message='入库单不存在')
2025-12-19 10:12:59 +08:00
# 如果修改了入库单号,检查新单号是否已存在
if receipt_model.receipt_no and receipt_model.receipt_no != receipt.receipt_no:
existing = await WarehouseReceiptDao.get_receipt_by_no(db, receipt_model.receipt_no)
if existing:
raise ServiceException(message=f'入库单号【{receipt_model.receipt_no}】已存在')
2025-12-19 10:12:59 +08:00
# 更新入库单基本信息
receipt_model.update_time = datetime.now()
await WarehouseReceiptDao.edit_receipt(db, receipt_model)
2025-12-19 10:12:59 +08:00
# 如果提供了样品列表,则同步更新样品
if receipt_model.samples is not None:
# 获取现有样品列表
from module_admin.entity.vo.warehouse_sample_vo import WarehouseSamplePageQueryModel
sample_query = WarehouseSamplePageQueryModel(receipt_id=receipt_model.receipt_id, page_num=1, page_size=1000)
existing_samples = await WarehouseSampleDao.get_sample_list(db, sample_query, is_page=False)
existing_sample_ids = {sample.sample_id for sample in existing_samples} if existing_samples else set()
2025-12-19 10:12:59 +08:00
# 处理前端传来的样品
submitted_sample_ids = set()
for sample_data in receipt_model.samples:
sample_dict = sample_data.model_dump(exclude_unset=True)
# 如果有sample_id说明是更新现有样品
if 'sample_id' in sample_dict and sample_dict['sample_id']:
sample_id = sample_dict['sample_id']
submitted_sample_ids.add(sample_id)
# 更新样品
from module_admin.entity.vo.warehouse_sample_vo import EditWarehouseSampleModel
edit_sample = EditWarehouseSampleModel(**sample_dict)
edit_sample.update_time = datetime.now()
edit_sample.update_by = receipt_model.update_by
await WarehouseSampleDao.edit_sample(db, edit_sample)
else:
# 新增样品
sample = WarehouseSample(**sample_dict)
sample.receipt_id = receipt_model.receipt_id
sample.receipt_no = receipt_model.receipt_no or receipt.receipt_no
sample.create_by = receipt_model.update_by
sample.create_time = datetime.now()
sample.update_time = datetime.now()
await WarehouseSampleDao.add_sample(db, sample)
# 删除前端没有提交的样品(逻辑删除)
samples_to_delete = existing_sample_ids - submitted_sample_ids
if samples_to_delete:
await WarehouseSampleDao.delete_sample(db, list(samples_to_delete))
2025-12-19 10:12:59 +08:00
await db.commit()
2025-12-19 10:12:59 +08:00
return CrudResponseModel(is_success=True, message='更新成功')
except ServiceException:
await db.rollback()
raise
except Exception as e:
await db.rollback()
raise ServiceException(message=f'更新入库单失败: {str(e)}')
2025-12-19 10:12:59 +08:00
@classmethod
async def delete_receipt(cls, db: AsyncSession, delete_model: DeleteWarehouseReceiptModel):
"""
删除入库单同时删除关联的样品
"""
try:
receipt_ids = [int(id_str) for id_str in delete_model.receipt_ids.split(',')]
# 检查入库单是否存在
for receipt_id in receipt_ids:
receipt = await WarehouseReceiptDao.get_receipt_by_id(db, receipt_id)
if not receipt:
raise ServiceException(message=f'入库单ID【{receipt_id}】不存在')
# 删除入库单(级联删除样品)
await WarehouseReceiptDao.delete_receipt(db, receipt_ids)
await db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except ServiceException:
await db.rollback()
raise
except Exception as e:
await db.rollback()
raise ServiceException(message=f'删除入库单失败: {str(e)}')
2025-12-19 10:12:59 +08:00
@classmethod
async def generate_receipt_no(cls, db: AsyncSession):
"""
生成入库单号
"""
try:
year = datetime.now().year
receipt_no = await WarehouseReceiptDao.generate_receipt_no(db, year)
return {'receiptNo': receipt_no}
except Exception as e:
raise ServiceException(message=f'生成入库单号失败: {str(e)}')
2025-12-19 10:12:59 +08:00