feat: upgrade adjustment workflow to require explicit inbound SKU or outbound tracking number and fix UTC timezone issue

This commit is contained in:
DXC
2026-03-19 15:26:40 +08:00
parent ae63748060
commit 6cc3d1b6e0
4 changed files with 167 additions and 3 deletions

View File

@ -2,7 +2,7 @@
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt
from app.utils.decorators import permission_required
from app.extensions import db
from app.extensions import db, beijing_time
from app.models.stock.adjustment import StockAdjustment
from app.models.base import MaterialBase
from app.models.inbound.buy import StockBuy
@ -351,7 +351,7 @@ def import_from_stocktake():
# 生成调整单号
order_no = generate_order_no()
# 创建调整单
# 创建调整单(使用北京时间)
adjustment = StockAdjustment(
order_no=order_no,
base_id=base_id,
@ -363,7 +363,8 @@ def import_from_stocktake():
adjust_quantity=adjust_quantity,
reason=reason,
status='pending',
operator=operator
operator=operator,
create_time=beijing_time()
)
db.session.add(adjustment)
count += 1
@ -374,3 +375,53 @@ def import_from_stocktake():
except Exception as e:
db.session.rollback()
return jsonify({'code': 500, 'msg': f'导入失败: {str(e)}'}), 500
# --------------------------------------------------------
# 7. 处理调整单关联入库SKU或出库单号
# POST /api/v1/stock/adjustment/<id>/process
# --------------------------------------------------------
@adjustment_bp.route('/<int:id>/process', methods=['POST'])
@jwt_required()
@permission_required('stock_adjustment:operation')
def process_adjustment(id):
"""处理待处理的调整单关联入库SKU或出库单号"""
identity = get_jwt_identity()
operator = identity.get('username', 'system') if isinstance(identity, dict) else str(identity)
if not operator or operator == '0':
operator = identity if identity else 'system'
data = request.get_json()
if not data:
return jsonify({'code': 400, 'msg': '缺少参数'}), 400
linked_sku = data.get('linked_sku', '')
linked_outbound_no = data.get('linked_outbound_no', '')
try:
adjustment = StockAdjustment.query.get(id)
if not adjustment:
return jsonify({'code': 404, 'msg': '调整单不存在'}), 404
if adjustment.status != 'pending':
return jsonify({'code': 400, 'msg': '只能处理待处理状态的调整单'}), 400
# 根据调整类型校验必填项
if adjustment.adjust_type == 'profit':
if not linked_sku:
return jsonify({'code': 400, 'msg': '盘盈调整必须关联入库SKU'}), 400
adjustment.linked_sku = linked_sku
elif adjustment.adjust_type == 'loss':
if not linked_outbound_no:
return jsonify({'code': 400, 'msg': '盘亏调整必须关联出库单号'}), 400
adjustment.linked_outbound_no = linked_outbound_no
adjustment.status = 'completed'
adjustment.operator = operator
db.session.commit()
return jsonify({'code': 200, 'msg': '处理成功', 'data': adjustment.to_dict()})
except Exception as e:
db.session.rollback()
return jsonify({'code': 500, 'msg': f'处理失败: {str(e)}'}), 500

View File

@ -34,6 +34,10 @@ class StockAdjustment(db.Model):
reason = db.Column(db.String(500), nullable=False)
# 状态:'pending' 待处理 / 'completed' 已完成 / 'cancelled' 已取消
status = db.Column(db.String(20), default='pending')
# 关联入库SKU盘盈时填写
linked_sku = db.Column(db.String(100), comment='关联入库SKU盘盈时填写')
# 关联出库单号(盘亏时填写)
linked_outbound_no = db.Column(db.String(100), comment='关联出库单号(盘亏时填写)')
# 操作人/经办人
operator = db.Column(db.String(100))
# 创建时间
@ -56,6 +60,8 @@ class StockAdjustment(db.Model):
'adjust_quantity': float(self.adjust_quantity or 0),
'reason': self.reason,
'status': self.status,
'linked_sku': self.linked_sku,
'linked_outbound_no': self.linked_outbound_no,
'operator': self.operator,
'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
'update_time': self.update_time.strftime('%Y-%m-%d %H:%M:%S') if self.update_time else None,