fix: prevent inbound of disabled materials

This commit is contained in:
dxc
2026-02-10 13:50:26 +08:00
committed by dxc (aider)
parent 18da3979a9
commit 17a61b489c
4 changed files with 30 additions and 7 deletions

View File

@ -60,7 +60,9 @@ class BuyInboundService:
@staticmethod @staticmethod
def search_base_material(keyword): def search_base_material(keyword):
try: try:
# [核心修改] 只查询已启用的物料,防止选择已禁用的历史物料
query = MaterialBase.query.filter(MaterialBase.is_enabled == True) query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
if keyword: if keyword:
query = query.filter( query = query.filter(
or_( or_(
@ -100,6 +102,10 @@ class BuyInboundService:
if not material: if not material:
raise ValueError("所选物料不存在") raise ValueError("所选物料不存在")
# [核心修改] 后端二次校验:如果物料已停用,禁止入库
if not material.is_enabled:
raise ValueError(f"物料【{material.name}】已停用,无法办理新入库。")
# --- [修复点] 执行唯一性校验 --- # --- [修复点] 执行唯一性校验 ---
BuyInboundService._check_unique( BuyInboundService._check_unique(
base_id=base_id, base_id=base_id,

View File

@ -40,7 +40,7 @@ class ProductInboundService:
@staticmethod @staticmethod
def search_base_material(keyword): def search_base_material(keyword):
try: try:
# 1. 基础查询:必须是已启用的物料 # [核心修改] 只查询已启用的物料
query = MaterialBase.query.filter(MaterialBase.is_enabled == True) query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
# 2. 动态条件:如果传入了关键词,则增加模糊匹配条件 # 2. 动态条件:如果传入了关键词,则增加模糊匹配条件
@ -85,6 +85,10 @@ class ProductInboundService:
material = MaterialBase.query.get(base_id) material = MaterialBase.query.get(base_id)
if not material: raise ValueError("物料不存在") if not material: raise ValueError("物料不存在")
# [核心修改] 后端二次校验:如果物料已停用,禁止入库
if not material.is_enabled:
raise ValueError(f"物料【{material.name}】已停用,无法办理新入库。")
# --- [核心修改] 执行唯一性校验 --- # --- [核心修改] 执行唯一性校验 ---
ProductInboundService._check_unique( ProductInboundService._check_unique(
serial_number=data.get('serial_number') serial_number=data.get('serial_number')

View File

@ -54,7 +54,7 @@ class SemiInboundService:
@staticmethod @staticmethod
def search_base_material(keyword): def search_base_material(keyword):
try: try:
# 基础查询:必须是已启用的物料 # [核心修改] 只查询已启用的物料
query = MaterialBase.query.filter(MaterialBase.is_enabled == True) query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
# 如果有关键词,进行模糊匹配 # 如果有关键词,进行模糊匹配
@ -101,6 +101,10 @@ class SemiInboundService:
if not material: if not material:
raise ValueError(f"ID为 {base_id} 的基础物料不存在") raise ValueError(f"ID为 {base_id} 的基础物料不存在")
# [核心修改] 后端二次校验:如果物料已停用,禁止入库
if not material.is_enabled:
raise ValueError(f"物料【{material.name}】已停用,无法办理新入库。")
# --- [核心修改] 执行唯一性校验 --- # --- [核心修改] 执行唯一性校验 ---
SemiInboundService._check_unique( SemiInboundService._check_unique(
base_id=base_id, base_id=base_id,

View File

@ -1,3 +1,4 @@
# app/services/inbound/service_service.py
from app import db from app import db
from app.models.inbound.service import StockService from app.models.inbound.service import StockService
from app.models.base import MaterialBase from app.models.base import MaterialBase
@ -37,7 +38,9 @@ class ServiceService:
def search_base_material(cls, keyword): def search_base_material(cls, keyword):
"""搜索基础物料,供前端远程选择""" """搜索基础物料,供前端远程选择"""
try: try:
# [核心修改] 只查询已启用的物料
query = MaterialBase.query.filter(MaterialBase.is_enabled == True) query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
if keyword: if keyword:
query = query.filter( query = query.filter(
db.or_( db.or_(
@ -66,9 +69,15 @@ class ServiceService:
def create_service(cls, data): def create_service(cls, data):
"""创建服务权益记录""" """创建服务权益记录"""
# 检查基础物料是否存在 # 检查基础物料是否存在
base = MaterialBase.query.get(data.get('base_id')) base_id = data.get('base_id')
base = MaterialBase.query.get(base_id)
if not base: if not base:
raise ValueError('基础物料不存在') raise ValueError('基础物料不存在')
# [核心修改] 后端二次校验:如果物料已停用,禁止创建服务权益
if not base.is_enabled:
raise ValueError(f"物料【{base.name}】已停用,无法创建新的服务权益。")
# 生成SKU # 生成SKU
sku = cls._generate_sku() sku = cls._generate_sku()
service = StockService( service = StockService(
@ -144,8 +153,8 @@ class ServiceService:
# 总数 # 总数
total = query.count() total = query.count()
# 分页 # 分页
items = query.order_by(StockService.created_at.desc())\ items = query.order_by(StockService.created_at.desc()) \
.offset((page - 1) * per_page)\ .offset((page - 1) * per_page) \
.limit(per_page).all() .limit(per_page).all()
return { return {
'items': [item.to_dict() for item in items], 'items': [item.to_dict() for item in items],