PO → ASN Sync
这个菜单做什么
当你在 AutoCount 为供应商的来货建一张 Purchase Order,这个菜单告诉 WMS 准备收货(称为 "ASN" —— Advance Shipment Notice,预到货通知)。
等货真的到仓库、WMS 标记已收货之后,WMS Sync Hub 会自动在 AutoCount 建好 GRN(Goods Received Note)。不用再重新录入。
⚡ 重点先看
一旦 WMS 报了收货、WMS Sync Hub 在 AutoCount 建好 GRN,Cancel Synced ASN 按钮会被挡 —— 库存已经记进 AutoCount 了,直接取消 ASN 会导致两边对不上。
真的要撤销:
- 先在 AutoCount 用正常方式取消 GRN。
- 回来这里再按 Cancel Synced ASN。
如果你在 AutoCount 里直接删掉那张 PO(或 set Cancelled = 'T'),WMS Sync Hub 会自动检测到,10 秒内帮你在 WMS 那边取消 ASN。不用手动按 Cancel Synced ASN。
但是:如果那张 PO 已经有 GRN,删 PO 的自动取消不会动 WMS(防止出现孤单货)。这种情况下要先取消 GRN 再删 PO。
从 v1.6.1 起,Transfer Selected to ASN 不再先检查 item 是否在 WMS 上。客户偏好让 WMS 自己返回错误(错误信息更权威 + 实时)。
如果有 SKU 没在 WMS 上注册,WMS 会拒绝整张 ASN,错误信息会出现在 Sync Log 里(含完整 request + response payload)。
怎么用
- 照常在 AutoCount 建 Purchase Order。
- 在左侧打开 PO → ASN Sync 菜单。
- 在表格里找你的 PO。可以用 Search 输入 DocNo / 供应商名 / 描述等任一关键字,按 Enter 筛选。
- Ctrl + Click 选中要推的 PO 行(可以一次选最多 10 张)。
- 点表格顶部的 Transfer Selected to ASN。
- 弹出确认对话框,列出要推的 PO 数量,点 Yes。
- 推送结果会逐张显示:
- ✓ 成功的 PO,WMS ASN # 列填上号码
- ✗ 失败的 PO,弹窗显示 WMS 返回的错误(INVALID_DATA、ITEM_NOT_EXISTS 等)
- 货真的到了以后,WMS 标记已收货,WMS Sync Hub 通过 webhook 自动建 GRN。
- GRN # 列会显示新 GRN 的号码。点 View 在 AutoCount 打开 GRN 原始窗口确认。
从 v1.6.2 起,单张 PO 最多可以推超过 1000 行 line items(之前在 ~200 行时会因为 URI 长度限制而失败)。这个限制已被修复(绕过 FormUrlEncodedContent 的内部 cap)。
取消已同步的 ASN
如果你推错 PO,或供应商取消来货:
- 在这菜单找到那张 PO 的行。
- 选中它(同样支持多选),点 Cancel Synced ASN。
- 确认对话框点 Yes。
- ASN 会在 WMS 上取消(worker 在 10 秒内异步处理),WMS ASN # 列清空。
前提:
- 还没建 GRN(
PODTL.TransferedQty = 0) - 否则会被本地的 GRN 检查拦下来,弹窗告诉你哪些 PO 被挡
Retry Failed PO Pushes
如果某张 PO 推送失败(WMS Stage = 'Failed'),原因可能是 SKU 没在 WMS、warehouseCode 配置错、网络问题。修好之后重试:
- 在表格里Ctrl + Click 选中所有 Failed 状态的 PO 行(一次最多 10)。
- 点顶部的 Retry Failed PO Pushes 按钮。
- 弹出确认对话框,列出要重试的 PO 号,点 Yes。
- 状态从 Failed 重置为空,下一轮 AsnCreateWorker poll 会重新推。
之前 AsnCreateWorker 会无限重试失败的 PO(每 15 秒一次)—— 如果 PO 数据有永久问题(item 没在 WMS、warehouseCode 错),会一直骚扰 WMS 服务器。
现在失败的 PO 会被 park 为 WmsStage = 'Failed',不再自动重试。你必须看 Sync Log 找出原因,修复,然后用 Retry Failed PO Pushes 主动重试。
多 GRN per PO(v1.6.5+)
WMS 收货是分批的 —— 比如 PO 订 100 EA,仓库可能:
- 早上收 30 EA → 发一次 webhook(status=RECEIVING)
- 下午又收 60 EA(累计 90) → 第二次 webhook(status=RECEIVING)
- 全部收完 → 第三次 webhook(status=RECEIVED)
每次 webhook,WMS Sync Hub 都会建一张新 GRN,只含这一次新增的部分(delta),不重复入库。
| Webhook | WMS 累计 | 已 booked | Delta | 建的 GRN |
|---|---|---|---|---|
| 1 (RECEIVING) | 30 EA | 0 | 30 | GR-A 收 30 EA |
| 2 (RECEIVING) | 90 EA | 30 | 60 | GR-B 收 60 EA |
| 3 (RECEIVED) | 100 EA | 90 | 10 | GR-C 收 10 EA |
| 4 (重传 / 同样 100 EA) | 100 EA | 100 | 0 | (跳过,没新增) |
总入库 = 30 + 60 + 10 = 100 EA,与 WMS 完全对齐。
Plugin 怎么显示多 GRN
PO → ASN Sync 页面现在是 master / detail 视图:
- Master 行:每张 PO 一行,含 GRNs 列显示该 PO 共建了几张 GRN
- ▶ 展开:看到这张 PO 下所有 GRN 的明细
- GRN # (带 View 按钮,点开 AutoCount 原始 GRN 窗口)
- WMS Status(RECEIVING / RECEIVED / CLOSED — 是哪次 webhook 触发的)
- GRN Date
- Created By
- Items(GRN 行数)
- Webhook At(webhook 到达时间)
GRN 单位 = PO 单位
WMS 用 EA(最小单位)报告收货数量,但 GRN 写入时自动换算回 PO 的 UOM(通常是 CT):
- WMS 收 24 EA + Rate=12 → GRN 写 2 CT
- WMS 收 18 EA → GRN 写 1.5 CT(如果 item 允许小数)
- UnitPrice 直接从
PODTL.UnitPrice拷过来 —— 单位、价格、数量三者一致
重传保护(自动)
WMS 网络抖动会重发同一个 webhook。新逻辑天然处理:
- 同样的 cumulative qty → delta = 0 → 直接跳过,不建 GRN
- Sync Log 里看到
delta = 0 ... nothing new to GRN的记录就是被正确拦下的
常见问题
- 问:我还需要手动录入 GRN 吗? 不用 —— WMS 一收货,WMS Sync Hub 自动建。每批货建一张 GRN。
- 问:供应商只送了部分 PO 的货怎么办? 自动建部分 GRN(只含已收的部分)。下次再送货会建另一张新 GRN,跟 PO 累计加起来。
- 问:一张 PO 有多张 GRN 怎么看? PO → ASN Sync 页面,点最左边的 ▶ 展开 → 显示该 PO 所有 GRN 的列表。
- 问:同步 ASN 后还能改 PO 吗? 改之前先取消 ASN(按 Cancel Synced ASN)。GRN 已经建了的话,要先在 AutoCount 取消 GRN 才能改。
- 问:怎么看 PO 推送时 WMS 返回的具体错误? 去 Sync Log,筛 Type = ASN_CREATE,找你的 PO 号,双击打开 View Payload 对话框,里面有完整的 request + response JSON。
- 问:WMS 报告的数量跟实际 GRN 数量对得上吗?
对。每张 GRN 都按 WMS 当时的 cumulative 减去之前已 booked 算 delta;GRN 保存后立刻把那段 EA 加到
PODTL.TransferedQty。下一个 webhook 算 delta 时基准已经更新,永不重复。