ry_wms/README.md

249 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### 详细入库全流程解析
#### 单据创建阶段 (Creation)
* 动作: 用户通过 add 接口新增,或 importData 导入 Excel。
* 数据变更:
* 插入 TRkWareNotice状态 ReceivingStatus = "0"。
* 插入 TRkWareNoticeTab状态 ReceivingStatus = "0", InStatus = "0"。
#### 收货确认阶段 (Receiving / Task Generation)
此阶段是“实物清点与任务生成”,并非流程的终点。
* 接口: confirmNoticeTab
* 业务逻辑:
1. 校验: 检查托盘状态、是否冻结InStatus=="1")。
2. 更新收货量: 累加 RecNum (累计收货数量)。
3. 判定冻结: 如果 RecNum (累计收货) == ReceivingNum (应收总数),将明细 InStatus 更新为 "1"。这标志着该物料收货动作结束,不能再收了。
4. 生成任务: 创建 TOngoodsshelf (入库任务),状态 InStatus = "0"。
5. 发送通知: 生成 TCallNotice通知下游如AGV或搬运工执行上架任务。
* 关键点: 此时单据状态 `ReceivingStatus` 依然是 `"0"`,库存表尚未增加库存。
#### 上架确认阶段 (Putaway / Completion)
此阶段是“任务执行与库存生成”,驱动状态流转。
* 接口: shelvesConfirm
* 业务逻辑:
1. 校验: 检查库位 (LocationId) 有效性。
2. 更新上架量: 累加 AcceNum (累计上架数量)。
3. 更新明细状态:
* 若 AcceNum < RecNum: 设置 ReceivingStatus = "1" (部分上架)。
* AcceNum >= RecNum: 设置 ReceivingStatus = "2" (全部上架)。
4. 完成任务: 将 TOngoodsshelf 移入历史表 TOngoodsshelfBak并从原表删除。
5. 生成库存:
* 普通模式: 插入 TMiStock (真实库存)。
* 虚拟模式 (Fictitious="1"): 插入 TMiStockF (虚拟库存)。
6. 判断主单完结:
* 遍历该单据下所有明细。
* 如果所有明细的状态都为 `"2"` (已上架),则触发归档流程。
#### 归档流程 (Archiving)
当上架确认检测到主单完结时自动触发。
* 更新主单: 将 TRkWareNotice 的 ReceivingStatus 设为 "2"。
* 同步收货表: 更新或插入 TRkReceivingGoods (收货记录表)。
* 历史迁移:
* 将主单数据移入 TRkWareNoticeBak。
* 将明细数据移入 TRkWareNoticeTabBak。
* 数据清理: 物理删除 TRkWareNotice 和 TRkWareNoticeTab 中的原数据。
* 关闭通知: 关闭关联的 TCallNoticeOrder 任务。
### 详细出库流程解析
> TCkOrdersServiceImpl
> TCkPickingwavegoodsServiceImpl
#### 单据创建阶段 (Creation)
* 动作:
* 用户通过 add 接口新增主单,或通过 importData 导入 Excel。
* 用户通过 updateTckOrderDetails 维护出库明细。
* 数据变更:
* 插入 TCkOrders主单状态 Status = "0"(新建)。
* 插入或更新 TCkOrderdetail明细 ConfirmStatus = "0"(待执行)。
* 业务逻辑:
1. 校验来源单号 DeliveryId 不能重复。
2. 校验同一单据内不能重复添加相同 GoodsId。
3. 若对应物料已有锁定库存,则不允许继续追加明细。
4. 回填价格、总金额、建单人、部门、记录人等基础信息。
* 关键点: 此阶段只是在系统内形成“出库需求”,还不会锁库存,也不会生成拣货任务。
#### 审核提交流程 (Audit Submission)
这一步负责把出库申请送入审批链,而不是直接执行出库。
* 接口: changeStatus / auditCkOrders
* 业务逻辑:
1. 查询当前出库单及其全部明细。
2. 将明细转换成 GoodsVo 列表,组装 OutBound 审批数据。
3. 把每条明细的 CallShelvesNum 回写为申请数量 ShelvesNum。
4. 调用钉钉创建审批实例,生成 InstanceId。
5. 写入本地 OutBound 审批记录,并把 InstanceId 回写到 TCkOrders。
* 关键点:
* updateStatus 负责发起审批流。
* auditCkOrders 是本地审核通过入口。
#### 任务分流阶段 (Dispatch)
审核通过后,系统会根据仓库类型决定走“推送 IWMS”还是“本地生成出库任务”。
* 接口: send / sendiwms / issue
* 业务逻辑:
1. send 会按仓库是否为 AGV 仓拆分出库明细。
2. AGV 仓明细调用 sendIwms向 IWMS 推送出库数据。
3. 非 AGV 仓明细调用 confirmOut走本地锁库与任务生成。
4. 手持出库 issue 会先自动创建一张已审核的普通出库单,再直接调用 confirmOut。
* 数据变更:
* sendIwms 成功后,会回写明细 TrNum = GoodsNum、PickNum并把 CkType 置为普通出库。
* 关键点: sendOrderNotice 还保留了向手持端补发 TCallNoticeOrder 的能力,但当前控制层入口已注释。
#### IWMS 推送阶段 (AGV Branch)
该分支只处理 AGV 仓明细,主要目标是把出库需求推送给外部 IWMS。
* 接口: sendiwms / sendIwms
* 业务逻辑:
1. 重新加载当前出库单,筛选出 AGV 仓明细。
2. 按 GoodsId、GoodsName、Ctl、StorageId、ShelvesNum 匹配库存记录。
3. 逐条组装推送报文,包含单号、物料、数量、追溯码、仓库、容器类型等字段。
4. 调用外部接口 `pushOutOrder` 发送数据。
5. 外部返回“成功”后,回写对应明细的提货数量与出库类型。
* 关键点: 该分支负责“推送外部系统”,不在本类内创建 TCkPickingwavegoods 本地拣货任务。
#### 本地出库任务生成阶段 (Local Task Generation)
这一阶段是 TCkOrdersServiceImpl 内最核心的“选库存 + 锁库存 + 生成任务”流程。
* 接口: confirmOut
* 业务逻辑:
1. 校验出库明细不能为空,并跳过 ConfirmStatus = "2" 的已完成明细。
2. 按物料、仓库、托盘号 Ctl、库位 LocationId 查询可用库存;若未指定仓库,则从当前部门有权限的仓库中查找。
3. 若指定了 Ctl则按托盘分组否则按库位分组逐组累加库存直到满足 GoodsNum。
4. 将本次命中的库位与数量写回明细:累计 PickNum并把销售单号集合拼接到 BusinessId。
5. 将主单 TCkOrders.Status 更新为 "1"(已锁定)。
6. 把“按物料汇总”的结果转换成“按库位汇总”的任务数据,避免同一库位重复创建任务。
7. 校验该库位是否已存在同单出库任务;若不存在,则进入 createLocationOutboundTasks。
8. 按仓库维度发送 TCallNotice 出库通知。
* 关键点: 这里完成的是库存占用与任务拆分,不是最终库存扣减。
#### 库存锁定与拣货任务落地 (Stock Locking / Picking Task Creation)
* 接口: createLocationOutboundTasks由 confirmOut 内部调用)
* 业务逻辑:
1. 对命中的每条 TMiStock 回写 OccupyNum并把库存状态设为 "1"(已锁定)。
2. 逐条生成 TCkPickingwavegoods 拣货任务,带出托盘号、库位、批次、库存主键、来源单号、仓库等信息。
3. 初始化拣货任务 RecNum = 0、ConfirmStatus = "0"(待执行),并挂接同一个 CallNoticeId。
* 数据变更:
* 更新 TMiStock。
* 插入 TCkPickingwavegoods。
* 发送 TCallNotice。
* 关键点: 本类到这里为止,已经完成出库资源占用和任务下发。
#### 调拨联动阶段 (Transfer)
调拨出库是本类中的另一条专用支路,会同时联动生成一张入库通知单。
* 接口: create / install
* 业务逻辑:
1. 创建一张 TCkOrders 调拨出库单OrderType 和 CkType 都为调拨出库。
2. 写入对应的 TCkOrderdetail 调拨明细。
3. 同步创建一张 TRkWareNotice 调拨入库通知单,以及对应的 TRkWareNoticeTab 明细。
4. 创建 TransferOrder把出库单和入库单关联起来。
* 关键点: 这里完成的是“调拨单据联动建单”,后续实际出库仍要继续走任务分配或确认链路。
#### 流程边界说明 (Boundary)
从 TCkOrdersServiceImpl 代码来看,它主要负责“建单、审批、分流、锁库、建拣货任务、推送 IWMS”。
* 关键点:
* 本类没有完成最终的库存实扣。
* 本类没有完成拣货任务归档。
* 本类也没有把主单推进到“出库完成”终态。
* 结论: 真正的拣货执行、库存扣减、任务完成与归档,发生在后续拣货/出库执行链路,而不是在本类中闭环完成。
### 出库执行闭环补充TCkPickingwavegoods
#### 拣货确认阶段 (Picking Confirmation)
这一阶段对应实际执行出库任务后的确认动作,是本地出库链路真正开始“落账”的地方。
* 接口: confirm
* 业务逻辑:
1. 校验提交的拣货确认明细不能为空。
2. 按当前托盘/任务条件查询待拣任务,若未查到任务则直接报错。
3. 要求本次确认必须把同一批待确认任务一起提交,否则拒绝确认。
4. 先把出库主单 TCkOrders.Status 重置为 "0",解除前一阶段的锁定态。
5. 遍历每条 TCkPickingwavegoods依次执行库存实扣、任务备份、明细累计出库量更新。
* 关键点: confirm 使用的是拣货任务上的 RecNum本次实际出库数量而不是申请数量 ShelvesNum。
#### 库存实扣与资源释放阶段 (Stock Deduction / Resource Release)
* 内部方法: updateTmiStock
* 业务逻辑:
1. 通过 DoctNumber 定位被锁定的 TMiStock 库存记录。
2. 用库存现存量 ShelvesNum 减去本次实际出库量 RecNum。
3. 若扣减后库存为 0则直接删除该库存记录。
4. 若扣减后仍有余量,则把库存状态恢复为 "0",并把 OccupyNum 清零。
5. 若当前库位已无任何库存,则把 TBaseStorageAreaLocation.Status 释放为 "0"。
6. 若当前托盘号 Ctl 下已无库存,则把托盘 TBasePallet.Status 释放为 "0"。
* 关键点: confirmOut 负责“占用库存”confirm 才真正完成“库存实扣”。
#### 任务备份与明细回写阶段 (Task Backup / Detail Update)
* 业务逻辑:
1. 每条已确认的 TCkPickingwavegoods 都会复制到 TCkPickingwavegoodsBak。
2. 备份记录的 ConfirmStatus 会被置为 "3"。
3. 回写对应的 TCkOrderdetailTrNum += RecNum表示累计实际出库量增加。
4. 清空本次明细上的 GoodsNum避免旧的申请数量继续参与后续出库。
5. 若 TrNum == ShelvesNum则把明细 ConfirmStatus 更新为 "2"(全部完成)。
6. 若 TrNum < ShelvesNum则把明细 ConfirmStatus "0" 推进为 "1"部分完成)。
* 关键点: 出库明细是否完成取决于累计实际出库量 TrNum 是否追平申请数量 ShelvesNum
#### 主单收口与归档阶段 (Order Convergence / Archiving)
系统会在每次确认后重新判断整张出库单是否已经全部完成
* 业务逻辑:
1. 重新查询该出库单下全部 TCkOrderdetail
2. 只要还有任意一条明细 ConfirmStatus 不是 "2"则主单仍未完结
3. 若主单未完结则把 TCkOrders.ConfirmStatus 更新为 "1"部分完成)。
4. 若主单全部完成则把 TCkOrders 备份到 TckOrdersBak
5. 同时把全部 TCkOrderdetail 备份到 TckOrderdetailBak并补齐审核人审核时间申请人驳回原因等主单信息
6. 备份完成后物理删除原 TCkOrders TCkOrderdetail 数据
* 关键点: 主单是否归档不取决于是否生成过任务而取决于所有明细是否都已完成实际出库
#### 任务删除与通知关闭阶段 (Task Cleanup / Notice Closing)
* 业务逻辑:
1. 当前批次确认完成后会删除对应的原始 TCkPickingwavegoods 任务
2. 再按 CallNoticeId 查询是否还存在未完成的同批呼叫任务
3. 若同一 CallNoticeId 下已无剩余任务则关闭对应的 TCallNotice 出库通知
* 关键点: 通知关闭的判断粒度是 CallNoticeId不是单条拣货任务
#### 设备平台推送阶段 (Device Push)
当某个呼叫批次下的本地出库任务全部结束后系统会尝试把出库完成结果推送到设备管理平台
* 内部方法: sendDevice
* 业务逻辑:
1. 生成签名并组装请求头
2. 以已完成的出库主单和明细为基础拼装外部表单数据
3. 调用设备平台 `batchSaveEntity` 接口推送出库完成结果
4. 不论成功还是失败都会记录 DeviceLog 日志
* 关键点:
* 成功时返回推送成功出库完成”。
* 失败时返回出库完成请求超时或失败或签名失败提示
#### 手工撤销补充 (Manual Cleanup)
除正常确认链路外代码中还保留了手工删除出库任务的兜底处理
* 接口: deleteTCkPickingwavegoodsByIds
* 业务逻辑:
1. 按任务查出对应托盘号 Ctl
2. 删除该托盘关联的出库任务记录
3. 将该托盘关联库存状态释放为 "0"。
* 关键点: 这是异常处理或人工干预分支不属于标准的出库完成闭环