feat(track): 入库/出库 webhook 按公司路由到对应实例
三个触发点此前都不带 company_name,无从路由:
· product_service / semi_service:入库通知补 material.company_name
· outbound_service:track_notifications 元组加 company(取自
stock_record.base.company_name;维修单走 repair.base,两处
relationship 均已定义),发送时带进 payload
出库路径同时**去掉**了显式传入的 url=TRACK_OUTBOUND_WEBHOOK_URL ——
url 参数优先级最高,保留它会让出库永远打到默认实例,company 路由形同
虚设。url 参数本身保留,需要强制覆盖时仍可用。
实测:
LICA 入库:待仓库收货 → 已入库,IRIS 库该 SN 0 行
LICA 出库:已入库 → 已出库,IRIS 库该 SN 0 行
IRIS 回归:对已入库设备重发入库通知,状态幂等不变
精确隔离:发一条 IRIS 通知,lica_backend 日志 +0 行、track_backend +19 行
注意:不做"两个实例都推一遍"——两个 Track 的 webhook key 是同一把、
两边都会鉴权通过,而 Track 按 serial_number/sku 匹配,相同型号设备会
同时命中两库,把 IRIS 的设备误标成已入库,且产生 2 倍审计与流转节点。
This commit is contained in:
@ -226,6 +226,8 @@ class ProductInboundService:
|
||||
'sku': material.spec_model or material.name,
|
||||
'serial_number': new_stock.serial_number,
|
||||
'quantity': float(new_stock.in_quantity or 0),
|
||||
# ★ 公司名决定通知哪个 Track 实例(IRIS / LICA),缺失则回落默认
|
||||
'company_name': getattr(material, 'company_name', None),
|
||||
'operator': get_current_operator(),
|
||||
})
|
||||
return new_stock
|
||||
|
||||
@ -265,6 +265,8 @@ class SemiInboundService:
|
||||
'sku': material.spec_model or material.name,
|
||||
'serial_number': webhook_sn,
|
||||
'quantity': float(new_stock.in_quantity or 0),
|
||||
# ★ 公司名决定通知哪个 Track 实例(IRIS / LICA),缺失则回落默认
|
||||
'company_name': getattr(material, 'company_name', None),
|
||||
'operator': get_current_operator(),
|
||||
})
|
||||
return new_stock
|
||||
|
||||
@ -359,7 +359,11 @@ class OutboundService:
|
||||
repair.shipping_date = current_time
|
||||
|
||||
# 收集 Track 联动信息(维修单带 serial_number)
|
||||
track_notifications.append((getattr(repair, 'serial_number', None), source_table, quantity))
|
||||
# ★ 连同 company_name 一起攒起来,发送时按公司路由到对应 Track 实例
|
||||
track_notifications.append((
|
||||
getattr(repair, 'serial_number', None), source_table, quantity,
|
||||
getattr(getattr(repair, 'base', None), 'company_name', None),
|
||||
))
|
||||
|
||||
# 创建出库记录
|
||||
new_record = TransOutbound(
|
||||
@ -394,7 +398,11 @@ class OutboundService:
|
||||
raise ValueError(f"库存记录不存在 (ID: {stock_id})")
|
||||
|
||||
# 收集 Track 联动信息(库存表 serial_number = Track 身份证)
|
||||
track_notifications.append((getattr(stock_record, 'serial_number', None), source_table, quantity))
|
||||
# ★ 连同 company_name 一起攒起来,发送时按公司路由到对应 Track 实例
|
||||
track_notifications.append((
|
||||
getattr(stock_record, 'serial_number', None), source_table, quantity,
|
||||
getattr(getattr(stock_record, 'base', None), 'company_name', None),
|
||||
))
|
||||
|
||||
new_record = TransOutbound(
|
||||
sku=item.get('sku'),
|
||||
@ -419,11 +427,11 @@ class OutboundService:
|
||||
db.session.commit()
|
||||
|
||||
# ★ 出库后通知 Track(发货出库 → Track 标记"已出库")
|
||||
# 仅在配置 TRACK_OUTBOUND_WEBHOOK_URL 时生效;notify_track 自身容错不阻断业务
|
||||
# 按每条的 company_name 路由到对应实例(IRIS / LICA)。
|
||||
# 这里刻意**不**显式传 url:显式 url 优先级最高,会一律打到默认实例,
|
||||
# 导致 LICA 的出库永远收不到联动。notify_track 自身容错,不阻断业务。
|
||||
try:
|
||||
from flask import current_app
|
||||
outbound_url = current_app.config.get('TRACK_OUTBOUND_WEBHOOK_URL')
|
||||
for sn, src_tbl, qty in track_notifications:
|
||||
for sn, src_tbl, qty, company in track_notifications:
|
||||
if not sn:
|
||||
continue
|
||||
notify_track({
|
||||
@ -432,8 +440,9 @@ class OutboundService:
|
||||
'serial_number': str(sn),
|
||||
'quantity': float(qty or 0),
|
||||
'outbound_type': common_data['outbound_type'],
|
||||
'company_name': company,
|
||||
'operator': get_current_operator(),
|
||||
}, url=outbound_url)
|
||||
})
|
||||
except Exception as e:
|
||||
import logging
|
||||
logging.getLogger(__name__).warning(f"⚠️ Track 出库通知失败: {e}")
|
||||
|
||||
Reference in New Issue
Block a user