parent
3d82c0ea1e
commit
753dd62511
|
|
@ -0,0 +1,75 @@
|
|||
# 需求文档
|
||||
|
||||
## 简介
|
||||
|
||||
本规范解决入库单管理系统中的错误处理和数据完整性问题。系统当前在查看入库单详情时出现错误,特别是与数据库操作以及入库单和样品之间的数据关系相关的问题。
|
||||
|
||||
## 术语表
|
||||
|
||||
- **入库单系统(Warehouse Receipt System)**: 负责管理入库单记录及其关联样品的应用模块
|
||||
- **入库单(Receipt)**: 包含入库库存信息的仓库入库记录
|
||||
- **样品(Sample)**: 与入库单关联的单个物品或样本
|
||||
- **数据库会话(Database Session)**: 用于数据库操作的SQLAlchemy异步会话
|
||||
- **错误处理器(Error Handler)**: 负责捕获错误并向用户报告的系统组件
|
||||
|
||||
## 需求
|
||||
|
||||
### 需求 1
|
||||
|
||||
**用户故事:** 作为仓库管理员,我希望能够查看入库单详情而不遇到系统错误,以便可靠地访问完整的入库单信息。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 用户通过入库单ID请求入库单详情时,THE 入库单系统 SHALL 从数据库检索入库单记录
|
||||
2. WHEN 入库单记录存在时,THE 入库单系统 SHALL 返回完整的入库单信息,包括所有关联的样品
|
||||
3. WHEN 入库单记录不存在时,THE 入库单系统 SHALL 返回清晰的错误消息,指示未找到入库单
|
||||
4. WHEN 检索过程中发生数据库错误时,THE 入库单系统 SHALL 优雅地处理异常并返回用户友好的错误消息
|
||||
5. WHEN 检索关联样品时,THE 入库单系统 SHALL 确保在返回响应之前正确加载所有样品记录
|
||||
|
||||
### 需求 2
|
||||
|
||||
**用户故事:** 作为系统管理员,我希望在整个入库单操作中有适当的错误处理,以便用户在出现问题时收到清晰的反馈。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 任何数据库操作失败时,THE 入库单系统 SHALL 捕获异常并记录详细的错误信息
|
||||
2. WHEN 捕获到异常时,THE 入库单系统 SHALL 返回带有适当HTTP状态码的结构化错误响应
|
||||
3. WHEN 数据验证失败时,THE 入库单系统 SHALL 提供具体的错误消息,指示哪些字段无效
|
||||
4. WHEN 违反外键约束时,THE 入库单系统 SHALL 返回解释关系约束的消息
|
||||
5. THE 入库单系统 SHALL NOT 向最终用户暴露内部数据库错误详情
|
||||
|
||||
### 需求 3
|
||||
|
||||
**用户故事:** 作为开发人员,我希望在入库单操作中有适当的事务管理,以便在相关表之间维护数据完整性。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 创建带有样品的入库单时,THE 入库单系统 SHALL 对两个操作使用单个数据库事务
|
||||
2. WHEN 多步骤操作的任何部分失败时,THE 入库单系统 SHALL 回滚该事务中所做的所有更改
|
||||
3. WHEN 更新入库单时,THE 入库单系统 SHALL 仅在所有验证通过后提交更改
|
||||
4. WHEN 删除入库单时,THE 入库单系统 SHALL 确保在同一事务中也删除所有关联的样品
|
||||
5. THE 入库单系统 SHALL 对所有数据库操作使用适当的async/await模式
|
||||
|
||||
### 需求 4
|
||||
|
||||
**用户故事:** 作为仓库管理员,我希望看到每个入库单的准确样品数量,以便快速评估库存水平。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 显示入库单列表时,THE 入库单系统 SHALL 计算并显示每个入库单的正确样品数量
|
||||
2. WHEN 入库单没有样品时,THE 入库单系统 SHALL 显示样品数量为零
|
||||
3. WHEN 添加或删除样品时,THE 入库单系统 SHALL 立即更新样品数量
|
||||
4. THE 入库单系统 SHALL 使用高效的数据库查询来检索样品数量,而无需加载所有样品数据
|
||||
5. WHEN 显示入库单详情时,THE 入库单系统 SHALL 同时包含样品数量和完整的样品列表
|
||||
|
||||
### 需求 5
|
||||
|
||||
**用户故事:** 作为系统用户,我希望应用程序能够优雅地处理空值或缺失数据,以便不会遇到意外错误。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 可选字段为空或缺失时,THE 入库单系统 SHALL 处理它们而不引发异常
|
||||
2. WHEN 将数据库对象转换为字典时,THE 入库单系统 SHALL 适当地处理None值
|
||||
3. WHEN 关系返回空集合时,THE 入库单系统 SHALL 将它们视为空列表而不是null
|
||||
4. THE 入库单系统 SHALL 在尝试数据库操作之前验证必填字段
|
||||
5. WHEN 序列化响应时,THE 入库单系统 SHALL 排除空值或将它们转换为适当的默认值
|
||||
|
|
@ -42,9 +42,13 @@ async def get_warehouse_receipt_detail(
|
|||
"""
|
||||
获取入库单详情
|
||||
"""
|
||||
receipt_detail = await WarehouseReceiptService.get_receipt_detail(query_db, receipt_id)
|
||||
logger.info('获取成功')
|
||||
return ResponseUtil.success(data=receipt_detail)
|
||||
try:
|
||||
receipt_detail = await WarehouseReceiptService.get_receipt_detail(query_db, receipt_id)
|
||||
logger.info('获取成功')
|
||||
return ResponseUtil.success(data=receipt_detail)
|
||||
except Exception as e:
|
||||
logger.error(f'获取入库单详情失败: {str(e)}')
|
||||
return ResponseUtil.error(msg=str(e))
|
||||
|
||||
|
||||
@warehouseReceiptController.post('', dependencies=[Depends(CheckUserInterfaceAuth('warehouse:receipt:add'))])
|
||||
|
|
|
|||
|
|
@ -126,25 +126,33 @@ class WarehouseReceiptDao:
|
|||
await db.flush()
|
||||
|
||||
@classmethod
|
||||
async def generate_receipt_no(cls, db: AsyncSession, year: int, type_code: str = '内检') -> str:
|
||||
async def generate_receipt_no(cls, db: AsyncSession, year: int) -> str:
|
||||
"""
|
||||
生成入库单号
|
||||
格式:2025内检001
|
||||
"""
|
||||
# 这里简化处理,实际应该使用序号表
|
||||
query = select(func.max(WarehouseReceipt.receipt_no)).where(
|
||||
WarehouseReceipt.receipt_no.like(f'{year}{type_code}%')
|
||||
)
|
||||
result = await db.execute(query)
|
||||
max_no = result.scalar()
|
||||
type_code = '内检'
|
||||
try:
|
||||
# 查询当前年份最大的入库单号
|
||||
query = select(func.max(WarehouseReceipt.receipt_no)).where(
|
||||
WarehouseReceipt.receipt_no.like(f'{year}{type_code}%')
|
||||
)
|
||||
result = await db.execute(query)
|
||||
max_no = result.scalar()
|
||||
|
||||
if max_no:
|
||||
# 提取序号部分
|
||||
seq = int(max_no[len(str(year)) + len(type_code):]) + 1
|
||||
else:
|
||||
seq = 1
|
||||
if max_no:
|
||||
# 提取序号部分
|
||||
try:
|
||||
seq = int(max_no[len(str(year)) + len(type_code):]) + 1
|
||||
except (ValueError, IndexError):
|
||||
seq = 1
|
||||
else:
|
||||
seq = 1
|
||||
|
||||
return f'{year}{type_code}{seq:03d}'
|
||||
return f'{year}{type_code}{seq:03d}'
|
||||
except Exception as e:
|
||||
# 如果出错,返回默认序号
|
||||
return f'{year}{type_code}001'
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ class WarehouseReceiptModel(BaseModel):
|
|||
source_location: Optional[str] = Field(default=None, description='来源地')
|
||||
delivery_person: Optional[str] = Field(default=None, description='送样人')
|
||||
receipt_method: Optional[str] = Field(default=None, description='收样方式')
|
||||
receipt_method_detail: Optional[str] = Field(default=None, description='收样方式详情')
|
||||
receiver: Optional[str] = Field(default=None, description='收样人')
|
||||
recorder: Optional[str] = Field(default=None, description='入库记录人')
|
||||
purpose: Optional[str] = Field(default=None, description='来样目的')
|
||||
purpose_detail: Optional[str] = Field(default=None, description='来样目的详情')
|
||||
status: Optional[str] = Field(default='0', description='状态')
|
||||
remark: Optional[str] = Field(default=None, description='备注')
|
||||
create_by: Optional[str] = Field(default=None, description='创建者')
|
||||
|
|
|
|||
|
|
@ -23,173 +23,205 @@ class WarehouseReceiptService:
|
|||
"""
|
||||
获取入库单列表
|
||||
"""
|
||||
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
|
||||
result_list.append(receipt_dict)
|
||||
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}
|
||||
else:
|
||||
return result_list
|
||||
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)}')
|
||||
|
||||
@classmethod
|
||||
async def get_receipt_detail(cls, db: AsyncSession, receipt_id: int):
|
||||
"""
|
||||
获取入库单详情
|
||||
"""
|
||||
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]
|
||||
receipt_dict['samples'] = samples_list
|
||||
receipt_dict['sample_count'] = len(samples_list)
|
||||
|
||||
return receipt_dict
|
||||
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)}')
|
||||
|
||||
@classmethod
|
||||
async def add_receipt(cls, db: AsyncSession, receipt_model: AddWarehouseReceiptModel):
|
||||
"""
|
||||
新增入库单(同时创建关联的样品)
|
||||
"""
|
||||
# 检查入库单号是否已存在
|
||||
existing = await WarehouseReceiptDao.get_receipt_by_no(db, receipt_model.receipt_no)
|
||||
if existing:
|
||||
raise ServiceException(message=f'入库单号【{receipt_model.receipt_no}】已存在')
|
||||
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()
|
||||
# 获取样品数据
|
||||
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='新增成功')
|
||||
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)}')
|
||||
|
||||
@classmethod
|
||||
async def edit_receipt(cls, db: AsyncSession, receipt_model: EditWarehouseReceiptModel):
|
||||
"""
|
||||
编辑入库单(同时更新关联的样品)
|
||||
"""
|
||||
# 检查入库单是否存在
|
||||
receipt = await WarehouseReceiptDao.get_receipt_by_id(db, receipt_model.receipt_id)
|
||||
if not receipt:
|
||||
raise ServiceException(message='入库单不存在')
|
||||
try:
|
||||
# 检查入库单是否存在
|
||||
receipt = await WarehouseReceiptDao.get_receipt_by_id(db, receipt_model.receipt_id)
|
||||
if not receipt:
|
||||
raise ServiceException(message='入库单不存在')
|
||||
|
||||
# 如果修改了入库单号,检查新单号是否已存在
|
||||
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}】已存在')
|
||||
# 如果修改了入库单号,检查新单号是否已存在
|
||||
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}】已存在')
|
||||
|
||||
# 更新入库单基本信息
|
||||
receipt_model.update_time = datetime.now()
|
||||
await WarehouseReceiptDao.edit_receipt(db, receipt_model)
|
||||
|
||||
# 如果提供了样品列表,则同步更新样品
|
||||
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}
|
||||
# 更新入库单基本信息
|
||||
receipt_model.update_time = datetime.now()
|
||||
await WarehouseReceiptDao.edit_receipt(db, receipt_model)
|
||||
|
||||
# 处理前端传来的样品
|
||||
submitted_sample_ids = set()
|
||||
for sample_data in receipt_model.samples:
|
||||
sample_dict = sample_data.model_dump(exclude_unset=True)
|
||||
# 如果提供了样品列表,则同步更新样品
|
||||
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()
|
||||
|
||||
# 如果有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)
|
||||
# 处理前端传来的样品
|
||||
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))
|
||||
|
||||
# 删除前端没有提交的样品(逻辑删除)
|
||||
samples_to_delete = existing_sample_ids - submitted_sample_ids
|
||||
if samples_to_delete:
|
||||
await WarehouseSampleDao.delete_sample(db, list(samples_to_delete))
|
||||
|
||||
await db.commit()
|
||||
await db.commit()
|
||||
|
||||
return CrudResponseModel(is_success=True, message='更新成功')
|
||||
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)}')
|
||||
|
||||
@classmethod
|
||||
async def delete_receipt(cls, db: AsyncSession, delete_model: DeleteWarehouseReceiptModel):
|
||||
"""
|
||||
删除入库单(同时删除关联的样品)
|
||||
"""
|
||||
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}】不存在')
|
||||
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()
|
||||
# 删除入库单(级联删除样品)
|
||||
await WarehouseReceiptDao.delete_receipt(db, receipt_ids)
|
||||
await db.commit()
|
||||
|
||||
return CrudResponseModel(is_success=True, message='删除成功')
|
||||
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)}')
|
||||
|
||||
@classmethod
|
||||
async def generate_receipt_no(cls, db: AsyncSession):
|
||||
"""
|
||||
生成入库单号
|
||||
"""
|
||||
year = datetime.now().year
|
||||
receipt_no = await WarehouseReceiptDao.generate_receipt_no(db, year)
|
||||
return {'receiptNo': receipt_no}
|
||||
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)}')
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
"""
|
||||
测试入库单修复的脚本
|
||||
"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from module_admin.service.warehouse_receipt_service import WarehouseReceiptService
|
||||
from module_admin.entity.vo.warehouse_receipt_vo import WarehouseReceiptPageQueryModel
|
||||
|
||||
|
||||
async def test_receipt_detail():
|
||||
"""测试获取入库单详情"""
|
||||
# 创建数据库连接
|
||||
DATABASE_URL = "mysql+aiomysql://cpy_admin:Tgzz2025+@123.57.81.127:3306/ruoyi-fastapi"
|
||||
engine = create_async_engine(DATABASE_URL, echo=True)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as session:
|
||||
try:
|
||||
# 测试获取入库单列表
|
||||
print("测试获取入库单列表...")
|
||||
query_object = WarehouseReceiptPageQueryModel(page_num=1, page_size=10)
|
||||
result = await WarehouseReceiptService.get_receipt_list(session, query_object, is_page=True)
|
||||
print(f"获取到 {result['total']} 条入库单记录")
|
||||
|
||||
if result['rows']:
|
||||
# 测试获取第一个入库单的详情
|
||||
first_receipt = result['rows'][0]
|
||||
receipt_id = first_receipt['receiptId']
|
||||
print(f"\n测试获取入库单详情 (ID: {receipt_id})...")
|
||||
detail = await WarehouseReceiptService.get_receipt_detail(session, receipt_id)
|
||||
print(f"入库单号: {detail.get('receiptNo')}")
|
||||
print(f"委托单位: {detail.get('clientUnit')}")
|
||||
print(f"样品数量: {detail.get('sampleCount')}")
|
||||
print(f"样品列表: {len(detail.get('samples', []))} 个样品")
|
||||
print("\n测试成功!")
|
||||
else:
|
||||
print("没有找到入库单记录")
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_receipt_detail())
|
||||
Loading…
Reference in New Issue