|
|
@ -18,6 +18,125 @@ import java.util.stream.Collectors; |
|
|
* @Description 齐套运输处理服务实现类(专门处理单个订单的齐套运输,避免事务自调用失效)- rqrq |
|
|
* @Description 齐套运输处理服务实现类(专门处理单个订单的齐套运输,避免事务自调用失效)- rqrq |
|
|
* @Author rqrq |
|
|
* @Author rqrq |
|
|
* @Date 2025/10/21 |
|
|
* @Date 2025/10/21 |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>================== 齐套运输业务逻辑说明 ==================</b></p> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>一、什么是齐套?</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 齐套是指一个生产订单(由notifyNo+itemNo确定)所需的所有物料都已经从立库出库完成, |
|
|
|
|
|
* 并且这些物料所在的栈板都已离开分拣位(D1/D2/R1-R4/J1-J4),进入缓存区(Z104)等待配送。 |
|
|
|
|
|
* |
|
|
|
|
|
* 齐套的目的是:当一个订单的所有物料都准备好后,统一发起运输任务,将栈板配送到生产区域。 |
|
|
|
|
|
* </pre> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>二、齐套判断条件(必须同时满足)</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 条件1:订单的所有物料明细(so_issue_notify_order_material_list_detail)的 out_wcs_flag='Y' |
|
|
|
|
|
* 即:totalCount == outCount(总数量 = 已出库数量) |
|
|
|
|
|
* |
|
|
|
|
|
* 条件2:订单所有物料关联的栈板都不在分拣位 |
|
|
|
|
|
* 分拣位列表:D1, D2, R1, R2, R3, R4, J1, J2, J3, J4 |
|
|
|
|
|
* 判断方式:遍历订单物料的serialNo → pallet_detail.pallet_id → pallet.location_code |
|
|
|
|
|
* 检查所有location_code是否都不在分拣位列表中 |
|
|
|
|
|
* </pre> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>三、齐套处理流程(5个步骤)</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 步骤1:检查物料出库情况 |
|
|
|
|
|
* - 查询订单物料总数(totalCount)和已出库数(outCount,即out_wcs_flag='Y'的数量) |
|
|
|
|
|
* - 如果 totalCount != outCount,说明物料未全部出库,跳过此订单 |
|
|
|
|
|
* - 如果 totalCount == 0,说明订单没有物料明细,跳过 |
|
|
|
|
|
* |
|
|
|
|
|
* 步骤2:检查栈板位置 |
|
|
|
|
|
* - 查询订单所有物料关联的栈板位置(location_code) |
|
|
|
|
|
* - 如果位置列表为空,说明物料已被人工取走,直接标记订单完成 |
|
|
|
|
|
* - 如果有任何栈板在分拣位,说明物料还在分拣中,跳过此订单 |
|
|
|
|
|
* |
|
|
|
|
|
* 步骤3:获取可用栈板 |
|
|
|
|
|
* - 查询在缓存区(Z104)中,calling_flag='N'且站点status_db=1的栈板 |
|
|
|
|
|
* - 这些是可以发起运输任务的栈板 |
|
|
|
|
|
* - 如果没有可用栈板,说明已随之前任务运走,直接标记transport_flag='Y' |
|
|
|
|
|
* |
|
|
|
|
|
* 步骤4:发起运输任务 |
|
|
|
|
|
* - 逐个为可用栈板创建运输任务 |
|
|
|
|
|
* - 特殊处理:如果订单有条码在分切区,第一个栈板目的地改为分切区(Z106) |
|
|
|
|
|
* - 每个运输任务独立事务,失败不影响其他栈板 |
|
|
|
|
|
* |
|
|
|
|
|
* 步骤5:更新状态 |
|
|
|
|
|
* - 只有全部栈板都成功发起任务,才标记transport_flag='Y' |
|
|
|
|
|
* - 如果有失败的栈板,保持transport_flag='N',等待下次定时任务处理 |
|
|
|
|
|
* - 当申请单下所有订单都transport_flag='Y'时,更新申请单push_wcs_flag='出库完成' |
|
|
|
|
|
* </pre> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>四、相关数据表</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 1. so_issue_notify_order_list:领料申请单订单表 |
|
|
|
|
|
* - notify_no + item_no 确定一个订单 |
|
|
|
|
|
* - production_area:生产区域(运输目的地) |
|
|
|
|
|
* - transport_flag:运输标记(N=未运输,Y=已运输) |
|
|
|
|
|
* - status:订单状态(ISSUE=待领料) |
|
|
|
|
|
* - push_wms_flag:推送WMS标记(Y=已推送) |
|
|
|
|
|
* |
|
|
|
|
|
* 2. so_issue_notify_order_material_list_detail:订单物料明细表 |
|
|
|
|
|
* - notify_no + item_no 关联订单 |
|
|
|
|
|
* - serial_no:物料序列号(条码) |
|
|
|
|
|
* - out_wcs_flag:出库标记(N=未出库,Y=已出库) |
|
|
|
|
|
* |
|
|
|
|
|
* 3. pallet_detail:栈板明细表 |
|
|
|
|
|
* - serial_no 关联物料条码 |
|
|
|
|
|
* - pallet_id:所在栈板 |
|
|
|
|
|
* |
|
|
|
|
|
* 4. pallet:栈板表 |
|
|
|
|
|
* - pallet_id:栈板编码 |
|
|
|
|
|
* - location_code:所在站点(关联agv_station) |
|
|
|
|
|
* - calling_flag:是否正在被调用(Y/N) |
|
|
|
|
|
* |
|
|
|
|
|
* 5. agv_station:AGV站点表 |
|
|
|
|
|
* - station_code:站点编码 |
|
|
|
|
|
* - status_db:站点状态(0=空闲,1=有货,2=待放货,3=待取货) |
|
|
|
|
|
* - area_type:区域类型(如Z104=缓存区) |
|
|
|
|
|
* |
|
|
|
|
|
* 6. so_issue_notify_header:领料申请单表头 |
|
|
|
|
|
* - notify_no:申请单号 |
|
|
|
|
|
* - push_wcs_flag:推送WCS状态(Y=已推送,出库完成=全部订单运输完成) |
|
|
|
|
|
* </pre> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>五、定时任务调度</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 1. 定时任务类:WcsTaskScheduler.scheduleKitTransportCheck() |
|
|
|
|
|
* - 每100秒执行一次 |
|
|
|
|
|
* - 调用 KitTransportService.processKitTransport() |
|
|
|
|
|
* |
|
|
|
|
|
* 2. 处理逻辑:KitTransportServiceImpl.processKitTransport() |
|
|
|
|
|
* - 查询待处理订单(status='ISSUE', push_wms_flag='Y', transport_flag='N') |
|
|
|
|
|
* - 每次最多处理100个订单 |
|
|
|
|
|
* - 逐个调用 processOrderKitTransport() 处理 |
|
|
|
|
|
* - 每个订单处理后休息1秒,避免死锁 |
|
|
|
|
|
* |
|
|
|
|
|
* 3. 单订单处理:本类.processOrderKitTransport() |
|
|
|
|
|
* - 处理单个订单的齐套判断和运输任务创建 |
|
|
|
|
|
* - 返回true表示已齐套并处理,返回false表示未齐套或处理失败 |
|
|
|
|
|
* </pre> |
|
|
|
|
|
* |
|
|
|
|
|
* <p><b>六、特殊场景处理</b></p> |
|
|
|
|
|
* <pre> |
|
|
|
|
|
* 场景1:物料被人工取走 |
|
|
|
|
|
* - 表现:订单物料全部out_wcs_flag='Y',但栈板位置列表为空 |
|
|
|
|
|
* - 处理:直接标记transport_flag='Y',认为已完成 |
|
|
|
|
|
* |
|
|
|
|
|
* 场景2:齐套但无可用栈板 |
|
|
|
|
|
* - 表现:订单齐套了,但缓存区没有可用栈板 |
|
|
|
|
|
* - 原因:可能已随之前的订单运走(多个订单共用栈板) |
|
|
|
|
|
* - 处理:直接标记transport_flag='Y' |
|
|
|
|
|
* |
|
|
|
|
|
* 场景3:分切区物料 |
|
|
|
|
|
* - 表现:订单有物料的仓库是分切区(Z999) |
|
|
|
|
|
* - 处理:第一个栈板目的地改为分切区(Z106),其他栈板照常去生产区域 |
|
|
|
|
|
* |
|
|
|
|
|
* 场景4:部分栈板运输失败 |
|
|
|
|
|
* - 表现:部分栈板发起运输任务失败 |
|
|
|
|
|
* - 处理:保持transport_flag='N',等待下次定时任务重试 |
|
|
|
|
|
* </pre> |
|
|
*/ |
|
|
*/ |
|
|
@Slf4j |
|
|
@Slf4j |
|
|
@Service |
|
|
@Service |
|
|
|