fix: support stock adjustment for items without stocktake draft
This commit is contained in:
@ -364,10 +364,16 @@ def adjust_stock():
|
||||
1. 根据 diff_qty 调整库存 (stock_quantity 和 available_quantity)
|
||||
2. 生成流水账记录 (盘盈入库 / 盘亏出库)
|
||||
3. 标记草稿为 is_processed=True
|
||||
|
||||
支持两种模式:
|
||||
- 有草稿模式:通过 draft_id 或 stock_id+source_table 查找草稿
|
||||
- 无草稿模式:直接传入 stock_id + diff_qty + source_table(未扫码直接盘亏)
|
||||
"""
|
||||
data = request.json
|
||||
draft_id = data.get('draft_id')
|
||||
stock_id = data.get('stock_id') # 备用参数:通过 stock_id 查找草稿
|
||||
stock_id = data.get('stock_id')
|
||||
diff_qty = data.get('diff_qty')
|
||||
source_table = data.get('source_table')
|
||||
operator_name = data.get('operator_name', 'System')
|
||||
remark = data.get('remark', '')
|
||||
|
||||
@ -375,26 +381,34 @@ def adjust_stock():
|
||||
return jsonify({"message": "draft_id 或 stock_id 不能同时为空"}), 400
|
||||
|
||||
try:
|
||||
# 1. 获取草稿记录(优先用 draft_id,否则用 stock_id)
|
||||
# 1. 尝试获取草稿
|
||||
draft = StocktakeDraft.query.get(draft_id) if draft_id else None
|
||||
if not draft and stock_id:
|
||||
# 尝试通过 stock_id 查找未处理的草稿
|
||||
if not draft and stock_id and source_table:
|
||||
draft = StocktakeDraft.query.filter_by(
|
||||
stock_id=stock_id,
|
||||
source_table=source_table
|
||||
).first()
|
||||
elif not draft and stock_id:
|
||||
draft = StocktakeDraft.query.filter_by(stock_id=stock_id).first()
|
||||
|
||||
if not draft:
|
||||
return jsonify({"message": f"平账失败:找不到对应的盘点草稿记录(draft_id={draft_id}, stock_id={stock_id})"}), 404
|
||||
# 2. 核心逻辑分支
|
||||
if draft:
|
||||
# 有草稿模式
|
||||
stock_id = draft.stock_id
|
||||
source_table = draft.source_table
|
||||
diff_qty = float(draft.diff_qty)
|
||||
else:
|
||||
# 无草稿模式(未扫码直接盘亏)
|
||||
if diff_qty is None or source_table is None or not stock_id:
|
||||
return jsonify({"message": "未扫码物资平账缺失必要参数(需提供 diff_qty 和 source_table)"}), 400
|
||||
diff_qty = float(diff_qty)
|
||||
|
||||
# 2. 获取库存记录
|
||||
if not draft.stock_id or not draft.source_table:
|
||||
return jsonify({"message": "草稿记录缺少库存关联信息"}), 400
|
||||
|
||||
stock = get_stock_record(draft.source_table, draft.stock_id)
|
||||
# 3. 获取并校验真实的库存记录
|
||||
stock = get_stock_record(source_table, stock_id)
|
||||
if not stock:
|
||||
return jsonify({"message": "库存记录不存在"}), 404
|
||||
return jsonify({"message": "平账失败:物理库存记录已不存在"}), 404
|
||||
|
||||
diff_qty = float(draft.diff_qty)
|
||||
|
||||
# 3. 计算调整
|
||||
# 4. 计算调整
|
||||
if diff_qty > 0:
|
||||
# 盘盈:增加库存
|
||||
new_stock_qty = float(stock.stock_quantity or 0) + diff_qty
|
||||
@ -415,19 +429,20 @@ def adjust_stock():
|
||||
else:
|
||||
return jsonify({"message": "差异为0,无需调整"}), 400
|
||||
|
||||
# 4. 执行库存调整
|
||||
# 5. 执行库存调整
|
||||
stock.stock_quantity = new_stock_qty
|
||||
stock.available_quantity = new_avail_qty
|
||||
|
||||
# 5. 生成流水账记录
|
||||
# 导入流水账模型
|
||||
# 6. 生成流水账记录
|
||||
from app.models.outbound import TransOutbound
|
||||
|
||||
# 生成唯一单号
|
||||
adj_no_suffix = draft.id if draft else f"MANUAL-{datetime.now().strftime('%Y%m%d%H%M%S')}"
|
||||
trans_record = TransOutbound(
|
||||
outbound_no=f"STKADJ-{datetime.now().strftime('%Y%m%d%H%M%S')}-{draft.id:04d}",
|
||||
outbound_no=f"STKADJ-{datetime.now().strftime('%Y%m%d%H%M%S')}-{adj_no_suffix}",
|
||||
sku=stock.sku,
|
||||
source_table=draft.source_table,
|
||||
stock_id=draft.stock_id,
|
||||
source_table=source_table,
|
||||
stock_id=stock_id,
|
||||
barcode=getattr(stock, 'barcode', ''),
|
||||
quantity=abs(diff_qty),
|
||||
unit_price=getattr(stock, 'pre_tax_unit_price', 0) or getattr(stock, 'manual_cost', 0) or 0,
|
||||
@ -439,8 +454,9 @@ def adjust_stock():
|
||||
)
|
||||
db.session.add(trans_record)
|
||||
|
||||
# 6. 删除草稿记录(平账后从工作台移除)
|
||||
db.session.delete(draft)
|
||||
# 7. 删除草稿记录(仅在有草稿时)
|
||||
if draft:
|
||||
db.session.delete(draft)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -450,7 +466,7 @@ def adjust_stock():
|
||||
"diff_qty": diff_qty,
|
||||
"new_stock_qty": new_stock_qty,
|
||||
"new_avail_qty": new_avail_qty,
|
||||
"draft_id": draft_id
|
||||
"draft_id": draft_id if draft_id else (draft.id if draft else None)
|
||||
}), 200
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@ -448,12 +448,14 @@ const api = {
|
||||
params: {}
|
||||
}),
|
||||
// ★ 新增: 单条库存调整
|
||||
adjustStock: (draftId: number, stockId: number, remark: string) => request({
|
||||
adjustStock: (draftId: number, stockId: number, diffQty: number, sourceTable: string, remark: string) => request({
|
||||
url: '/v1/inbound/stock/adjust',
|
||||
method: 'post',
|
||||
data: {
|
||||
draft_id: draftId,
|
||||
stock_id: stockId, // 备用参数
|
||||
stock_id: stockId, // 库存项ID
|
||||
diff_qty: diffQty, // 差异数量(支持无草稿模式)
|
||||
source_table: sourceTable, // 必须:stock_buy / stock_semi / stock_product
|
||||
operator_name: currentUser,
|
||||
remark: remark
|
||||
}
|
||||
@ -755,6 +757,10 @@ const closeOverlays = () => {
|
||||
// --- 导出 Excel 逻辑 (调用后端API) ---
|
||||
const exportToExcel = async () => {
|
||||
try {
|
||||
// ===== 调试代码 =====
|
||||
console.warn('---- 触发了导出 Excel ----');
|
||||
// ===== 调试结束 =====
|
||||
|
||||
ElMessage.info('正在生成盘点报告,请稍候...');
|
||||
// 使用项目封装的 request 发送请求,确保自动携带 JWT Token
|
||||
const res: any = await request({
|
||||
@ -886,6 +892,12 @@ const openVarianceDialog = async () => {
|
||||
// ★ 新增: 确认平账
|
||||
const handleAdjust = async (row: any) => {
|
||||
try {
|
||||
// ===== 调试代码 =====
|
||||
console.warn('---- 准备平账参数检查 ----');
|
||||
console.warn('当前点击行的完整数据:', row);
|
||||
console.warn(`将要发送的 draftId: ${row.id}, stockId: ${row.stock_id}, sourceTable: ${row.source_table}`);
|
||||
// ===== 调试结束 =====
|
||||
|
||||
await ElMessageBox.confirm(
|
||||
`确定要对 "${row.uuid}" 进行平账调整吗?\n\n差异: ${row.diff_qty > 0 ? '盘盈 +' : '盘亏 '}${row.diff_qty}`,
|
||||
'确认平账',
|
||||
@ -894,7 +906,7 @@ const handleAdjust = async (row: any) => {
|
||||
|
||||
const remark = `盘点差异调整 - ${row.diff_qty > 0 ? '盘盈入库' : '盘亏出库'}`
|
||||
|
||||
const res: any = await api.adjustStock(row.id, row.stock_id, remark)
|
||||
const res: any = await api.adjustStock(row.id, row.stock_id, row.diff_qty, row.source_table || 'stock_buy', remark)
|
||||
|
||||
ElMessage.success(res.message || '调整成功')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user