ry_wms/README.md

13 KiB
Raw Blame History

详细入库全流程解析

单据创建阶段 (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"。
  • 关键点: 这是异常处理或人工干预分支,不属于标准的出库完成闭环。