feat: implement dynamic inspection requirement logic based on material master data
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# 文件路径: app/api/v1/inbound/base.py
|
||||
|
||||
from flask import Blueprint, request, jsonify, send_file, g
|
||||
from flask import Blueprint, request, jsonify, send_file, g, current_app
|
||||
from app.extensions import db
|
||||
from app.services.inbound.base_service import MaterialBaseService
|
||||
from app.utils.decorators import login_required, permission_required, audit_log
|
||||
@ -410,3 +410,49 @@ def batch_set_warning():
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f"批量设置预警失败: {str(e)}")
|
||||
return jsonify({"code": 500, "msg": f"批量设置预警失败: {str(e)}"}), 500
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 2.6 批量设置强制质检 API (POST /api/v1/inbound/base/batch-inspection)
|
||||
# ==============================================================================
|
||||
@inbound_base_bp.route('/batch-inspection', methods=['POST'])
|
||||
@permission_required('material_list:operation')
|
||||
def batch_set_inspection():
|
||||
"""
|
||||
批量设置物料强制质检标记
|
||||
请求体格式: {
|
||||
"ids": [1, 2, 3],
|
||||
"isInspectionRequired": true
|
||||
}
|
||||
"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({"code": 400, "msg": "No data provided"}), 400
|
||||
|
||||
ids = data.get('ids', [])
|
||||
is_inspection_required = bool(data.get('isInspectionRequired', False))
|
||||
|
||||
if not ids:
|
||||
return jsonify({"code": 400, "msg": "请选择要设置的物料"}), 400
|
||||
|
||||
updated_count = 0
|
||||
for base_id in ids:
|
||||
material = MaterialBase.query.get(base_id)
|
||||
if material:
|
||||
material.is_inspection_required = is_inspection_required
|
||||
updated_count += 1
|
||||
|
||||
db.session.commit()
|
||||
return jsonify({
|
||||
"code": 200,
|
||||
"msg": f"批量设置成功,已更新 {updated_count} 条记录",
|
||||
"data": {
|
||||
"updated": updated_count
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f"批量设置强制质检失败: {str(e)}")
|
||||
return jsonify({"code": 500, "msg": f"批量设置强制质检失败: {str(e)}"}), 500
|
||||
|
||||
@ -31,6 +31,9 @@ class MaterialBase(db.Model):
|
||||
# 启用状态
|
||||
is_enabled = db.Column(db.Boolean, default=True, comment='是否启用')
|
||||
|
||||
# 强制质检标记(采购入库时必须上传检测报告)
|
||||
is_inspection_required = db.Column(db.Boolean, default=False, comment='是否强制要求质检')
|
||||
|
||||
# ============================================================
|
||||
# 关联关系区域
|
||||
# ============================================================
|
||||
@ -81,6 +84,8 @@ class MaterialBase(db.Model):
|
||||
'generalImage': parse_list(self.product_image),
|
||||
# 【核心修改】:直接返回布尔值,不再转成 1 或 0
|
||||
'isEnabled': bool(self.is_enabled),
|
||||
# 强制质检标记
|
||||
'isInspectionRequired': bool(self.is_inspection_required),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -81,6 +81,8 @@ class StockBuy(db.Model):
|
||||
'category': self.base.category if self.base else '',
|
||||
'unit': self.base.unit if self.base else '',
|
||||
'material_type': self.base.material_type if self.base else '',
|
||||
# 强制质检标记
|
||||
'isInspectionRequired': bool(self.base.is_inspection_required) if self.base else False,
|
||||
|
||||
'sku': self.sku,
|
||||
'inbound_date': self.in_date.strftime('%Y-%m-%d') if self.in_date else '',
|
||||
|
||||
@ -75,7 +75,9 @@ class MaterialBaseService:
|
||||
'category': item.category,
|
||||
'unit': item.unit,
|
||||
'type': item.material_type,
|
||||
'status': '启用'
|
||||
'status': '启用',
|
||||
# 强制质检标记
|
||||
'isInspectionRequired': bool(item.is_inspection_required)
|
||||
})
|
||||
return results
|
||||
except Exception as e:
|
||||
|
||||
@ -94,6 +94,22 @@ class BuyInboundService:
|
||||
if not material: raise ValueError("所选物料不存在")
|
||||
if not material.is_enabled: raise ValueError(f"物料【{material.name}】已停用")
|
||||
|
||||
# ============================================================
|
||||
# 强制质检校验:如果物料标记为强制质检,则必须提供到检状态和检测报告
|
||||
# ============================================================
|
||||
if material.is_inspection_required:
|
||||
inspection_status = data.get('inspection_status')
|
||||
if not inspection_status:
|
||||
raise ValueError(f"物料【{material.name}】为强管控物料,必须选择到检状态")
|
||||
|
||||
# 检查检测报告:文件列表或外部链接至少有一个
|
||||
# 前端会将外部链接添加到 inspection_report 数组中一起提交
|
||||
inspection_report_list = data.get('inspection_report', [])
|
||||
has_report_file = inspection_report_list and len(inspection_report_list) > 0
|
||||
|
||||
if not has_report_file:
|
||||
raise ValueError(f"物料【{material.name}】为强管控物料,必须提供检测报告文件或外部链接")
|
||||
|
||||
BuyInboundService._check_unique(
|
||||
base_id=base_id,
|
||||
serial_number=data.get('serial_number'),
|
||||
@ -171,7 +187,36 @@ class BuyInboundService:
|
||||
try:
|
||||
stock = StockBuy.query.get(stock_id)
|
||||
if not stock: raise ValueError("记录不存在")
|
||||
BuyInboundService._check_unique(base_id=data.get('base_id', stock.base_id),
|
||||
|
||||
# 获取物料信息用于校验
|
||||
base_id = data.get('base_id', stock.base_id)
|
||||
material = MaterialBase.query.get(base_id)
|
||||
|
||||
# ============================================================
|
||||
# 强制质检校验:如果物料标记为强制质检,则必须提供到检状态和检测报告
|
||||
# ============================================================
|
||||
if material and material.is_inspection_required:
|
||||
inspection_status = data.get('inspection_status', stock.inspection_status)
|
||||
if not inspection_status:
|
||||
raise ValueError(f"物料【{material.name}】为强管控物料,必须选择到检状态")
|
||||
|
||||
# 检查检测报告:文件列表至少有一个
|
||||
inspection_report_list = data.get('inspection_report')
|
||||
if inspection_report_list is None:
|
||||
# 如果没有传入,使用现有的
|
||||
import json as json_module
|
||||
try:
|
||||
existing_reports = json_module.loads(stock.inspection_report) if stock.inspection_report else []
|
||||
except:
|
||||
existing_reports = []
|
||||
has_report_file = existing_reports and len(existing_reports) > 0
|
||||
else:
|
||||
has_report_file = inspection_report_list and len(inspection_report_list) > 0
|
||||
|
||||
if not has_report_file:
|
||||
raise ValueError(f"物料【{material.name}】为强管控物料,必须提供检测报告文件或外部链接")
|
||||
|
||||
BuyInboundService._check_unique(base_id=base_id,
|
||||
serial_number=data.get('serial_number', stock.serial_number),
|
||||
batch_number=data.get('batch_number', stock.batch_number),
|
||||
exclude_id=stock_id)
|
||||
|
||||
Reference in New Issue
Block a user