feat(inbound): 入库提交时校验库位必须存在

此前入库只校验库位「非空字符串」,任意值都能写进 stock_buy.warehouse_location —
存量数据里那 5 条裸数字('1' '5' '7' '14' '22')就是这么来的。

新增 app/utils/warehouse_location.py:
- location_error(location)      —— 库位必须存在于 sys_warehouse_location
- usable_locations(company, xs) —— 批量筛出「存在且本公司可见」的库位
- material_company(base_id)     —— 取物料所属公司

★ 只校验存在,**不校验归属公司** —— 跨公司使用库位不做限制(业务上可能共用)。
  若日后要收紧,location_error 里传一次 material_company(base_id) 即可。

空值仍由各接口原有的「必填」校验负责,两件事语义分开、互不干扰。
三个接口(buy / product / semi 的 /submit)各加一行调用。
This commit is contained in:
yueli
2026-09-29 13:33:35 +08:00
parent 4890b996c4
commit 3e131fa584
4 changed files with 86 additions and 0 deletions

View File

@ -2,6 +2,7 @@
from flask import Blueprint, request, jsonify
from app.services.inbound.product_service import ProductInboundService
from app.utils.decorators import permission_required
from app.utils.warehouse_location import location_error
from app.models.base import MaterialBase
from app.services.track_query_service import lookup_product
import traceback
@ -117,6 +118,12 @@ def submit():
location = data.get('warehouse_location', '').strip()
if not location:
return jsonify({"code": 400, "msg": "入库失败:库位为必填项,不能为空!"}), 400
# 库位存在性校验:必须在 sys_warehouse_location 里查得到。
# ★ 只校验存在,**不校验归属公司** —— 跨公司使用库位不做限制。
err = location_error(location)
if err:
return jsonify({"code": 400, "msg": f"入库失败:{err}"}), 400
user_permissions = get_current_user_permissions()
if 'inbound_product:*' not in user_permissions: