From 4605e62f1d1f07d3cbad26c8dd73cb0c2871e953 Mon Sep 17 00:00:00 2001 From: lyd <1419499670@qq.com> Date: Tue, 15 Nov 2022 17:40:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wms/ext/acs/rest/AcsToWmsController.java | 13 + .../wms/ext/acs/service/AcsToWmsService.java | 6 + .../acs/service/impl/AcsToWmsServiceImpl.java | 358 +++++++++----- .../org/nl/wms/sch/manage/RegionIOEnum.java | 37 ++ .../java/org/nl/wms/sch/manage/UnitEnum.java | 30 ++ .../wms/sch/manage/UpdateTaskStatusEnum.java | 28 ++ .../callEmpty/FjCallEmptyVehicleTask.java | 283 +++++++++++ .../callEmpty/GjxCallEmpVehicleTask.java | 444 ----------------- .../callEmpty/HnCallEmptyVehicleTask.java | 261 ++++++++++ .../callEmpty/YqxCallEmpVehicleTask.java | 450 ------------------ .../callEmpty/YzjCallEmptyVehicleTask.java | 310 ++++++++++++ .../wql/QSCH_GjxCallEmpVehicleTask.wql | 60 --- .../wql/QSCH_fjCallEmptyVehicle_01.wql | 88 ++++ .../wql/QSCH_hnCallEmptyVehicle_01.wql | 65 +++ .../wql/QSCH_yzjCallEmptyVehicle_01.wql | 85 ++++ .../callMaterial/FjCallMaterialTask.java | 271 +++++++++++ .../callMaterial/SzCallMaterialTask.java | 283 +++++++++++ ...rialTask.java => YzjCallMaterialTask.java} | 213 +++++---- ...rial_01.wql => QSCH_cyCallMaterial_01.wql} | 5 +- .../wql/QSCH_szCallMaterial_01.wql} | 65 +-- .../wql/QSCH_yzjCallMaterial_01.wql | 71 +++ .../tasks/sendEmpty/DpSendEmpVehicleTask.java | 203 ++++++++ .../tasks/sendEmpty/FjSendEmpVehicleTask.java | 197 ++++++++ .../tasks/sendEmpty/HnSendEmpVehicleTask.java | 196 ++++++++ .../sendEmpty/YzjSendEmpVehicleTask.java | 231 +++++++++ .../wql/QSCH_hnSendEmptyVehicle_01.wql | 71 +++ .../sendMaterial/FjSendMaterialTask.java | 281 +++++++++++ .../sendMaterial/GjxSendMaterialTask.java | 379 --------------- ...erialTask.java => HnSendMaterialTask.java} | 221 +++++---- .../tasks/sendMaterial/SendMaterialTask.java | 230 +++++++++ .../sendMaterial/SzSendMaterialTask.java | 290 +++++++++++ .../sendMaterial/YqxSendMaterialTask.java | 275 ----------- .../sendMaterial/YzjSendMaterialTask.java | 294 ++++++++++++ .../wql/QSCH_fjCallEmptyVehicle_01.wql | 66 +++ ...rial_01.wql => QSCH_hnSendMaterial_01.wql} | 8 +- ...rial_01.wql => QSCH_szSendMaterial_01.wql} | 17 +- .../wql/QSCH_yzSendMaterial_01.wql} | 51 +- .../service/impl/RegionIoServiceImpl.java | 3 - .../src/main/java/org/nl/wms/wms.xls | Bin 258560 -> 278016 bytes .../src/views/wms/pdm/device/index.vue | 9 +- .../src/views/wms/sch/point/index.vue | 6 +- 41 files changed, 4444 insertions(+), 2010 deletions(-) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionIOEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UnitEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/SzCallMaterialTask.java rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/{YqxCallMaterialTask.java => YzjCallMaterialTask.java} (81%) rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/{QSCH_yqxCallMAterial_01.wql => QSCH_cyCallMaterial_01.wql} (94%) rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/{sendMaterial/wql/QSCH_gjxSendMaterial_01.wql => callMaterial/wql/QSCH_szCallMaterial_01.wql} (54%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/HnSendEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_hnSendEmptyVehicle_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/{HkxSendMaterialTask.java => HnSendMaterialTask.java} (80%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjCallEmptyVehicle_01.wql rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/{QSCH_hkxSendMaterial_01.wql => QSCH_hnSendMaterial_01.wql} (96%) rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/{QSCH_yqxSendMaterial_01.wql => QSCH_szSendMaterial_01.wql} (77%) rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/{callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql => sendMaterial/wql/QSCH_yzSendMaterial_01.wql} (51%) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java index 0fe289f..b4d50f1 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java @@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Map; + /** * @author ludj * @date 2021-07-21 @@ -51,6 +53,17 @@ public class AcsToWmsController { return new ResponseEntity<>(acsToWmsService.apply(whereJson), HttpStatus.OK); } + @PostMapping("/manipulatorApply") + @Log("ACS机械手给WMS发送任务") + @ApiOperation("ACS机械手给WMS发送任务") + public ResponseEntity manipulatorApply(@RequestBody Map whereJson) { + acsToWmsService.manipulatorApply(whereJson); + JSONObject result = new JSONObject(); + result.put("status", HttpStatus.OK.value()); + result.put("message", "发送任务成功"); + return new ResponseEntity<>(result, HttpStatus.OK); + } + @PostMapping("/againApply") @Log("二次申请任务") @ApiOperation("二次申请任务") diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java index 17e9538..800a8c6 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java @@ -51,4 +51,10 @@ public interface AcsToWmsService { */ JSONObject apply(JSONObject whereJson); + /** + * ACS机械手给WMS发送任务 + * 组盘 + * @param whereJson + */ + void manipulatorApply(Map whereJson); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java index 40fd615..4d24a98 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java @@ -1,6 +1,7 @@ package org.nl.wms.ext.acs.service.impl; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; @@ -8,6 +9,7 @@ import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.SpringContextHolder; import org.nl.wms.ext.acs.service.AcsToWmsService; @@ -15,14 +17,16 @@ import org.nl.wms.log.LokiLog; import org.nl.wms.log.LokiLogType; import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.service.TaskService; -import org.nl.wms.sch.tasks.callEmpty.GjxCallEmpVehicleTask; -import org.nl.wms.sch.tasks.callEmpty.YqxCallEmpVehicleTask; -import org.nl.wms.sch.tasks.callMaterial.YqxCallMaterialTask; -import org.nl.wms.sch.tasks.sendEmpty.HtSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendEmpty.YqxSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendMaterial.GjxSendMaterialTask; -import org.nl.wms.sch.tasks.sendMaterial.HkxSendMaterialTask; -import org.nl.wms.sch.tasks.sendMaterial.YqxSendMaterialTask; +import org.nl.wms.sch.tasks.callEmpty.FjCallEmptyVehicleTask; +import org.nl.wms.sch.tasks.callEmpty.HnCallEmptyVehicleTask; +import org.nl.wms.sch.tasks.callEmpty.YzjCallEmptyVehicleTask; +import org.nl.wms.sch.tasks.callMaterial.FjCallMaterialTask; +import org.nl.wms.sch.tasks.callMaterial.SzCallMaterialTask; +import org.nl.wms.sch.tasks.callMaterial.YzjCallMaterialTask; +import org.nl.wms.sch.tasks.sendEmpty.DpSendEmpVehicleTask; +import org.nl.wms.sch.tasks.sendEmpty.FjSendEmpVehicleTask; +import org.nl.wms.sch.tasks.sendEmpty.YzjSendEmpVehicleTask; +import org.nl.wms.sch.tasks.sendMaterial.*; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -170,133 +174,235 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Transactional(rollbackFor = Exception.class) public JSONObject apply(JSONObject whereJson) { String type = whereJson.getString("type"); - String point_code = whereJson.getString("point_code"); - String vehicle_type = whereJson.getString("vehicle_type"); + String point_code = whereJson.getString("device_code"); String vehicle_code = whereJson.getString("vehicle_code"); - //载具数量 - String vehicle_num = whereJson.getString("vehicle_num"); - //物料数量 - String material_num = whereJson.getString("material_num"); + String is_full = whereJson.getString("is_full"); + String weight = whereJson.getString("weight"); + String qty = whereJson.getString("qty"); + if (ObjectUtil.isEmpty(type)) throw new BadRequestException("类型不能为空"); if (ObjectUtil.isEmpty(point_code)) throw new BadRequestException("点位不能为空"); + // 参数统一获取 + JSONObject param = new JSONObject(); + param.put("vehicle_code", vehicle_code); + param.put("is_full", is_full); + param.put("weight", weight); + param.put("qty", qty); + /* * 根据type判断是什么业务类型: - * 1.共挤线申请空盘 - * 2.共挤线满托入库 - * 3.油漆线申请空盘 - * 4.油漆线申请物料 - * 5.油漆线空盘入库 - * 6.一楼空盘入库 (有载具号) - * 7.油漆线->输送线(油漆线满料) - * 8.豪凯自动线下料入库 + * 1.混碾机送料入库-困料货架 + * 2.混碾机呼叫空托盘 + * 3.压制机下料位叫料出库 + * 4.压制机下料位送空托盘 + * 5.压制机满料入库 + * 6.压制机呼叫空钢托盘 + * 7.烧制叫料出库 + * 8.烧制送料入库 + * 9.分拣叫料出库 + * 10.分拣送空钢托盘 + * 11.分拣送料入库 + * 12.分拣呼叫木托盘 + * 13.叠盘区送空钢托盘 */ - if (StrUtil.equals(type, "1")) { - // 1.共挤线申请空盘: 调用空托盘出库处理类创建任务 - if (ObjectUtil.isEmpty(vehicle_num)) throw new BadRequestException("数量不能为空"); - - JSONObject param = new JSONObject(); - param.put("point_code2", point_code); - param.put("vehicle_type", vehicle_type); - param.put("vehicle_code", vehicle_code); - param.put("qty", material_num); - // 创建任务 - GjxCallEmpVehicleTask taskBean = SpringContextHolder.getBean(GjxCallEmpVehicleTask.class); - taskBean.createTask(param); - - } else if (StrUtil.equals(type, "2")) { - // 2.共挤线满托入库: 调用物料入库处理类创建任务 - if (ObjectUtil.isEmpty(material_num) || (StrUtil.equals(material_num, "0"))) - throw new BadRequestException("物料数量不能为空或者为0"); - - JSONObject param = new JSONObject(); - param.put("point_code1", point_code); // 满料位 - param.put("qty", material_num); // 满料位 - param.put("vehicle_type", vehicle_type); - param.put("vehicle_code", vehicle_code); - - GjxSendMaterialTask taskBean = SpringContextHolder.getBean(GjxSendMaterialTask.class); - String task_id = taskBean.createTask(param); // 创建任务 - } else if (StrUtil.equals(type, "3")) { - // 3.油漆线申请空盘: 调用空托盘出库处理类创建任务 - if (ObjectUtil.isEmpty(vehicle_num)) throw new BadRequestException("数量不能为空"); - - JSONObject param = new JSONObject(); - param.put("point_code2", point_code); - param.put("vehicle_code", vehicle_code); - param.put("qty", vehicle_num); - // 创建任务 - YqxCallEmpVehicleTask taskBean = SpringContextHolder.getBean(YqxCallEmpVehicleTask.class); - String task_id = taskBean.createTask(param); - } else if (StrUtil.equals(type, "4")) { - // 4.油漆线申请物料: 调用物料出库库处理类创建任务 - JSONObject param = new JSONObject(); - param.put("point_code2", point_code); // 叫料点 - param.put("io_type", "2"); - param.put("vehicle_type", vehicle_type); - param.put("vehicle_code", vehicle_code); - param.put("material_num", material_num); - // 创建任务 - YqxCallMaterialTask taskBean = SpringContextHolder.getBean(YqxCallMaterialTask.class); - String task_id = taskBean.createTask(param); - - } else if (StrUtil.equals(type, "5")) { - // 5.油漆线空盘入库: 调用空托盘入库处理类创建任务 - if (ObjectUtil.isEmpty(point_code)) throw new BadRequestException("点位不能为空"); - if (ObjectUtil.isEmpty(vehicle_num)) throw new BadRequestException("数量不能为空"); - if (ObjectUtil.isEmpty(vehicle_type)) throw new BadRequestException("载具类型不能为空"); - - JSONObject param = new JSONObject(); - param.put("point_code1", point_code); - param.put("qty", vehicle_num); - param.put("vehicle_type", vehicle_type); - param.put("vehicle_code", vehicle_code); - // 创建任务 - YqxSendEmpVehicleTask taskBean = SpringContextHolder.getBean(YqxSendEmpVehicleTask.class); - taskBean.createTask(param); - - - } else if (StrUtil.equals(type, "6")) { - // 6.一楼空盘入库 (有载具号): 调用空托盘入库处理类创建任务 - if (ObjectUtil.isEmpty(vehicle_code)) throw new BadRequestException("载具号不能为空"); - JSONObject param = new JSONObject(); - - // 查询载具号对应的数量 - JSONObject jsonVeQty = new JSONObject(); - if (ObjectUtil.isEmpty(vehicle_num)) { - if (ObjectUtil.isEmpty(jsonVeQty)) throw new BadRequestException("请先手持扫码"); - } else { - jsonVeQty.put("qty", vehicle_num); - } - - param.put("qty", jsonVeQty.getString("qty")); - param.put("point_code1", point_code); - param.put("vehicle_code", vehicle_code); - param.put("vehicle_type", vehicle_type); - // 创建任务 - HtSendEmpVehicleTask taskBean = SpringContextHolder.getBean(HtSendEmpVehicleTask.class); - String task_id = taskBean.createTask(param); - - } else if (StrUtil.equals(type, "7")) { - JSONObject param = new JSONObject(); - param.put("point_code1", point_code); - param.put("vehicle_code", vehicle_code); - param.put("vehicle_type", vehicle_type); - param.put("qty", material_num); - // 1.生成起点确定的任务 - SpringContextHolder.getBean(YqxSendMaterialTask.class).createTask(param); - } else if (StrUtil.equals(type, "8")) { - // 8.豪凯自动线下料入库 - JSONObject param = new JSONObject(); - param.put("point_code1", point_code); - param.put("vehicle_code", vehicle_code); - param.put("vehicle_type", vehicle_type); - param.put("qty", material_num); - HkxSendMaterialTask taskBean = SpringContextHolder.getBean(HkxSendMaterialTask.class); - String task_id = taskBean.createTask(param); - + switch (type) { + case "1": + // 1.混碾机送料入库:混碾机物料送到困料货架 + if (ObjectUtil.isEmpty(point_code)) throw new BadRequestException("设备号不能为空"); + // 创建任务 + param.put("point_code1", point_code); // 起点 + SpringContextHolder.getBean(HnSendMaterialTask.class).createTask(param); + break; + case "2": + if (ObjectUtil.isEmpty(point_code)) throw new BadRequestException("设备号不能为空"); + param.put("point_code2", point_code); // 终点 + // 创建任务 + SpringContextHolder.getBean(HnCallEmptyVehicleTask.class).createTask(param); + break; + case "3": + // 压制机叫料任务 + param.put("point_code2", point_code); // 终点 + // 创建任务 + SpringContextHolder.getBean(YzjCallMaterialTask.class).createTask(param); + break; + case "4": + // 压制机送空托盘 + param.put("point_code1", point_code); // 起点 + // 创建任务 + SpringContextHolder.getBean(YzjSendEmpVehicleTask.class).createTask(param); + break; + case "5": + // 压制机满料入库 + param.put("point_code1", point_code); // 起点 + // 创建任务 + SpringContextHolder.getBean(YzjSendMaterialTask.class).createTask(param); + break; + case "6": + // 压制机呼叫空托盘 + param.put("point_code2", point_code); // 终点 + // 创建任务 + SpringContextHolder.getBean(YzjCallEmptyVehicleTask.class).createTask(param); + break; + case "7": + // 烧制叫料出库 + param.put("point_code2", point_code); // 终点 + SpringContextHolder.getBean(SzCallMaterialTask.class).createTask(param); + break; + case "8": + // 烧制送料入库 + param.put("point_code1", point_code); // 起点 + SpringContextHolder.getBean(SzSendMaterialTask.class).createTask(param); + break; + case "9": + // 分拣叫料出库 + param.put("point_code2", point_code); // 终点 + SpringContextHolder.getBean(FjCallMaterialTask.class).createTask(param); + break; + case "10": + // 分拣送钢托盘 + param.put("point_code1", point_code); // 起点 + SpringContextHolder.getBean(FjSendEmpVehicleTask.class).createTask(param); + break; + case "11": + // 分拣送料入库 + param.put("point_code1", point_code); // 起点 + SpringContextHolder.getBean(FjSendMaterialTask.class).createTask(param); + break; + case "12": + // 分拣呼叫木托盘 + param.put("point_code2", point_code); // 起点 + SpringContextHolder.getBean(FjCallEmptyVehicleTask.class).createTask(param); + break; + case "13": + // 叠盘区送空钢托盘 + param.put("point_code1", point_code); // 起点 + SpringContextHolder.getBean(DpSendEmpVehicleTask.class).createTask(param); + break; } return null; } + + /** + * ACS机械手给WMS发送任务 + * 组盘 + * + * @param jsonObject + */ + @Override + public void manipulatorApply(Map jsonObject) { + //组盘 + JSONObject produceInfoByCode = new JSONObject(); + String device_code = (String) jsonObject.get("device_code"); + String vehicle_code = (String) jsonObject.get("vehicle_code"); + String qty = String.valueOf(jsonObject.get("qty")); + produceInfoByCode = this.getProduceInfoByCode(device_code); + String material_id = (String) produceInfoByCode.get("material_id"); + String cust_id = (String) produceInfoByCode.get("cust_id"); + String producetask_id = (String) produceInfoByCode.get("producetask_id"); + WQLObject.getWQLObject("st_buss_vehiclegroup").delete("vehicle_code ='" + vehicle_code + "'"); + // 如果上报不了,则去点位上取(木托盘情况) + if (StrUtil.equals("0", vehicle_code)) { + vehicle_code = produceInfoByCode.getString("vehicle_code"); + } + JSONObject materialObj = WQLObject + .getWQLObject("MD_ME_Material") + .query("material_id='" + material_id + "'") + .uniqueResult(0); + JSONObject groubObj = new JSONObject(); + groubObj.put("group_id", IdUtil.getSnowflake(1, 1).nextId()); + + groubObj.put("vehicle_code", vehicle_code); + groubObj.put("material_uuid", material_id); + groubObj.put("material_code", materialObj.getString("material_code")); + groubObj.put("material_name", materialObj.getString("material_name")); + groubObj.put("cust_id", cust_id); + groubObj.put("qty", qty); + groubObj.put("producetask_id", producetask_id); + groubObj.put("AlongSide", jsonObject.get("AlongSide")); + groubObj.put("BshortSide", jsonObject.get("BshortSide")); + groubObj.put("Htrapezoidal", jsonObject.get("Htrapezoidal")); + groubObj.put("Wthickness", jsonObject.get("Wthickness")); + groubObj.put("tray_qty", jsonObject.get("tray_qty")); + groubObj.put("crib_category", jsonObject.get("crib_category")); + groubObj.put("tray_high", jsonObject.get("tray_high")); + groubObj.put("palletX1_line", jsonObject.get("palletX1_line")); + groubObj.put("palletY1_row", jsonObject.get("palletY1_row")); + groubObj.put("palletA1_angle", jsonObject.get("palletA1_angle")); + groubObj.put("palletX2_line", jsonObject.get("palletX2_line")); + groubObj.put("palletY2_row", jsonObject.get("palletY2_row")); + groubObj.put("palletA2_angle", jsonObject.get("palletA2_angle")); + groubObj.put("palletX3_line", jsonObject.get("palletX3_line")); + groubObj.put("palletY3_row", jsonObject.get("palletY3_row")); + groubObj.put("pressCribX1_line", jsonObject.get("pressCribX1_line")); + groubObj.put("palletA3_angle", jsonObject.get("palletA3_angle")); + groubObj.put("pressCribY1_row", jsonObject.get("pressCribY1_row")); + groubObj.put("pressCribA1_angle", jsonObject.get("pressCribA1_angle")); + groubObj.put("pressCribX2_line", jsonObject.get("pressCribX2_line")); + groubObj.put("pressCribY2_row", jsonObject.get("pressCribY2_row")); + groubObj.put("pressCribA2_angle", jsonObject.get("pressCribA2_angle")); + groubObj.put("pressCribX3_line", jsonObject.get("pressCribX3_line")); + groubObj.put("pressCribY3_row", jsonObject.get("pressCribY3_row")); + groubObj.put("pressCribA3_angle", jsonObject.get("pressCribA3_angle")); + groubObj.put("Zoffset", jsonObject.get("Zoffset")); + groubObj.put("pallet_layerQty", jsonObject.get("pallet_layerQty")); + groubObj.put("pressCrib_layerQty", jsonObject.get("pressCrib_layerQty")); + groubObj.put("codeLayerX1_interval", jsonObject.get("codeLayerX1_interval")); + groubObj.put("codeLayerY1_interval", jsonObject.get("codeLayerY1_interval")); + groubObj.put("pressCrib_layerQty", jsonObject.get("pressCrib_layerQty")); + groubObj.put("codeLayerX2_interval", jsonObject.get("codeLayerX2_interval")); + groubObj.put("codeLayerY2_interval", jsonObject.get("codeLayerY2_interval")); + groubObj.put("codeLayerX3_interval", jsonObject.get("codeLayerX3_interval")); + groubObj.put("codeLayerY3_interval", jsonObject.get("codeLayerY3_interval")); + groubObj.put("codeLayerY1_offset", jsonObject.get("codeLayerY1_offset")); + groubObj.put("codeLayerX1_offset", jsonObject.get("codeLayerX1_offset")); + groubObj.put("codeLayerX3_interval", jsonObject.get("codeLayerX3_interval")); + groubObj.put("codeLayerX2_offset", jsonObject.get("codeLayerX2_offset")); + groubObj.put("codeLayerX3_offset", jsonObject.get("codeLayerX3_offset")); + groubObj.put("codeLayerY3_offset", jsonObject.get("codeLayerY3_offset")); + groubObj.put("pressLayerX1_interval", jsonObject.get("pressLayerX1_interval")); + groubObj.put("pressLayerY1_interval", jsonObject.get("pressLayerY1_interval")); + groubObj.put("pressLayerX2_interval", jsonObject.get("pressLayerX2_interval")); + groubObj.put("pressLayerY2_interval", jsonObject.get("pressLayerY2_interval")); + groubObj.put("pressLayerX3_interval", jsonObject.get("pressLayerX3_interval")); + groubObj.put("pressLayerY3_interval", jsonObject.get("pressLayerY3_interval")); + groubObj.put("pressLayerX1_offset", jsonObject.get("pressLayerX1_offset")); + groubObj.put("pressLayerY1_offset", jsonObject.get("pressLayerY1_offset")); + groubObj.put("pressLayerX2_offset", jsonObject.get("pressLayerX2_offset")); + groubObj.put("pressLayerY2_offset", jsonObject.get("pressLayerY2_offset")); + groubObj.put("pressLayerX3_offset", jsonObject.get("pressLayerX3_offset")); + groubObj.put("pressLayerY3_offset", jsonObject.get("pressLayerY3_offset")); + groubObj.put("one_cribTotal", jsonObject.get("one_cribTotal")); + groubObj.put("two_cribTotal", jsonObject.get("two_cribTotal")); + groubObj.put("one_qty", jsonObject.get("one_qty")); + groubObj.put("two_qty", jsonObject.get("two_qty")); + groubObj.put("tool_coordinate", jsonObject.get("tool_coordinate")); + groubObj.put("create_id", SecurityUtils.getCurrentUserId()); + groubObj.put("create_name", SecurityUtils.getCurrentNickName()); + groubObj.put("create_time", DateUtil.now()); + WQLObject.getWQLObject("st_buss_vehiclegroup").insert(groubObj); + // 判断是分拣还是压制的送料入库 + if (device_code.startsWith("FJCD")) { + jsonObject.put("type", "11"); + } else { + jsonObject.put("type", "5"); + } + this.apply((JSONObject) jsonObject); + } + + private JSONObject getProduceInfoByCode(String code) { + //根据 设备点位去找生产任务信息 + //1 根据点位去找设备,去找对应的设备信息 + JSONObject pointObj = WQLObject.getWQLObject("sch_base_point").query("point_code ='" + code + "'").uniqueResult(0); + String device_code = pointObj.getString("device_code"); + //2 根据设备去找对应的生产任务 1-未生产、2-已下发、3-生产中、4-暂停、5-完成 + JSONObject productTaskObj = WQLObject.getWQLObject("PDM_BD_WorkOrder") + .query("device_code ='" + device_code + "' and producetask_status in ('3','2','4')", "seq_no") + .uniqueResult(0); + if (ObjectUtil.isEmpty(productTaskObj)) { + throw new BadRequestException("未找到点位为'" + code + "'的生产任务!"); + } + return productTaskObj; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionIOEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionIOEnum.java new file mode 100644 index 0000000..04969a8 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionIOEnum.java @@ -0,0 +1,37 @@ +package org.nl.wms.sch.manage; + +/** + * @author: lyd + * @description: 库存出入库枚举 + * @Date: 2022/11/15 + */ +public enum RegionIOEnum { + // 出入库 + IO_TYPE_IN("1", "入库"), + IO_TYPE_OUT("2", "出库"), + // 订单状态 + BILL_STATUS_GENERATE("1", "生成"), + BILL_STATUS_EXECUTION("2", "执行中"), + BILL_STATUS_FINISH("3", "完成"), + // 创建模式 1-PC产生、2-ACS申请、3-手持创建、4-外部接口产生 + CREATE_MODE_PC("1", "PC产生"), + CREATE_MODE_ACS("2", "ACS申请"), + CREATE_MODE_PDA("3", "手持创建"), + CREATE_MODE_INTERFACE("4", "外部接口产生"); + + private final String code; + private final String name; + + RegionIOEnum(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UnitEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UnitEnum.java new file mode 100644 index 0000000..1a73425 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UnitEnum.java @@ -0,0 +1,30 @@ +package org.nl.wms.sch.manage; + +/** + * @author: lyd + * @description: 计量单位枚举 + * @Date: 2022/11/15 + */ +public enum UnitEnum { + KG("1", "千克"), + ZHONG("4", "盅"), + BLOCK("3", "块"), + TOU("5", "托") +// KG("5", "千克"), + ; + private final String code; + private final String name; + + UnitEnum(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java new file mode 100644 index 0000000..0ab99ae --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java @@ -0,0 +1,28 @@ +package org.nl.wms.sch.manage; + +/** + * @author: lyd + * @description: 更新任务状态 + * @Date: 2022/11/15 + */ +public enum UpdateTaskStatusEnum { + CANCEL("0","取消任务"), + EXECUTION("1","任务执行中"), + FORCEFINISH("2", "强制完成任务"); + + private final String code; + private final String name; + + UpdateTaskStatusEnum(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java new file mode 100644 index 0000000..325859b --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java @@ -0,0 +1,283 @@ +package org.nl.wms.sch.tasks.callEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.RegionIOEnum; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.manage.UpdateTaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author: lyd + * @description: 分拣呼叫木托盘 + * @Date: 2022/11/14 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class FjCallEmptyVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = FjCallEmptyVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + return null; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + + JSONObject requestObj = task.getJSONObject("request_param"); + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + String point_code1 = task.getString("point_code1"); + + if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { + /* + * 取消任务 + */ + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + if (ObjectUtil.isNotEmpty(point_code1)) { + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + + JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + startPoint.put("lock_type", "1"); + pointTab.update(startPoint); + } + } + + if (StrUtil.equals(status, UpdateTaskStatusEnum.EXECUTION.getCode())) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", task.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { + /* + * 更改任务状态为完成 + */ + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + if (startPoint.getString("point_type").equals("1")) { // 包装缓存位 + // 插入出库单 + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 + regionIoObj.put("region_id", startPoint.getString("region_id")); + regionIoObj.put("region_code", startPoint.getString("region_code")); + regionIoObj.put("region_name", startPoint.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code2")); + regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + // 点位更新,起点:空位,解锁; + startPoint.put("point_status", "1"); + startPoint.put("lock_type", "1"); + startPoint.put("task_id", ""); + startPoint.put("pcsn", ""); + startPoint.put("ivt_qty", "0"); + startPoint.put("material_id", ""); + startPoint.put("instorage_time", ""); + startPoint.put("is_full", "2"); + startPoint.put("standing_time", "0"); + startPoint.put("vehicle_type", ""); + startPoint.put("vehicle_code", ""); + } else { // 钢托盘每次就一个 --- 如果是堆叠位5需要更新设备状态?? + startPoint.put("point_status", "1"); + startPoint.put("lock_type", "1"); + startPoint.put("vehicle_qty", "0"); + } + pointTab.update(startPoint); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 + + //任务表【SCH_BASE_Task】 + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); + + + String point_code2 = form.getString("point_code2"); + String sub_device_code = point_code2.substring(0, point_code2.indexOf("_")); + + String device_code = pointTab.query("point_code = '" + sub_device_code + "'").uniqueResult(0).getString("device_code"); + + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("分拣呼叫木托盘") + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .acs_task_type("2") + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .task_group_id(org.nl.wms.util.IdUtil.getLongId()) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + // 先找包装暂存区是否有半满托的,没有就呼叫空的木托盘 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + // 创建任务 + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + // 寻找入窑暂存区是否有半托 + JSONObject noFull = new JSONObject(); + noFull.put("flag", "1"); + noFull.put("region_code", "BZZCQ"); + noFull.put("material_id", taskObj.getString("material_id")); + JSONObject noFullPoint = WQL.getWO("QSCH_fjCallEmptyVehicle_01").addParamMap(noFull).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(noFullPoint)) { // 找到半满托盘,叫料出库 + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code1", noFullPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住起点 + noFullPoint.put("task_id", taskObj.getString("task_id")); + noFullPoint.put("lock_type", "2"); + pointTab.update(noFullPoint); + } else { // 没有就呼叫空的木托盘 + JSONObject param = new JSONObject(); + param.put("flag", "2"); + param.put("region_code", "BZZCQ"); + param.put("vehicle_type", vehicle_type); + JSONObject kmtPoint = WQL.getWO("QSCH_fjCallEmptyVehicle_01").addParamMap(param).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(kmtPoint)) { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code1", kmtPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住起点 + kmtPoint.put("task_id", taskObj.getString("task_id")); + kmtPoint.put("lock_type", "2"); + pointTab.update(kmtPoint); + } else { + taskObj.put("remark", "未找到可用的载具!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java deleted file mode 100644 index 72950a2..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java +++ /dev/null @@ -1,444 +0,0 @@ -package org.nl.wms.sch.tasks.callEmpty; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.nl.modules.common.exception.BadRequestException; -import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.system.util.CodeUtil; -import org.nl.modules.wql.WQL; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.RegionTypeEnum; -import org.nl.wms.util.IdUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -@Service -@RequiredArgsConstructor -@Slf4j -/** - * 共挤线申请空盘 - */ -public class GjxCallEmpVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = GjxCallEmpVehicleTask.class.getName(); - - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject taskObj, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String task_id = taskObj.getString("task_id"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - if (StrUtil.equals(status, "0")) { - /* - * 取消删除 - * 1.终点为叠盘架更新起点点位、等待点点位、叠盘架点位 - * 2.终点为供给线更新叠盘架点位 - */ - if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - - JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - // 终点在叠盘架 - if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQB.getId())) { - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - // 判断此起点是否是等待点 - if (!StrUtil.equals(jsonStart.getString("col_num"), "9")) { - // 如果不是等待点更新等待点状态 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + - "' and block_num = '" + jsonStart.getString("block_num") + - "' and row_num = '" + jsonStart.getString("row_num") + - "' and col_num = '9'").uniqueResult(0); - - jsonEmpWait.put("lock_type", "1"); - pointTab.update(jsonEmpWait); - } - jsonStart.put("lock_type", "1"); - pointTab.update(jsonStart); - - // 更新终点(叠盘架状态) - jsonEnd.put("lock_type", "1"); - pointTab.update(jsonEnd); - - } else { - // 终点在供给线 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - jsonStart.put("lock_type", "1"); - pointTab.update(jsonStart); - } - - taskTab.delete("task_id = '" + task_id + "'"); - } - - if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { - // 更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { - /* - * 更改任务状态为完成 - * 1.终点为叠盘架更新叠盘架数量、起点点位状态、等待位状态,更新任务组状态 - * 2.终点为供给线,更新起点载数量 - */ - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); - jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); - jsonTask.put("update_time", DateUtil.now()); - taskTab.update(jsonTask); - - // 判断终点在哪里 - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - - JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - // 终点在叠盘架 - if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQB.getId())) { - // 更新起点点位状态 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - // 判断起点是不是养生A区空载具 - if (StrUtil.equals(jsonStart.getString("region_id"), RegionTypeEnum.YSAQKTPQ01.getId())) { - // 判断此起点是否是等待点 - if (!StrUtil.equals(jsonStart.getString("col_num"), "9")) { - // 如果不是等待点更新等待点状态 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + - "' and block_num = '" + jsonStart.getString("block_num") + - "' and row_num = '" + jsonStart.getString("row_num") + - "' and col_num = '9'").uniqueResult(0); - - jsonEmpWait.put("lock_type", "1"); - pointTab.update(jsonEmpWait); - } - } - - jsonStart.put("point_status", "1"); - jsonStart.put("lock_type", "1"); - jsonStart.put("vehicle_type", ""); - jsonStart.put("vehicle_code", ""); - jsonStart.put("vehicle_qty", 0); - pointTab.update(jsonStart); - - // 更新终点(叠盘架状态) - jsonEnd.put("vehicle_qty", NumberUtil.add(jsonEnd.getString("vehicle_qty"), jsonTask.getString("vehicle_qty"))); - jsonEnd.put("lock_type", "1"); - jsonEnd.put("point_status", "2"); - jsonEnd.put("vehicle_type", jsonTask.getString("vehicle_type")); - pointTab.update(jsonEnd); - - // 更新任务组状态 - JSONObject jsonTask2 = taskTab.query("task_group_id = '" + jsonTask.getString("task_group_id") + "' and task_id <> '" + jsonTask.getString("task_id") + "'").uniqueResult(0); - jsonTask2.put("point_code1", jsonEnd.getString("point_code")); - jsonTask2.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(jsonTask2); - } else { - // 终点在供给线线: 更新起点(叠盘架)数量 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - jsonStart.put("vehicle_qty", NumberUtil.sub(jsonStart.getString("vehicle_qty"), "1")); - jsonStart.put("lock_type", "1"); - if (StrUtil.equals(jsonStart.getString("vehicle_qty"), "0")) { - jsonStart.put("point_status", "1"); - jsonStart.put("vehicle_type", ""); - } - pointTab.update(jsonStart); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - - JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - // 创建任务 - JSONObject jsonTask = taskArr.getJSONObject(i); - String vehicle_type = jsonTask.getString("vehicle_type"); - - // 找叠盘架是否与对应的载具类型 - JSONObject jsonDpjStart = pointTab.query("region_id = '" + RegionTypeEnum.DPJQB.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty <> '0'").uniqueResult(0); - - if (ObjectUtil.isNotEmpty(jsonDpjStart)) { - // 判断叠盘架是否有任务 有就下一个任务 - boolean is_point = this.isTask(jsonDpjStart.getString("point_code")); - if (!is_point) continue; - - // 更新任务起点 - jsonTask.put("point_code1", jsonDpjStart.getString("point_code")); - jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(jsonTask); - - // 起点上锁 - jsonDpjStart.put("lock_type", 2); - pointTab.update(jsonDpjStart); - - } else { - // 判断叠盘架载具数量是否是0 - JSONObject jsonDpjStart2 = pointTab.query("region_id = '" + RegionTypeEnum.DPJQB.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonDpjStart2)) continue; - - // 判断叠盘架是否有任务 - boolean is_point = this.isTask(jsonDpjStart2.getString("point_code")); - if (!is_point) continue; - - // 找叠盘架暂存位是否有空托盘 - JSONObject map = new JSONObject(); - map.put("flag", "1"); - map.put("vehicle_type", vehicle_type); - - JSONObject jsonZcKtp = WQL.getWO("QSCH_GjxCallEmpVehicleTask").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(jsonZcKtp)) { - // 创建任务:空载具暂存位 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("暂存位->叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonZcKtp.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonZcKtp.getString("vehicle_code")) - .vehicle_type(jsonZcKtp.getString("vehicle_type")) - .vehicle_qty(jsonZcKtp.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁定起点 - jsonZcKtp.put("lock_type", "2"); - pointTab.update(jsonZcKtp); - } else { - // 空托盘暂存区没有就到养生A区找: 先找到出库等待点 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + RegionTypeEnum.YSAQKTPQ01.getId() + - "' and col_num = '9' and can_vehicle_type = '" + vehicle_type + - "' and is_used = '1' and is_delete = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonEmpWait)) continue; - - JSONObject jsonStartPoint = pointTab.query("region_id = '" + jsonEmpWait.getString("region_id") + - "' and block_num = '" + jsonEmpWait.getString("block_num") + - "' and row_num = '" + jsonEmpWait.getString("row_num") + - "' and point_status = '2' and lock_type = '1' order by out_empty_seq DESC").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonStartPoint)) continue; - - // 判断找到的空载具点位是否是等待点 - if (StrUtil.equals(jsonEmpWait.getString("point_code"), jsonStartPoint.getString("point_code"))) { - // 创建 养生A区空载具等待点 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("养生A区-> 叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonStartPoint.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonStartPoint.getString("vehicle_code")) - .vehicle_type(jsonStartPoint.getString("vehicle_type")) - .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁起点 - jsonStartPoint.put("lock_type", "2"); - pointTab.update(jsonStartPoint); - } else { - // 判断等待点是否是 未锁定、为空载具 - if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1")) { - // 创建 养生A区空载具 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("养生A区>叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonStartPoint.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonStartPoint.getString("vehicle_code")) - .vehicle_type(jsonStartPoint.getString("vehicle_type")) - .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁起点 - jsonStartPoint.put("lock_type", "2"); - pointTab.update(jsonStartPoint); - // 锁等待点 - jsonEmpWait.put("lock_type", "2"); - pointTab.update(jsonEmpWait); - } else { - continue; - } - } - } - } - } - - } - - - @Override - @Transactional(rollbackFor = Exception.class) -// 虽然是养生A区,应该有二次申请,但是通过判断叠盘架是否有任务来判断做限制 - public String createTask(JSONObject form) { - /* - * 1.先生成确定终点的任务 - * 2.通过findStartPoint()找起点 - * 3.下发给ACS - */ - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 - - //任务表【SCH_BASE_Task】 - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); - - - - - String point_code2 = form.getString("point_code2"); - String sub_device_code = point_code2.substring(0, point_code2.indexOf("_")); - - String device_code = pointTab.query("point_code = '" + sub_device_code + "'").uniqueResult(0).getString("device_code"); - - JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - - SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("共挤线叫空载具") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .acs_task_type("2") - .vehicle_code(form.getString("vehicle_code")) - .vehicle_type(workOrderObj.getString("vehicle_type")) - .vehicle_qty(form.getIntValue("qty")) - .task_group_id(IdUtil.getLongId()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void forceFinish(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"2"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Override - public void cancel(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"0"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Override - public List addTask() { - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); - - ArrayList resultList = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - - String point_code1 = json.getString("point_code1"); - //判断起点是否属于养生A区 - if (point_code1.startsWith("2")) { - //养生A区发给ACS需要新的点位(2101-03-1----->21011-03-1) - point_code1 = point_code1.substring(0, 4) + "1" + point_code1.substring(4, 9); - } - - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(point_code1) - .next_device_code(json.getString("point_code3")) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - resultList.add(dto); - } - return resultList; - } - - @Transactional(rollbackFor = Exception.class) - public boolean isTask(String point_code) { - /* - * 判断点位是否有任务存在 - */ - WQLObject tab = WQLObject.getWQLObject("SCH_BASE_Task"); - - boolean result; - - JSONObject jsonPointCode1 = tab.query("point_code1 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode2 = tab.query("point_code2 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode3 = tab.query("point_code3 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode4 = tab.query("point_code4 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - - if (ObjectUtil.isEmpty(jsonPointCode1) && ObjectUtil.isEmpty(jsonPointCode2) && ObjectUtil.isEmpty(jsonPointCode3) && ObjectUtil.isEmpty(jsonPointCode4)) { - result = true; - } else { - result = false; - } - - return result; - } - - -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java new file mode 100644 index 0000000..ff6bec8 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java @@ -0,0 +1,261 @@ +package org.nl.wms.sch.tasks.callEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.tasks.RegionTypeEnum; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 混碾呼叫空托盘 + * @Date: 2022/11/9 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class HnCallEmptyVehicleTask extends AbstractAcsTask { + + private final String THIS_CLASS = HnCallEmptyVehicleTask.class.getName(); + + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + if (StrUtil.equals(status, "0")) { + /* + * 取消任务 + */ + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + + String point_code1 = task.getString("point_code1"); + if (ObjectUtil.isEmpty(point_code1)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", task.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + /* + * 更改任务状态为完成 + */ + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + /** + * 点位更新,起点:空位,解锁; + */ + String point_code1 = taskObj.getString("point_code1"); + JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + startPoint.put("point_status", "1"); + startPoint.put("lock_type", "1"); + pointTab.update(startPoint); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + /* + * 1.先生成确定终点的任务 + * 2.通过findStartPoint()找起点 + * 3.下发给ACS + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 + + //任务表【SCH_BASE_Task】 + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); + + + String point_code2 = form.getString("point_code2"); + String sub_device_code = point_code2.substring(0, point_code2.indexOf("_")); + + String device_code = pointTab.query("point_code = '" + sub_device_code + "'").uniqueResult(0).getString("device_code"); + + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("混碾机叫空载具") + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .acs_task_type("2") + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .task_group_id(org.nl.wms.util.IdUtil.getLongId()) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + + JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + // 创建任务 + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "KLHJ"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + // 直接到困料货架找一个空载具 + JSONObject startPoint = WQL.getWO("QSCH_hnCallEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(startPoint)) { + taskObj.put("remark", "困料货架无可用载具!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code1", startPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住起点 + startPoint.put("task_id", taskObj.getString("task_id")); + startPoint.put("lock_type", "2"); + pointTab.update(startPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + /* + * 强制完成 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java deleted file mode 100644 index 97e5e37..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java +++ /dev/null @@ -1,450 +0,0 @@ -package org.nl.wms.sch.tasks.callEmpty; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.nl.modules.common.exception.BadRequestException; -import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.system.util.CodeUtil; -import org.nl.modules.wql.WQL; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.RegionTypeEnum; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -@Service -@RequiredArgsConstructor -@Slf4j -public class YqxCallEmpVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = YqxCallEmpVehicleTask.class.getName(); - - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject taskObj, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String task_id = taskObj.getString("task_id"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - if (StrUtil.equals(status, "0")) { - /* - * 取消删除 - * 1.终点为叠盘架更新起点点位、等待点点位、叠盘架点位 - * 2.终点为油漆线更新叠盘架点位 - */ - if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - - JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - // 终点在叠盘架 - if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQB.getId())) { - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - // 判断此起点是否是等待点 - if (!StrUtil.equals(jsonStart.getString("col_num"), "9")) { - // 如果不是等待点更新等待点状态 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + - "' and block_num = '" + jsonStart.getString("block_num") + - "' and row_num = '" + jsonStart.getString("row_num") + - "' and col_num = '9'").uniqueResult(0); - - jsonEmpWait.put("lock_type", "1"); - pointTab.update(jsonEmpWait); - } - jsonStart.put("lock_type", "1"); - pointTab.update(jsonStart); - - // 更新终点(叠盘架状态) - jsonEnd.put("lock_type", "1"); - pointTab.update(jsonEnd); - - } else { - // 终点在油漆线 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - jsonStart.put("lock_type", "1"); - pointTab.update(jsonStart); - } - - taskTab.delete("task_id = '" + task_id + "'"); - } - - if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { - // 更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { - /* - * 更改任务状态为完成 - * 1.终点为叠盘架更新叠盘架数量、起点点位状态、等待位状态,更新任务组状态 - * 2.终点为油漆线,更新起点载具数量 - */ - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); - jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); - jsonTask.put("update_time", DateUtil.now()); - taskTab.update(jsonTask); - - // 判断终点在哪里 - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - - JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - // 终点在叠盘架 - if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQA.getId())) { - // 更新起点点位状态 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - // 判断起点是不是养生A区空载具 - if (StrUtil.equals(jsonStart.getString("region_id"), RegionTypeEnum.YSAQKTPQ01.getId())) { - // 判断此起点是否是等待点 - if (!StrUtil.equals(jsonStart.getString("col_num"), "9")) { - // 如果不是等待点更新等待点状态 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + - "' and block_num = '" + jsonStart.getString("block_num") + - "' and row_num = '" + jsonStart.getString("row_num") + - "' and col_num = '9'").uniqueResult(0); - - jsonEmpWait.put("lock_type", "1"); - pointTab.update(jsonEmpWait); - } - } - - jsonStart.put("point_status", "1"); - jsonStart.put("lock_type", "1"); - jsonStart.put("vehicle_type", ""); - jsonStart.put("vehicle_code", ""); - jsonStart.put("vehicle_qty", 0); - pointTab.update(jsonStart); - - // 更新终点(叠盘架状态) - jsonEnd.put("vehicle_qty", NumberUtil.add(jsonEnd.getString("vehicle_qty"),jsonTask.getString("vehicle_qty"))); - jsonEnd.put("lock_type", "1"); - jsonEnd.put("point_status", "2"); - jsonEnd.put("vehicle_type", jsonTask.getString("vehicle_type")); - pointTab.update(jsonEnd); - - // 更新任务组状态 - JSONObject jsonTask2 = taskTab.query("task_group_id = '" + jsonTask.getString("task_group_id") + "' and task_id <> '" + jsonTask.getString("task_id") + "'").uniqueResult(0); - // 判断叠盘架数量是否 < 需求数量 (暂时只能<需求数量) - if (jsonEnd.getIntValue("vehicle_qty") < jsonTask2.getIntValue("vehicle_qty")) { - jsonTask2.put("vehicle_qty", jsonEnd.getIntValue("vehicle_qty")); - } - jsonTask2.put("point_code1", jsonEnd.getString("point_code")); - jsonTask2.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(jsonTask2); - } else { - // 终点在油漆线: 更新起点(叠盘架)数量 - JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - jsonStart.put("vehicle_qty",NumberUtil.sub(jsonStart.getString("vehicle_qty"),jsonTask.getString("vehicle_qty"))); - jsonStart.put("lock_type", "1"); - if (StrUtil.equals(jsonStart.getString("vehicle_qty"),"0")) { - jsonStart.put("point_status", "1"); - jsonStart.put("vehicle_type", ""); - } - pointTab.update(jsonStart); - } - } - } - - /** - * 虽然是养生A区,应该有二次申请,但是通过判断叠盘架是否有任务来判断做限制 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - - JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - // 创建任务 - JSONObject jsonTask = taskArr.getJSONObject(i); - String vehicle_type = jsonTask.getString("vehicle_type"); - - // 找叠盘架是否与对应的载具类型 - JSONObject jsonDpjStart = pointTab.query("region_id = '" + RegionTypeEnum.DPJQA.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty <> '0'").uniqueResult(0); - - if (ObjectUtil.isNotEmpty(jsonDpjStart)) { - // 判断叠盘架是否有任务 有就下一个任务 - boolean is_point = this.isTask(jsonDpjStart.getString("point_code")); - if (!is_point) continue; - - // 判断叠盘架数量是否 < 需求数量 (暂时只能<需求数量) - if (jsonDpjStart.getIntValue("vehicle_qty") < jsonTask.getIntValue("vehicle_qty")) { - jsonTask.put("vehicle_qty", jsonDpjStart.getIntValue("vehicle_qty")); - } - - // 起点上锁 - jsonDpjStart.put("lock_type", "2"); - pointTab.update(jsonDpjStart); - - // 更新任务起点 - jsonTask.put("point_code1", jsonDpjStart.getString("point_code")); - jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(jsonTask); - - - } else { - // 判断叠盘架载具数量是否是0 - JSONObject jsonDpjStart2 = pointTab.query("region_id = '" + RegionTypeEnum.DPJQA.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonDpjStart2)) continue; - - // 判断叠盘架是否有任务 - boolean is_point = this.isTask(jsonDpjStart2.getString("point_code")); - if (!is_point) continue; - - // 找叠盘架暂存位是否有空托盘 - JSONObject map = new JSONObject(); - map.put("flag", "1"); - map.put("vehicle_type", vehicle_type); - - JSONObject jsonZcKtp = WQL.getWO("QSCH_YqxCallEmpVehicleTask").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(jsonZcKtp)) { - // 创建任务:空载具暂存位 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("暂存位>叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonZcKtp.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonZcKtp.getString("vehicle_code")) - .vehicle_type(jsonZcKtp.getString("vehicle_type")) - .vehicle_qty(jsonZcKtp.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁定起点 - jsonZcKtp.put("lock_type", "2"); - pointTab.update(jsonZcKtp); - } else { - // 空托盘暂存区没有就到养生A区找: 先找到出库等待点 - JSONObject jsonEmpWait = pointTab.query("region_id = '" + RegionTypeEnum.YSAQKTPQ01.getId() + - "' and col_num = '9' and can_vehicle_type = '" + vehicle_type + - "' and is_used = '1' and is_delete = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonEmpWait)) continue; - - JSONObject jsonStartPoint = pointTab.query("region_id = '" + jsonEmpWait.getString("region_id") + - "' and block_num = '" + jsonEmpWait.getString("block_num") + - "' and row_num = '" + jsonEmpWait.getString("row_num") + - "' and point_status = '2' and lock_type = '1' order by out_empty_seq DESC").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonStartPoint)) continue; - - // 判断找到的空载具点位是否是等待点 - if (StrUtil.equals(jsonEmpWait.getString("point_code"), jsonStartPoint.getString("point_code"))) { - // 创建 养生A区空载具等待点 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("养生A区>叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonStartPoint.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonStartPoint.getString("vehicle_code")) - .vehicle_type(jsonStartPoint.getString("vehicle_type")) - .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁起点 - jsonStartPoint.put("lock_type", "2"); - pointTab.update(jsonStartPoint); - } else { - // 判断等待点是否是 未锁定 - if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1")) { - // 创建 养生A区空载具 --> 叠盘架 - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .acs_task_type("2") - .task_name("养生A区>叠盘架空载具") - .task_status(TaskStatusEnum.START_AND_POINT.getCode()) - .point_code1(jsonStartPoint.getString("point_code")) - .point_code2(jsonDpjStart2.getString("point_code")) - .vehicle_code(jsonStartPoint.getString("vehicle_code")) - .vehicle_type(jsonStartPoint.getString("vehicle_type")) - .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) - .task_group_id(jsonTask.getLong("task_group_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - // 锁起点 - jsonStartPoint.put("lock_type", "2"); - pointTab.update(jsonStartPoint); - // 锁等待点 - jsonEmpWait.put("lock_type", "2"); - pointTab.update(jsonEmpWait); - } else { - continue; - - } - } - } - } - } - - } - - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - /* - * 1.先生成确定终点的任务 - * 2.通过findStartPoint()找起点 - * 3.下发给ACS - */ - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 - - //任务表【SCH_BASE_Task】 - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); - - - - - String point_code2 = form.getString("point_code2"); - String sub_device_code = point_code2.substring(0, point_code2.indexOf("_")); - - String device_code = pointTab.query("point_code = '" + sub_device_code + "'").uniqueResult(0).getString("device_code"); - - JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - - SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("油漆线叫空载具") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .acs_task_type("2") - .vehicle_code(form.getString("vehicle_code")) - .vehicle_type(workOrderObj.getString("vehicle_type")) - .vehicle_qty(form.getIntValue("qty")) - .task_group_id(org.nl.wms.util.IdUtil.getLongId()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void forceFinish(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"2"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - - @Override - public void cancel(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"0"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Override - public List addTask() { - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '"+THIS_CLASS+"' and task_status = '"+TaskStatusEnum.START_AND_POINT.getCode()+"' and is_delete ='0'").getResultJSONArray(0); - - ArrayList resultList = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - String point_code1 = json.getString("point_code1"); - //判断起点是否属于养生A区 - if (point_code1.startsWith("2")) { - //养生A区发给ACS需要新的点位(2101-03-1----->21011-03-1) - point_code1 = point_code1.substring(0, 4) + "1" + point_code1.substring(4, 9); - } - - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(point_code1) - .next_device_code(json.getString("point_code3")) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - resultList.add(dto); - } - return resultList; - } - - @Transactional(rollbackFor = Exception.class) - public boolean isTask(String point_code) { - /* - * 判断点位是否有任务存在 - */ - WQLObject tab = WQLObject.getWQLObject("SCH_BASE_Task"); - - boolean result; - - JSONObject jsonPointCode1 = tab.query("point_code1 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode2 = tab.query("point_code2 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode3 = tab.query("point_code3 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - JSONObject jsonPointCode4 = tab.query("point_code4 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); - - if (ObjectUtil.isEmpty(jsonPointCode1) && ObjectUtil.isEmpty(jsonPointCode2) && ObjectUtil.isEmpty(jsonPointCode3) && ObjectUtil.isEmpty(jsonPointCode4)) { - result = true; - } else { - result = false; - } - - return result; - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java new file mode 100644 index 0000000..4aaa9c3 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java @@ -0,0 +1,310 @@ +package org.nl.wms.sch.tasks.callEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 压制机呼叫空钢托盘 + * @Date: 2022/11/10 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class YzjCallEmptyVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = YzjCallEmptyVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,1:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + + JSONObject requestObj = task.getJSONObject("request_param"); + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + String point_code1 = task.getString("point_code1"); + + if (StrUtil.equals(status, "0")) { + /* + * 取消任务 + */ + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + if (ObjectUtil.isNotEmpty(point_code1)) { + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + + JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + startPoint.put("lock_type", "1"); + pointTab.update(startPoint); + } + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", task.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status,"2")) { + /* + * 更改任务状态为完成 + */ + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + if (point_code1.startsWith("L")) { // 入窑缓存位 + // 插入出库单 + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "2"); // 出库 + regionIoObj.put("region_id", startPoint.getString("region_id")); + regionIoObj.put("region_code", startPoint.getString("region_code")); + regionIoObj.put("region_name", startPoint.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code2")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + // 点位更新,起点:空位,解锁; + startPoint.put("point_status", "1"); + startPoint.put("lock_type", "1"); + startPoint.put("task_id", ""); + startPoint.put("pcsn", ""); + startPoint.put("ivt_qty", "0"); + startPoint.put("material_id", ""); + startPoint.put("instorage_time", ""); + startPoint.put("is_full", "2"); + startPoint.put("standing_time", "0"); + startPoint.put("vehicle_type", ""); + startPoint.put("vehicle_code", ""); + } else { // 钢托盘每次就一个 --- 如果是堆叠位5需要更新设备状态?? + startPoint.put("point_status", "1"); + startPoint.put("lock_type", "1"); + startPoint.put("vehicle_qty", "0"); + } + pointTab.update(startPoint); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + /* + * 1.先生成确定终点的任务 + * 2.通过findStartPoint()找起点 + * 3.下发给ACS + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 + + //任务表【SCH_BASE_Task】 + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); + + + String point_code2 = form.getString("point_code2"); + String sub_device_code = point_code2.substring(0, point_code2.indexOf("_")); + + String device_code = pointTab.query("point_code = '" + sub_device_code + "'").uniqueResult(0).getString("device_code"); + + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("压制机叫空载具") + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .acs_task_type("2") + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .task_group_id(org.nl.wms.util.IdUtil.getLongId()) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + // 找托盘:先找库存上是否有半满托盘,如果没有就到KGTDDW05找空钢托盘 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + // 创建任务 + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + // 寻找入窑暂存区是否有半托 + JSONObject noFull = new JSONObject(); + noFull.put("flag", "1"); + noFull.put("region_code", "RYZCQ"); + noFull.put("material_id", taskObj.getString("material_id")); + JSONObject noFullPoint = WQL.getWO("QSCH_yzjCallEmptyVehicle_01").addParamMap(noFull).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(noFullPoint)) { // 找到半满托盘,叫料出库 + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code1", noFullPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住起点 + noFullPoint.put("task_id", taskObj.getString("task_id")); + noFullPoint.put("lock_type", "2"); + pointTab.update(noFullPoint); + } else { // 到KGTDDW05找空钢托盘 + JSONObject param = new JSONObject(); + param.put("flag", "2"); + param.put("region_code", "KGTCPQ"); + param.put("point_code", "KGTDDW05"); + JSONObject kgtPoint = WQL.getWO("QSCH_yzjCallEmptyVehicle_01").addParamMap(param).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(kgtPoint)) { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code1", kgtPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住起点 + kgtPoint.put("task_id", taskObj.getString("task_id")); + kgtPoint.put("lock_type", "2"); + pointTab.update(kgtPoint); + } else { + taskObj.put("remark", "未找到可用的载具!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql deleted file mode 100644 index b76c2fb..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql +++ /dev/null @@ -1,60 +0,0 @@ -[交易说明] - 交易名: 共挤线申请空盘 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - - IF 输入.flag = "1" - QUERY - SELECT - * - FROM - SCH_BASE_Point - WHERE - is_used = '1' - AND is_delete = '0' - AND lock_type = '1' - AND point_status = '2' - AND region_code = 'KTPHCQB01' - - OPTION 输入.vehicle_type <> "" - can_vehicle_type = 输入.vehicle_type - ENDOPTION - - ENDSELECT - ENDQUERY - ENDIF \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql new file mode 100644 index 0000000..5c66b1f --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql @@ -0,0 +1,88 @@ +[交易说明] + 交易名: 分拣码垛呼叫空载具 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND is_full = '2' + AND point_status = '3' + AND point_type = '1' + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY col_num,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF + IF 输入.flag = "2" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND point_status = '2' + AND point_type = '2' + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + OPTION 输入.vehicle_type <> "" + p.vehicle_type = 输入.vehicle_type + ENDOPTION + ORDER BY col_num,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql new file mode 100644 index 0000000..2dcd046 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql @@ -0,0 +1,65 @@ +[交易说明] + 交易名: 混碾机呼叫空载具 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## +IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND point_status = '2' + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY col_num,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql new file mode 100644 index 0000000..c92d852 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql @@ -0,0 +1,85 @@ +[交易说明] + 交易名:压制机呼叫空钢托盘 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.point_code TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_full = '2' + AND is_delete = '0' + AND point_status = '2' + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ENDSELECT + ENDQUERY + ENDIF + IF 输入.flag = "2" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND point_status = '2' + AND vehicle_qty > '0' + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + OPTION 输入.point_code <> "" + p.point_code = 输入.point_code + ENDOPTION + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java new file mode 100644 index 0000000..c091d03 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java @@ -0,0 +1,271 @@ +package org.nl.wms.sch.tasks.callMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 分拣叫料出库 + * @Date: 2022/11/11 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class FjCallMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = FjCallMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + // 物料点 + JSONObject material_point = pointTab.query("point_code = '" + taskObj.getString("point_code1") + "'").uniqueResult(0); + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + + if (ObjectUtil.isNotEmpty(material_point)) { + // 点位解锁 + material_point.put("lock_type", "1"); + pointTab.update(material_point); + } + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + JSONObject requestObj = task.getJSONObject("request_param"); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "2"); // 出库 + regionIoObj.put("region_id", material_point.getString("region_id")); + regionIoObj.put("region_code", material_point.getString("region_code")); + regionIoObj.put("region_name", material_point.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code2")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + //完成后 + // 物料点位解锁 并设置空位 + material_point.put("lock_type", "1"); + material_point.put("point_status", "1"); + material_point.put("task_id", ""); + material_point.put("pcsn", ""); + material_point.put("ivt_qty", "0"); + material_point.put("material_id", ""); + material_point.put("instorage_time", ""); + material_point.put("is_full", "2"); + material_point.put("standing_time", "0"); + material_point.put("vehicle_type", ""); + material_point.put("vehicle_code", ""); + pointTab.update(material_point); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + String point_code2 = form.getString("point_code2"); + String vehicle_type = form.getString("vehicle_type"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("material_num"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code2 + "存在未完成的任务"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + String device_code = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("分拣出库") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .vehicle_code(vehicle_code) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .vehicle_type(vehicle_type) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + // 到出窑缓存区找一托物料 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String material_id = taskObj.getString("material_id"); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject queryParam = new JSONObject(); + queryParam.put("flag", "1"); + queryParam.put("material_id", material_id); + queryParam.put("region_code", "CYZCQ"); + queryParam.put("vehicle_type", "%" + vehicle_type + "%"); + // 到出窑暂存区找 + JSONObject json1 = WQL.getWO("QSCH_cyCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(json1)) { + // 拿到点位 + JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); + if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); + // 物料点位上锁 + material_point.put("lock_type", "2"); + pointTab.update(material_point); + + taskObj.put("point_code1", material_point.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskObj.put("acs_task_type", "2"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("remark", "出窑暂存区无所需物料"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } + + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/SzCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/SzCallMaterialTask.java new file mode 100644 index 0000000..5ca6a3a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/SzCallMaterialTask.java @@ -0,0 +1,283 @@ +package org.nl.wms.sch.tasks.callMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 烧制工序叫料 - 入窑位 + * @Date: 2022/11/10 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class SzCallMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = SzCallMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + // 物料点 + JSONObject material_point = pointTab.query("point_code = '" + taskObj.getString("point_code1") + "'").uniqueResult(0); + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + + if (ObjectUtil.isNotEmpty(material_point)) { + // 点位解锁 + material_point.put("lock_type", "1"); + pointTab.update(material_point); + } + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + JSONObject requestObj = task.getJSONObject("request_param"); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "2"); // 出库 + regionIoObj.put("region_id", material_point.getString("region_id")); + regionIoObj.put("region_code", material_point.getString("region_code")); + regionIoObj.put("region_name", material_point.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code2")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + //完成后 + // 物料点位解锁 并设置空位 + material_point.put("lock_type", "1"); + material_point.put("point_status", "1"); + material_point.put("task_id", ""); + material_point.put("pcsn", ""); + material_point.put("ivt_qty", "0"); + material_point.put("material_id", ""); + material_point.put("instorage_time", ""); + material_point.put("is_full", "2"); + material_point.put("standing_time", "0"); + material_point.put("vehicle_type", ""); + material_point.put("vehicle_code", ""); + pointTab.update(material_point); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + String point_code2 = form.getString("point_code2"); + String vehicle_type = form.getString("vehicle_type"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("material_num"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code2 + "存在未完成的任务"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + String device_code = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("烧制出库") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .vehicle_code(vehicle_code) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .vehicle_type(vehicle_type) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + // 到入窑缓存区找一托物料 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String material_id = taskObj.getString("material_id"); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject queryParam = new JSONObject(); + queryParam.put("flag", "1"); + queryParam.put("material_id", material_id); + queryParam.put("region_code", "RYZCQ"); + queryParam.put("vehicle_type", "%" + vehicle_type + "%"); + // 到入窑暂存区找,优先找满拖的 + JSONObject json1 = WQL.getWO("QSCH_szCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(json1)) { + // 拿到点位 + JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); + if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); + // 物料点位上锁 + material_point.put("lock_type", "2"); + pointTab.update(material_point); + + taskObj.put("point_code1", material_point.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskObj.put("acs_task_type", "2"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("remark", "入窑暂存区无所需物料"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } + + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YqxCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java similarity index 81% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YqxCallMaterialTask.java rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java index 7c31707..a939bce 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YqxCallMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java @@ -19,24 +19,60 @@ import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.tasks.AcsTaskDto; import org.nl.wms.util.IdUtil; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; - /** - *油漆线叫料 + * @author: lyd + * @description: 压制机叫料工序 + * @Date: 2022/11/10 */ @Service @RequiredArgsConstructor @Slf4j -public class YqxCallMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = YqxCallMaterialTask.class.getName(); - - +public class YzjCallMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = YzjCallMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ @Override - @Transactional(rollbackFor = Exception.class) public void updateTaskStatus(JSONObject task, String status) { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); @@ -82,13 +118,13 @@ public class YqxCallMaterialTask extends AbstractAcsTask { regionIoObj.put("iostorinv_id", IdUtil.getLongId()); regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); regionIoObj.put("buss_date", DateUtil.today()); - regionIoObj.put("io_type", "2"); + regionIoObj.put("io_type", "2"); // 出库 regionIoObj.put("region_id", material_point.getString("region_id")); regionIoObj.put("region_code", material_point.getString("region_code")); regionIoObj.put("region_name", material_point.getString("region_name")); regionIoObj.put("material_id", taskObj.getString("material_id")); regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); - regionIoObj.put("qty", requestObj.getString("material_num")); + regionIoObj.put("qty", requestObj.getString("qty")); regionIoObj.put("bill_status", "3"); regionIoObj.put("start_point_code", taskObj.getString("point_code1")); regionIoObj.put("end_point_code", taskObj.getString("point_code2")); @@ -104,91 +140,28 @@ public class YqxCallMaterialTask extends AbstractAcsTask { material_point.put("lock_type", "1"); material_point.put("point_status", "1"); material_point.put("task_id", ""); + material_point.put("pcsn", ""); + material_point.put("ivt_qty", "0"); material_point.put("material_id", ""); + material_point.put("instorage_time", ""); + material_point.put("is_full", "2"); + material_point.put("standing_time", "0"); material_point.put("vehicle_type", ""); material_point.put("vehicle_code", ""); pointTab.update(material_point); } - } + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ @Override - public void findStartPoint() { - /* - * 根据业务找对应的起点 - */ - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - String material_id = taskObj.getString("material_id"); - String vehicle_type = taskObj.getString("vehicle_type"); - JSONObject queryParam = new JSONObject(); - queryParam.put("flag", "1"); - queryParam.put("material_id", material_id); - queryParam.put("region_code", "YSQA01"); - queryParam.put("vehicle_type", "%" + vehicle_type + "%"); - //1、根据物料id查找养生A区物料点 - JSONObject json1 = WQL.getWO("QSCH_yqxCallMAterial_01").addParamMap(queryParam).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(json1)) { - // 拿到点位 - JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); - // 物料点位上锁 - material_point.put("lock_type", "2"); - pointTab.update(material_point); - - taskObj.put("point_code1", material_point.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("acs_task_type", "2"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("remark", "养生A区无所需物料"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - - } - } - - @Override - public List addTask() { - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); - - ArrayList acsTaskArr = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - //养生A区发给ACS需要新的点位(2101-03-1----->21011-03-1) - String point_code =json.getString("point_code1"); - String newPoint = point_code.substring(0, 4) + "1" + point_code.substring(4, 9); - - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(newPoint) - .next_device_code(json.getString("point_code3")) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - acsTaskArr.add(dto); - } - return acsTaskArr; - } - - @Override - public String createTask(JSONObject whereJson) { - String point_code2 = whereJson.getString("point_code2"); - String vehicle_type = whereJson.getString("vehicle_type"); - String vehicle_code = whereJson.getString("vehicle_code"); - String qty = whereJson.getString("material_num"); + public String createTask(JSONObject form) { + String point_code2 = form.getString("point_code2"); + String vehicle_type = form.getString("vehicle_type"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("material_num"); //生产工单表【PDM_BD_WorkOrder】 WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); @@ -207,7 +180,7 @@ public class YqxCallMaterialTask extends AbstractAcsTask { .task_id(IdUtil.getLongId()) .task_code(CodeUtil.getNewCode("TASK_CODE")) .task_type("task_type") - .task_name("油漆线叫料") + .task_name("压制机叫料") .material_qty(qty) .task_status(TaskStatusEnum.SURE_END.getCode()) .point_code2(point_code2) @@ -217,7 +190,7 @@ public class YqxCallMaterialTask extends AbstractAcsTask { .vehicle_type(vehicle_type) .handle_class(THIS_CLASS) .create_time(DateUtil.now()) - .request_param(whereJson.toJSONString()) + .request_param(form.toJSONString()) .build(); JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); taskTab.insert(json); @@ -227,6 +200,60 @@ public class YqxCallMaterialTask extends AbstractAcsTask { return String.valueOf(dto.getTask_id()); } + /** + * @returninvoke + * @discription 确定任务起点 + * @author ldjun + * @created 2020年6月12日 下午6:01:30 + */ + @Override + public void findStartPoint() { + /* + * 根据业务找对应的起点,直接到困料货架获取 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String material_id = taskObj.getString("material_id"); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject queryParam = new JSONObject(); + queryParam.put("flag", "1"); + queryParam.put("material_id", material_id); + queryParam.put("region_code", "KLHJ"); + queryParam.put("vehicle_type", "%" + vehicle_type + "%"); + //1、 + JSONObject json1 = WQL.getWO("QSCH_yzjCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(json1)) { + // 拿到点位 + JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); + if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); + // 物料点位上锁 + material_point.put("lock_type", "2"); + pointTab.update(material_point); + + taskObj.put("point_code1", material_point.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskObj.put("acs_task_type", "2"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("remark", "困料货架无所需物料"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } + + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ @Override public void forceFinish(String task_id) { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); @@ -238,7 +265,11 @@ public class YqxCallMaterialTask extends AbstractAcsTask { } } - + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ @Override public void cancel(String task_id) { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); @@ -246,7 +277,7 @@ public class YqxCallMaterialTask extends AbstractAcsTask { if (ObjectUtil.isNotEmpty(taskObj)) this.updateTaskStatus(taskObj,"0"); else { - throw new BadRequestException("任务已完成不能取消!"); + throw new BadRequestException("未找到该任务或者任务已完成!"); } } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yqxCallMAterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql similarity index 94% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yqxCallMAterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql index 915bfd8..3ea0e4d 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yqxCallMAterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 共挤线满料请求 + 交易名: 分拣叫料 所属模块: 功能简述: 版权所有: @@ -55,6 +55,7 @@ p.is_used = '1' AND is_delete = '0' AND lock_type='1' + AND point_status = '3' OPTION 输入.material_id <> "" p.material_id = 输入.material_id ENDOPTION @@ -64,7 +65,7 @@ OPTION 输入.vehicle_type <> "" p.can_vehicle_type like 输入.vehicle_type ENDOPTION - ORDER BY block_num,col_num desc,row_num + ORDER BY col_num,row_num,layer_num ENDSELECT ENDQUERY ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_gjxSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_szCallMaterial_01.wql similarity index 54% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_gjxSendMaterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_szCallMaterial_01.wql index 29b1351..b4bbdc9 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_gjxSendMaterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_szCallMaterial_01.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 共挤线满料请求 + 交易名: 烧制叫料 所属模块: 功能简述: 版权所有: @@ -40,25 +40,23 @@ ########################################## # 3、业务主过程 # ########################################## - - IF 输入.flag = "1" - QUERY - SELECT - p.point_id, - p.point_code, - p.point_name, - p.block_num, - p.col_num, - p.row_num + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name, + p.block_num, + p.col_num, + p.row_num FROM - SCH_BASE_Point p - where - p.is_used = '1' + SCH_BASE_Point p + WHERE + p.is_used = '1' AND is_delete = '0' - AND lock_type = '1' + AND lock_type='1' AND point_status = '3' - and col_num>1 - OPTION 输入.material_id <> "" + OPTION 输入.material_id <> "" p.material_id = 输入.material_id ENDOPTION OPTION 输入.region_code <> "" @@ -67,34 +65,7 @@ OPTION 输入.vehicle_type <> "" p.can_vehicle_type like 输入.vehicle_type ENDOPTION - ORDER BY block_num,row_num,col_num - ENDSELECT - ENDQUERY + ORDER BY is_full desc,col_num,row_num,layer_num + ENDSELECT + ENDQUERY ENDIF - - IF 输入.flag = "2" - QUERY - SELECT - block_num, - row_num, - COUNT(*) AS sum - FROM - SCH_BASE_Point p - WHERE - p.is_delete = '0' - AND is_used = '1' - AND region_code = 'YSQA01' - AND point_status = '1' - AND lock_type = '1' - OPTION 输入.vehicle_type <> "" - p.can_vehicle_type like 输入.vehicle_type - ENDOPTION - GROUP BY block_num,row_num - HAVING sum = 9 - ORDER BY block_num,row_num - ENDSELECT - ENDQUERY - ENDIF - - - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql new file mode 100644 index 0000000..685eb23 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql @@ -0,0 +1,71 @@ +[交易说明] + 交易名: 压制机叫料 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name, + p.block_num, + p.col_num, + p.row_num + FROM + SCH_BASE_Point p + WHERE + p.is_used = '1' + AND is_delete = '0' + AND lock_type='1' + AND point_status = '3' + OPTION 输入.material_id <> "" + p.material_id = 输入.material_id + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + ORDER BY col_num desc,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java new file mode 100644 index 0000000..c8b57e5 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java @@ -0,0 +1,203 @@ +package org.nl.wms.sch.tasks.sendEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author: lyd + * @description: 叠盘送空载具 + * @Date: 2022/11/15 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class DpSendEmpVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = DpSendEmpVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + return null; + } + + /** + * @param taskObj 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = taskObj.getString("task_id"); + String point_code1 = taskObj.getString("point_code1"); + String point_code2 = taskObj.getString("point_code2"); + JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + // 解锁终点位置 + if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 + JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point2.put("lock_type", "1"); + pointTab.update(point2); + } + // 任务设置为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("remark", "已取消"); + taskTab.update(jsonTask); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + jsonTask.put("update_time", DateUtil.now()); + jsonTask.put("car_no", taskObj.getString("car_no")); + taskTab.update(jsonTask); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); + jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); + jsonTask.put("update_time", DateUtil.now()); + taskTab.update(jsonTask); + // 释放点位 + if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 + JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point_2.put("lock_type", "1"); + point_2.put("point_status", "2"); + point_2.put("vehicle_code", jsonTask.getString("vehicle_code")); + point_2.put("vehicle_qty", NumberUtil.add(point_2.getString("vehicle_qty"), jsonTask.getString("vehicle_qty"))); + point_2.put("instorage_time", DateUtil.now()); + point_2.put("is_full", "1"); + point_2.put("ivt_qty", "0"); + point_2.put("pcsn", ""); + point_2.put("material_id", ""); + point_2.put("standing_time", "0"); + pointTab.update(point_2); + // 起点设置为空位 + JSONObject point_1 = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + point_1.put("point_status", "1"); + point_1.put("point_status", "1"); + point_1.put("point_status", "1"); + pointTab.update(point_1); + } + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + // 送到KGTDDW01 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + + String point_code1 = form.getString("point_code1"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("叠盘空钢托盘入库") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(form.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + // 直接找 + JSONObject endPoint = pointTab.query("point_code = 'KGTDDW01' AND lock_type = '1' AND is_used='1'").uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "钢托盘堆叠位不可用!"); + taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java new file mode 100644 index 0000000..e09e1ea --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java @@ -0,0 +1,197 @@ +package org.nl.wms.sch.tasks.sendEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author: lyd + * @description: 分拣送空钢托盘 + * @Date: 2022/11/11 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class FjSendEmpVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = FjSendEmpVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + return null; + } + + /** + * @param taskObj 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = taskObj.getString("task_id"); + String point_code2 = taskObj.getString("point_code2"); + JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + // 解锁终点位置 + if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 + JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point2.put("lock_type", "1"); + pointTab.update(point2); + } + // 任务设置为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("remark", "已取消"); + taskTab.update(jsonTask); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + jsonTask.put("update_time", DateUtil.now()); + jsonTask.put("car_no", taskObj.getString("car_no")); + taskTab.update(jsonTask); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); + jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); + jsonTask.put("update_time", DateUtil.now()); + taskTab.update(jsonTask); + // 释放点位 + if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 + JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point_2.put("lock_type", "1"); + point_2.put("point_status", "2"); + point_2.put("vehicle_code", jsonTask.getString("vehicle_code")); + point_2.put("vehicle_qty", NumberUtil.add(point_2.getString("vehicle_qty"), jsonTask.getString("vehicle_qty"))); + point_2.put("instorage_time", DateUtil.now()); + point_2.put("is_full", "1"); + point_2.put("ivt_qty", "0"); + point_2.put("pcsn", ""); + point_2.put("material_id", ""); + point_2.put("standing_time", "0"); + pointTab.update(point_2); + } + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + // 送到叠盘区:KGTDTW01 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + + String point_code1 = form.getString("point_code1"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("分拣空钢托盘入库") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(form.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + // 直接找 + JSONObject endPoint = pointTab.query("point_code = 'KGTDTW01' AND lock_type = '1' AND is_used='1'").uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "钢托盘叠托位不可用!"); + taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/HnSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/HnSendEmpVehicleTask.java new file mode 100644 index 0000000..cbe5126 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/HnSendEmpVehicleTask.java @@ -0,0 +1,196 @@ +package org.nl.wms.sch.tasks.sendEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author: lyd + * @description: 混碾送空盅 + * @Date: 2022/11/15 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class HnSendEmpVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = HnSendEmpVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + return null; + } + + /** + * @param taskObj 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = taskObj.getString("task_id"); + String point_code2 = taskObj.getString("point_code2"); + JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + // 解锁终点位置 + if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 + JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point2.put("lock_type", "1"); + pointTab.update(point2); + } + // 任务设置为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("remark", "已取消"); + taskTab.update(jsonTask); + } + + if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { + // 更新任务状态为执行中 + jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + jsonTask.put("update_time", DateUtil.now()); + jsonTask.put("car_no", taskObj.getString("car_no")); + taskTab.update(jsonTask); + } + + if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { + // 更改任务状态为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); + jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); + jsonTask.put("update_time", DateUtil.now()); + taskTab.update(jsonTask); + // 释放点位 + if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 + JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point_2.put("lock_type", "1"); + point_2.put("point_status", "2"); + point_2.put("vehicle_code", jsonTask.getString("vehicle_code")); + point_2.put("vehicle_qty", "1"); // 混碾送的空盅一个放一个位置,所以只设一个 + point_2.put("instorage_time", DateUtil.now()); + point_2.put("is_full", "1"); + point_2.put("ivt_qty", "0"); + point_2.put("pcsn", ""); + point_2.put("material_id", ""); + point_2.put("standing_time", "0"); + pointTab.update(point_2); + } + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + // 送到困料货架,盅 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + + String point_code1 = form.getString("point_code1"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("分拣空钢托盘入库") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(form.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + // 找困料货架 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + // 直接找 + JSONObject endPoint = pointTab.query("region_code = 'KLHJ' AND lock_type = '1' AND is_used='1' AND point_type = '1'").uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "困料货架无可用货位!"); + taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java new file mode 100644 index 0000000..663b92e --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java @@ -0,0 +1,231 @@ +package org.nl.wms.sch.tasks.sendEmpty; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.tasks.RegionTypeEnum; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 压制机送空托盘入库 + * @Date: 2022/11/10 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class YzjSendEmpVehicleTask extends AbstractAcsTask { + private final String THIS_CLASS = YzjSendEmpVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param taskObj 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = taskObj.getString("task_id"); + String point_code2 = taskObj.getString("point_code2"); + JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + // 解锁终点位置 + if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 + JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point2.put("lock_type", "1"); + pointTab.update(point2); + } + // 任务设置为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("remark", "已取消"); + taskTab.update(jsonTask); + } + + if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { + // 更新任务状态为执行中 + jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + jsonTask.put("update_time", DateUtil.now()); + jsonTask.put("car_no", taskObj.getString("car_no")); + taskTab.update(jsonTask); + } + + if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { + // 更改任务状态为完成 + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); + jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); + jsonTask.put("update_time", DateUtil.now()); + taskTab.update(jsonTask); + // 释放点位 + if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 + JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + point_2.put("lock_type", "1"); + point_2.put("point_status", "2"); + point_2.put("vehicle_code", jsonTask.getString("vehicle_code")); + point_2.put("vehicle_qty", "1"); + point_2.put("instorage_time", DateUtil.now()); + point_2.put("is_full", "1"); + point_2.put("ivt_qty", "0"); + point_2.put("pcsn", ""); + point_2.put("material_id", ""); + point_2.put("standing_time", "0"); + pointTab.update(point_2); + } + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + /* + * 1.先生成确定起点的任务 + * 2.通过findNextPoint()找终点 + * 3.下发给ACS + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + + String point_code1 = form.getString("point_code1"); + + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_name("压制机空盘入库") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(form.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + /* + * 根据业务找对应的终点 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "KLHJ"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + //1、查找困料货架是否有空位,将空桶送过去,由于一个货架只放一个,不需要判定,有空位即可放 + JSONObject endPoint = WQL.getWO("QSCH_hnSendEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "困料货架无可用货位!"); + taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_hnSendEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_hnSendEmptyVehicle_01.wql new file mode 100644 index 0000000..92cd9e6 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_hnSendEmptyVehicle_01.wql @@ -0,0 +1,71 @@ +[交易说明] + 交易名: 压制机送空盘 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name, + p.block_num, + p.col_num, + p.row_num + FROM + SCH_BASE_Point p + WHERE + p.is_used = '1' + AND is_delete = '0' + AND lock_type='1' + AND point_status = '1' + OPTION 输入.material_id <> "" + p.material_id = 输入.material_id + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + ORDER BY col_num desc,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java new file mode 100644 index 0000000..7c88607 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java @@ -0,0 +1,281 @@ +package org.nl.wms.sch.tasks.sendMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.tasks.sendEmpty.FjSendEmpVehicleTask; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author: lyd + * @description: 分拣送料入库 + * @Date: 2022/11/14 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class FjSendMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = FjSendEmpVehicleTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + return null; + } + + /** + * @param taskObj 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + String point_code2 = taskObj.getString("point_code2"); + if (ObjectUtil.isEmpty(point_code2)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + String point_code2 = taskObj.getString("point_code2"); + JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + JSONObject requestObj = task.getJSONObject("request_param"); + //工单标识 + String workorder_id = requestObj.getString("material_info_id"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); + + if (!point_code2.equals("BZX01")) { // 半满到包装暂存区,记录库存 + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "1"); + regionIoObj.put("region_id", point2Obj.getString("region_id")); + regionIoObj.put("region_code", point2Obj.getString("region_code")); + regionIoObj.put("region_name", point2Obj.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code3")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + //完成后入库 + point2Obj.put("instorage_time", DateUtil.now()); + point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + point2Obj.put("ivt_qty", requestObj.getString("qty")); + point2Obj.put("standing_time", workorderObj.getString("standing_time")); + point2Obj.put("material_id", workorderObj.getString("material_id")); + point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); + point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); + point2Obj.put("is_full", requestObj.getString("is_full")); + point2Obj.put("point_status", "3"); + } + // 终点解锁 + point2Obj.put("lock_type", "1"); + pointTab.update(point2Obj); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + String point_code1 = form.getString("point_code1"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("qty"); + String is_full = form.getString("is_full"); + String weight = form.getString("weight"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + // 混碾机设备编码 + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("分拣入库") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + // 判断是否满拖:半满->包装暂存区,满->包装线 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + JSONObject requestObj = taskObj.getJSONObject("request_param"); + if (requestObj.getString("is_full").equals("1")) { + JSONObject endPoint = pointTab.query("point_code = 'BZX01' AND lock_type = '1'").uniqueResult(0); + // 满拖就到包装线 + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } else { + // 半满拖就去包装暂存区 + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "BZZCQ"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + //1、查找困料货架是否有响应的载具类型和对应的物料 + JSONObject endPoint = WQL.getWO("QSCH_fjCallEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "包装暂存区无可用货位!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java deleted file mode 100644 index 176be07..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java +++ /dev/null @@ -1,379 +0,0 @@ -package org.nl.wms.sch.tasks.sendMaterial; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.nl.modules.common.exception.BadRequestException; -import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.system.util.CodeUtil; -import org.nl.modules.wql.WQL; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.util.IdUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - - -/** - * 共挤线送料任务服务 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class GjxSendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = GjxSendMaterialTask.class.getName(); - - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject task, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - //任务取消 - if (StrUtil.equals(status, "0")) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - - //释放相关电位信息 - JSONObject param1 = new JSONObject(); - param1.put("lock_type", "1"); - param1.put("task_id", ""); - param1.put("material_id", ""); - pointTab.update(param1, "task_id = '" + taskObj.getString("task_id") + "'"); - } - - if ("1".equals(status)) { - // 更新任务状态为执行中 - taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("car_no", taskObj.getString("car_no")); - taskTab.update(taskObj); - } - - if (StrUtil.equals(status, "2")) { - - //判断状态, - if (StrUtil.equals("2", taskObj.getString("task_status"))) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - return; - } - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - - String point_code2 = taskObj.getString("point_code2"); - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - JSONObject requestObj = task.getJSONObject("request_param"); - //工单标识 - String workorder_id = requestObj.getString("material_info_id"); - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); - - - //区域出入表【st_ivt_regionIO】 - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - JSONObject regionIoObj = new JSONObject(); - regionIoObj.put("iostorinv_id", IdUtil.getLongId()); - regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); - regionIoObj.put("buss_date", DateUtil.today()); - regionIoObj.put("io_type", "1"); - regionIoObj.put("region_id", endPoint.getString("region_id")); - regionIoObj.put("region_code", endPoint.getString("region_code")); - regionIoObj.put("region_name", endPoint.getString("region_name")); - regionIoObj.put("material_id", taskObj.getString("material_id")); - regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); - regionIoObj.put("qty", requestObj.getString("qty")); - regionIoObj.put("bill_status", "3"); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", "2"); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); - regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - - //完成后入库 - // 点位解锁 - endPoint.put("lock_type", "1"); - endPoint.put("point_status", "3"); - endPoint.put("material_id", taskObj.getString("material_id")); - endPoint.put("instorage_time", DateUtil.now()); - endPoint.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - endPoint.put("ivt_qty", requestObj.getString("qty")); - endPoint.put("standing_time", workorderObj.getString("standing_time")); - endPoint.put("vehicle_code", taskObj.getString("vehicle_code")); - endPoint.put("vehicle_type", taskObj.getString("vehicle_type")); - pointTab.update(endPoint); - //释放整列货位 - JSONObject param = new JSONObject(); - param.put("lock_type", "1"); - pointTab.update(param, "task_id = '" + task_id + "'"); - - } - - } - - @Override - public void findNextPoint() { - //判断共挤线是否有执行中的任务,如果任务数>=3,则不生成任务 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - /* - * 根据业务找对应的终点 - */ - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - String material_id = taskObj.getString("material_id"); - String vehicle_type = taskObj.getString("vehicle_type"); - JSONObject param1 = new JSONObject(); - param1.put("flag", "1"); - param1.put("material_id", material_id); - param1.put("region_code", "YSQA01"); - param1.put("vehicle_type", "%" + vehicle_type + "%"); - //1、查找库区类是否有响应的载具类型和对应的物料 - JSONObject json1 = WQL.getWO("QSCH_gjxSendMaterial_01").addParamMap(param1).process().uniqueResult(0); - - - //判断是否有到同一列的相同物料SKU的AGV任务,如果有,则等待 - JSONArray taskIngs = taskTab.query("is_delete='0' and material_id = '" + material_id + "' and (task_status = '4' or task_status = '5' or task_status = '6' )").getResultJSONArray(0); - - if (ObjectUtil.isNotEmpty(taskIngs)) { - JSONObject taskIng = taskIngs.getJSONObject(0); - if (ObjectUtil.isNotEmpty(taskIng) && ObjectUtil.isNotEmpty(json1)) { - JSONObject point2 = pointTab.query("point_code = '" + taskIng.getString("point_code2") + "'").uniqueResult(0); - if (StrUtil.equals(point2.getString("block_num"), json1.getString("block_num")) - && StrUtil.equals(point2.getString("row_num"), json1.getString("row_num"))) { - taskObj.put("remark", "相应列有AGV在工作,等待执行!"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - } - } - - - if (ObjectUtil.isNotEmpty(json1)) { - Integer block_num = json1.getInteger("block_num"); - Integer col_num = json1.getInteger("col_num"); - Integer row_num = json1.getInteger("row_num"); - - JSONObject firstRow = pointTab.query("block_num = '" + block_num + "' and row_num = '" + row_num + "' and col_num ='" + (col_num - 1) + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(firstRow)) throw new BadRequestException("数据错误,请校验!"); - taskObj.put("point_code2", firstRow.getString("point_code")); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - //二楼普通任务 - taskTab.update(taskObj); - //锁住相关货位 - JSONObject point = new JSONObject(); - point.put("lock_type", "2"); - point.put("task_id", taskObj.getString("task_id")); - pointTab.update(point, "block_num = '" + block_num + "' and row_num = '" + row_num + "' and col_num <= '" + (col_num - 1) + "'"); - - } else {//找空位入 - if (ObjectUtil.isNotEmpty(taskIngs) && taskIngs.size() > 1) { - taskObj.put("remark", "相应列有AGV在工作,等待执行!"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - continue; - } - - JSONObject param2 = new JSONObject(); - param2.put("flag", "2"); - param2.put("region_code", "YSQA01"); - param2.put("vehicle_type", "%" + vehicle_type + "%"); - //1、查找整列为空的货位 - JSONObject json2 = WQL.getWO("QSCH_gjxSendMaterial_01").addParamMap(param2).process().uniqueResult(0); - if (ObjectUtil.isEmpty(json2)) { - taskObj.put("remark", "养生A区无可用货位"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - Integer block_num = json2.getInteger("block_num"); - Integer row_num = json2.getInteger("row_num"); - JSONObject firstRow = pointTab.query("block_num = '" + block_num + "' and row_num = '" + row_num + "' and col_num ='9'").uniqueResult(0); - taskObj.put("point_code2", firstRow.getString("point_code")); - //二楼普通任务 - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - //锁住相关货位 - JSONObject point = new JSONObject(); - point.put("lock_type", "2"); - point.put("task_id", taskObj.getString("task_id")); - pointTab.update(point, "block_num = '" + block_num + "' and row_num = '" + row_num + "' and col_num <= '" + 9 + "'"); - - } - } - - } - } - - @Override - public List addTask() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = taskTab.query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); - - ArrayList acsTaskArr = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - - //养生A区发给ACS需要新的点位(2101-03-1----->21011-03-1) - String point_code = json.getString("point_code2"); - String newPoint = point_code.substring(0, 4) + "1" + point_code.substring(4, 9); - - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(json.getString("point_code1")) - .next_device_code(newPoint) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - acsTaskArr.add(dto); - } - return acsTaskArr; - } - - @Override - public String createTask(JSONObject whereJson) { - String point_code1 = whereJson.getString("point_code1"); - String vehicle_type = whereJson.getString("vehicle_type"); - String vehicle_code = whereJson.getString("vehicle_code"); - String qty = whereJson.getString("qty"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); - - - JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("共挤线满料") - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .acs_task_type("2")//2楼AGV普通任务 - .vehicle_code(vehicle_code) - .material_qty(qty) - .material_info_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .vehicle_type(vehicle_type) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(whereJson.toJSONString()) - .build(); - - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - @Override - public void forceFinish(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status < " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) { - this.updateTaskStatus(taskObj, "2"); - } else { - throw new BadRequestException("任务已删除或者已完成!"); - } - - } - - - @Override - public void cancel(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) { - this.updateTaskStatus(taskObj, "0"); - } else { - throw new BadRequestException("任务已完成不能取消!"); - } - } - - //TODO 暂时不用二次申请 - @Transactional(rollbackFor = Exception.class) - @Override - public String againApply(String task_id) { - /* - * 再次下发任务处理方法 - * 涉及业务:入空载具、出空载具、入物料、出物料 - */ - - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); // 点位表 - - JSONObject taskObj = taskTab.query("task_id ='" + task_id + "'").uniqueResult(0); - - JSONObject jsonPoint3 = pointTab.query("point_code = '" + taskObj.getString("point_code3") + "'").uniqueResult(0); - //提前更新这列货位状态,方便生成往这列的任务 - jsonPoint3.put("point_status", "3"); - jsonPoint3.put("material_id", taskObj.getString("material_id")); - pointTab.update(jsonPoint3); - //释放相关货位 - JSONObject point = new JSONObject(); - point.put("lock_type", "1"); - point.put("task_id", ""); - pointTab.update(point, "task_id = '" + taskObj.getString("task_id") + "'"); - - - //养生A区发给ACS需要新的点位(2101-03-1----->21011-03-1) - String point_code = taskObj.getString("point_code3"); - String newPoint = point_code.substring(0, 4) + "1" + point_code.substring(4, 9); - return newPoint; - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java similarity index 80% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java index 5419c5f..a9e3180 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java @@ -19,25 +19,61 @@ import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.tasks.AcsTaskDto; import org.nl.wms.util.IdUtil; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; - /** - * 豪凯自动线线送料任务服务 + * @author: lyd + * @description: 混碾机送料 + * @Date: 2022/11/9 */ @Service @RequiredArgsConstructor @Slf4j -public class HkxSendMaterialTask extends AbstractAcsTask { - - private final String THIS_CLASS = HkxSendMaterialTask.class.getName(); - +public class HnSendMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = HnSendMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ @Override - @Transactional(rollbackFor = Exception.class) public void updateTaskStatus(JSONObject task, String status) { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); @@ -73,6 +109,8 @@ public class HkxSendMaterialTask extends AbstractAcsTask { if (StrUtil.equals(status, "2")) { // 更改任务状态为完成 taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); taskObj.put("update_time", DateUtil.now()); taskTab.update(taskObj); @@ -114,22 +152,77 @@ public class HkxSendMaterialTask extends AbstractAcsTask { point2Obj.put("ivt_qty", requestObj.getString("qty")); point2Obj.put("standing_time", workorderObj.getString("standing_time")); point2Obj.put("material_id", workorderObj.getString("material_id")); + point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); + point2Obj.put("is_full", requestObj.getString("is_full")); // 终点解锁 point2Obj.put("lock_type", "1"); point2Obj.put("point_status", "3"); - // 载具类型 - point2Obj.put("vehicle_type", taskObj.getString("vehicle_type")); pointTab.update(point2Obj); } - } + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + * 混碾机送料到困料货架 + */ + @Override + public String createTask(JSONObject form) { + String point_code1 = form.getString("point_code1"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("qty"); + String is_full = form.getString("is_full"); + String weight = form.getString("weight"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + // 混碾机设备编码 + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("混碾机满料") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ @Override public void findNextPoint() { - /* - * 根据业务找对应的终点 + /** + * 根据业务找到相应的终点 */ WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); @@ -139,12 +232,12 @@ public class HkxSendMaterialTask extends AbstractAcsTask { String vehicle_type = taskObj.getString("vehicle_type"); JSONObject param1 = new JSONObject(); param1.put("flag", "1"); - param1.put("region_code", "CPQYA01"); + param1.put("region_code", "KLHJ"); param1.put("vehicle_type", "%" + vehicle_type + "%"); - //1、查找库区类是否有响应的载具类型和对应的物料 - JSONObject endPoint = WQL.getWO("QSCH_hkxSendMaterial_01").addParamMap(param1).process().uniqueResult(0); + //1、查找困料货架是否有响应的载具类型和对应的物料 + JSONObject endPoint = WQL.getWO("QSCH_hnCallEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); if (ObjectUtil.isEmpty(endPoint)) { - taskObj.put("remark", "成品区无可用货位!"); + taskObj.put("remark", "困料货架无可用货位!"); taskObj.put("update_time", DateUtil.now()); taskTab.update(taskObj); } else { @@ -163,88 +256,32 @@ public class HkxSendMaterialTask extends AbstractAcsTask { } } - @Override - public List addTask() { - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); - - ArrayList acsTaskArr = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(json.getString("point_code1")) - .next_device_code(json.getString("point_code3")) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - acsTaskArr.add(dto); - } - return acsTaskArr; - } - - @Override - public String createTask(JSONObject whereJson) { - String point_code1 = whereJson.getString("point_code1"); - String vehicle_type = whereJson.getString("vehicle_type"); - String vehicle_code = whereJson.getString("vehicle_code"); - String qty = whereJson.getString("qty"); - - - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); - - JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("豪凯线满料") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .material_info_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .vehicle_type(vehicle_type) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(whereJson.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ @Override public void forceFinish(String task_id) { + /* + * 强制完成 + */ WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj, "2"); + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } } - + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ @Override public void cancel(String task_id) { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java new file mode 100644 index 0000000..1e0f711 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java @@ -0,0 +1,230 @@ +package org.nl.wms.sch.tasks.sendMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: + * @Date: 2022/11/10 + */ +public class SendMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = this.getClass().getName(); + + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + String point_code2 = taskObj.getString("point_code2"); + if (ObjectUtil.isEmpty(point_code2)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + String point_code2 = taskObj.getString("point_code2"); + JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + JSONObject requestObj = task.getJSONObject("request_param"); + //工单标识 + String workorder_id = requestObj.getString("material_info_id"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "1"); + regionIoObj.put("region_id", point2Obj.getString("region_id")); + regionIoObj.put("region_code", point2Obj.getString("region_code")); + regionIoObj.put("region_name", point2Obj.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code3")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + //完成后入库 + point2Obj.put("instorage_time", DateUtil.now()); + point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + point2Obj.put("ivt_qty", requestObj.getString("qty")); + point2Obj.put("standing_time", workorderObj.getString("standing_time")); + point2Obj.put("material_id", workorderObj.getString("material_id")); + point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); + point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); + point2Obj.put("is_full", requestObj.getString("is_full")); + + // 终点解锁 + point2Obj.put("lock_type", "1"); + point2Obj.put("point_status", "3"); + pointTab.update(point2Obj); + } + + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + */ + @Override + public String createTask(JSONObject form) { + String point_code1 = form.getString("point_code1"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("qty"); + String is_full = form.getString("is_full"); + String weight = form.getString("weight"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + // 混碾机设备编码 + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("混碾机满料") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java new file mode 100644 index 0000000..0bb88e4 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java @@ -0,0 +1,290 @@ +package org.nl.wms.sch.tasks.sendMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 烧制满料入库 + * @Date: 2022/11/10 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class SzSendMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = SzSendMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + String point_code2 = taskObj.getString("point_code2"); + if (ObjectUtil.isEmpty(point_code2)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + String point_code2 = taskObj.getString("point_code2"); + JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + JSONObject requestObj = task.getJSONObject("request_param"); + //工单标识 + String workorder_id = requestObj.getString("material_info_id"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "1"); // 入库 + regionIoObj.put("region_id", point2Obj.getString("region_id")); + regionIoObj.put("region_code", point2Obj.getString("region_code")); + regionIoObj.put("region_name", point2Obj.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code3")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + //完成后入库 + point2Obj.put("instorage_time", DateUtil.now()); + point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + point2Obj.put("ivt_qty", requestObj.getString("qty")); + point2Obj.put("standing_time", workorderObj.getString("standing_time")); + point2Obj.put("material_id", workorderObj.getString("material_id")); + point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); + point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); + point2Obj.put("is_full", requestObj.getString("is_full")); + + // 终点解锁 + point2Obj.put("lock_type", "1"); + point2Obj.put("point_status", "3"); + pointTab.update(point2Obj); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + * 压制机送料入窑缓存货架 + */ + @Override + public String createTask(JSONObject form) { + String point_code1 = form.getString("point_code1"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("qty"); + String is_full = form.getString("is_full"); + String weight = form.getString("weight"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + // 压制机设备编码 + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("烧制入库") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + // 查找出窑缓存货架 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "CYZCQ"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + //1、查找出窑缓存区的空位 + JSONObject endPoint = WQL.getWO("QSCH_szSendMaterial_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "出窑暂存区无可用货位!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + /* + * 强制完成 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java deleted file mode 100644 index c28b8e4..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java +++ /dev/null @@ -1,275 +0,0 @@ -package org.nl.wms.sch.tasks.sendMaterial; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.nl.modules.common.exception.BadRequestException; -import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.system.util.CodeUtil; -import org.nl.modules.wql.WQL; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.modules.wql.util.SpringContextHolder; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.service.PointService; -import org.nl.wms.sch.service.dto.PointDto; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.RegionTypeEnum; -import org.nl.wms.util.IdUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - - -/** - * 油漆线送物料 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class YqxSendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = YqxSendMaterialTask.class.getName(); - - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject taskObj, String status) { - /** - *改变任务状态 - **/ - String task_id = taskObj.getString("task_id"); - WQLObject taskTab = WQLObject.getWQLObject("sch_base_task"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - JSONObject jsonTask = taskTab.query("task_id='" + task_id + "'").uniqueResult(0); - - if (StrUtil.equals(status, "0")) { - //取消任务,释放相关点位的锁 - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - JSONObject param = new JSONObject(); - param.put("lock_type", "1"); - param.put("task_id", ""); - pointTab.update(param, "point_code = '" + point_code1 + "'"); - pointTab.update(param, "point_code = '" + point_code2 + "'"); - - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("remark", "已取消"); - taskTab.update(jsonTask); - } - - if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { - //更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if (TaskStatusEnum.FINISHED.getCode().equals(status)) { - // 更新任务状态为完成 - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("taskfinish_mode", taskObj.getString("taskfinish_mode")); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("remark", "任务执行完成"); - taskTab.update(jsonTask); - - - //取消任务,释放相关点位的锁 - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - JSONObject param = new JSONObject(); - param.put("lock_type", "1"); - param.put("task_id", ""); - - pointTab.update(param, "point_code = '" + point_code1 + "'"); - - param.put("point_status", "3"); - pointTab.update(param, "point_code = '" + point_code2 + "'"); - } - - } - - @Override - public void findNextPoint() { - String task_status = TaskStatusEnum.SURE_START.getCode(); - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - JSONArray taskArry = taskTab.query("task_status='" + task_status + "' AND handle_class='" + THIS_CLASS + "' AND is_delete='0' ").getResultJSONArray(0); - for (int i = 0; i < taskArry.size(); i++) { - JSONObject taskObj = taskArry.getJSONObject(i); - String task_id = taskObj.getString("task_id"); - - JSONObject param = new JSONObject(); - param.put("flag", "1"); - JSONObject endPoint = WQL.getWO("QSCH_yqxSendMaterial_01").addParamMap(param).process().uniqueResult(0); - if (ObjectUtil.isEmpty(endPoint)) { - taskObj.put("remark", "电梯无可用点"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - //锁住点位 - endPoint.put("lock_type", "2"); - endPoint.put("task_id", task_id); - pointTab.update(endPoint); - - //修改任务状态 - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("point_code2", endPoint.getString("point_code")); - taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentNickName()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject whereJson) { - String point_code1 = whereJson.getString("point_code1"); - String vehicle_type = whereJson.getString("vehicle_type"); - String vehicle_code = whereJson.getString("vehicle_code"); - String qty = whereJson.getString("qty"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - - String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); - - JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("油漆线满料") - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .material_info_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .vehicle_type(vehicle_type) - .handle_class(THIS_CLASS) - .material_qty(qty) - .create_time(DateUtil.now()) - .request_param(whereJson.toJSONString()) - .build(); - //任务表【SCH_BASE_Task】 - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - - @Override - public void forceFinish(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"2"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Override - public void cancel(String task_id) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"0"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Transactional(rollbackFor = Exception.class) - public JSONObject findEndPoint(JSONObject json) { - String point_code1 = json.getString("point_code1"); - - WQLObject regionTab = WQLObject.getWQLObject("SCH_BASE_Region"); - - // 根据起点判断是什么区域 然后要入到什么区 - PointDto startDto = SpringContextHolder.getBean(PointService.class).findByCode(point_code1); - if (ObjectUtil.isEmpty(startDto)) throw new BadRequestException("起点点位不存在"); - JSONObject jsonStartRegion = regionTab.query("region_id = '" + startDto.getRegion_id() + "'").uniqueResult(0); - - /* - * 物料入库业务:目前只有2个业务,如果区域不正确则报错 - * 1.共挤线 --> 养生区A - * 2.豪凯线 --> 成品区 - */ - String point_code2 = ""; - if (StrUtil.equals(jsonStartRegion.getString("region_code"), RegionTypeEnum.GJQY.getCode())) { - JSONObject map = new JSONObject(); - map.put("flag", "2"); - map.put("region_code", RegionTypeEnum.YSQA.getCode()); - JSONObject jsonEndPoint = WQL.getWO("ST_REGION_IN_01").addParamMap(map).process().uniqueResult(0); - - if (ObjectUtil.isEmpty(jsonEndPoint)) throw new BadRequestException("仓位不足"); - point_code2 = jsonEndPoint.getString("point_code"); - } else if (StrUtil.equals(jsonStartRegion.getString("region_code"), RegionTypeEnum.HKQY.getCode())) { - JSONObject map = new JSONObject(); - map.put("flag", "2"); - map.put("region_code", RegionTypeEnum.CPQYA.getCode()); - JSONObject jsonEndPoint = WQL.getWO("ST_REGION_IN_01").addParamMap(map).process().uniqueResult(0); - - if (ObjectUtil.isEmpty(jsonEndPoint)) throw new BadRequestException("仓位不足"); - point_code2 = jsonEndPoint.getString("point_code"); - } - - JSONObject resuft = new JSONObject(); - resuft.put("point_code2", point_code2); - return resuft; - } - - @Override - public List addTask() { - /* - * 下发给ACS时需要特殊处理 - */ - JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); - - ArrayList acsTaskArr = new ArrayList<>(); - for (int i = 0; i < arr.size(); i++) { - JSONObject json = arr.getJSONObject(i); - AcsTaskDto dto = AcsTaskDto.builder() - .task_id(json.getString("task_id")) - .task_code(json.getString("task_code")) - .task_type(json.getString("acs_task_type")) - .start_device_code(json.getString("point_code1")) - .next_device_code(json.getString("point_code3")) - .vehicle_code(json.getString("vehicle_code")) - .vehicle_type(json.getString("vehicle_type")) - .priority(json.getString("priority")) - .remark(json.getString("remark")) - .build(); - acsTaskArr.add(dto); - } - return acsTaskArr; - } - -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java new file mode 100644 index 0000000..d2a902f --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java @@ -0,0 +1,294 @@ +package org.nl.wms.sch.tasks.sendMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author: lyd + * @description: 压制机满料入库 + * @Date: 2022/11/10 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class YzjSendMaterialTask extends AbstractAcsTask { + private final String THIS_CLASS = YzjSendMaterialTask.class.getName(); + /** + * 添加任务进行下发 + * + * @return + */ + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { // 任务 + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code2")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + /** + * @param task 代表一条任务对象 + * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 + * @return + * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 + * @author ldjun + * @created 2019年4月17日 下午8:51:50 + */ + @Override + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + String point_code2 = taskObj.getString("point_code2"); + if (ObjectUtil.isEmpty(point_code2)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + String point_code2 = taskObj.getString("point_code2"); + JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + JSONObject requestObj = task.getJSONObject("request_param"); + //工单标识 + String workorder_id = requestObj.getString("material_info_id"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "1"); // 入库 + regionIoObj.put("region_id", point2Obj.getString("region_id")); + regionIoObj.put("region_code", point2Obj.getString("region_code")); + regionIoObj.put("region_name", point2Obj.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code3")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + //完成后入库 + point2Obj.put("instorage_time", DateUtil.now()); + point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + point2Obj.put("ivt_qty", requestObj.getString("qty")); + point2Obj.put("standing_time", workorderObj.getString("standing_time")); + point2Obj.put("material_id", workorderObj.getString("material_id")); + point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); + point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); + point2Obj.put("is_full", requestObj.getString("is_full")); + + // 终点解锁 + point2Obj.put("lock_type", "1"); + point2Obj.put("point_status", "3"); + pointTab.update(point2Obj); + } + } + + /** + * @param form 创建任务需要的参数 + * @return 返回任务标识 + * 压制机送料入窑缓存货架 + */ + @Override + public String createTask(JSONObject form) { + String point_code1 = form.getString("point_code1"); + String vehicle_code = form.getString("vehicle_code"); + String qty = form.getString("qty"); + String is_full = form.getString("is_full"); + String weight = form.getString("weight"); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //判断当前点是否有未完成的任务 + JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + // 压制机设备编码 + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_name("压制机满料") + .material_qty(qty) + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(form.toJSONString()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + /** + * @return + * @discription 确定下一点位 + * @author ldjun + * @created 2020年6月12日 下午6:01:06 + */ + @Override + public void findNextPoint() { + /** + * 根据业务找到相应的终点 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "RYZCQ"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + //1、查找入窑暂存货架的空位 + JSONObject endPoint = WQL.getWO("QSCH_yzSendMaterial_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "困料货架无可用货位!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + + + } + } + + /** + * @param task_id 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + @Override + public void forceFinish(String task_id) { + /* + * 强制完成 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"2"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } + + /** + * 取消任务,货物搬回原点 + * + * @param task_id + */ + @Override + public void cancel(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj,"0"); + else { + throw new BadRequestException("未找到该任务或者任务已完成!"); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjCallEmptyVehicle_01.wql new file mode 100644 index 0000000..b85146d --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjCallEmptyVehicle_01.wql @@ -0,0 +1,66 @@ +[交易说明] + 交易名: 分拣送料 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## +IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND point_status = '1' + AND point_type = '1' + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY col_num,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql similarity index 96% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql index 69e7b81..592893c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 豪凯线送料请求 + 交易名: 混碾机送料 所属模块: 功能简述: 版权所有: @@ -40,8 +40,7 @@ ########################################## # 3、业务主过程 # ########################################## - - IF 输入.flag = "1" +IF 输入.flag = "1" QUERY SELECT p.point_id, @@ -64,6 +63,3 @@ ENDSELECT ENDQUERY ENDIF - - - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql similarity index 77% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql index 0e1582e..e840e78 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 油漆线送料请求 + 交易名: 烧制入库 所属模块: 功能简述: 版权所有: @@ -40,8 +40,7 @@ ########################################## # 3、业务主过程 # ########################################## - - IF 输入.flag = "1" +IF 输入.flag = "1" QUERY SELECT p.point_id, @@ -53,10 +52,14 @@ lock_type = '1' AND is_used = '1' AND is_delete = '0' - and (point_code = 'SSX01A2' or point_code = 'SSX02A1') + AND point_status = '1' + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY col_num,row_num,layer_num ENDSELECT ENDQUERY ENDIF - - - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql similarity index 51% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql index 8163667..5bfd567 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 油漆线申请空盘 + 交易名: 压制机送料 所属模块: 功能简述: 版权所有: @@ -13,8 +13,11 @@ ################################################# ## 表字段对应输入参数 ################################################# - 输入.flag TYPEAS s_string - 输入.vehicle_type TYPEAS s_string + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -37,24 +40,26 @@ ########################################## # 3、业务主过程 # ########################################## - - IF 输入.flag = "1" - QUERY - SELECT - * - FROM - SCH_BASE_Point - WHERE - is_used = '1' - AND is_delete = '0' - AND lock_type = '1' - AND point_status = '2' - AND region_code = 'KTPHCQA01' - - OPTION 输入.vehicle_type <> "" - can_vehicle_type = 输入.vehicle_type +IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + AND point_status = '1' + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type ENDOPTION - - ENDSELECT - ENDQUERY - ENDIF \ No newline at end of file + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY col_num,row_num,layer_num + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/bill/service/impl/RegionIoServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/bill/service/impl/RegionIoServiceImpl.java index 9d00621..520913b 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/bill/service/impl/RegionIoServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/bill/service/impl/RegionIoServiceImpl.java @@ -5,9 +5,7 @@ import lombok.RequiredArgsConstructor; import org.nl.modules.common.exception.BadRequestException; import org.nl.modules.wql.WQL; import org.nl.modules.wql.util.SpringContextHolder; -import org.nl.wms.sch.service.RegionService; import org.nl.wms.sch.tasks.cpOut.CpOutTask; -import org.nl.wms.sch.tasks.sendMaterial.HkxSendMaterialTask; import org.nl.wms.st.bill.service.RegionIoService; import org.nl.wms.st.bill.service.dto.RegionIoDto; import org.springframework.stereotype.Service; @@ -22,7 +20,6 @@ import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.wql.core.bean.ResultBean; import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.WqlUtil; import lombok.extern.slf4j.Slf4j; diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls b/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls index 0c2e02a00975f8f4d718804a9eebbddf3fda853a..1248824e98abb1a5d5749a6a7b32aafbbe7a9a23 100644 GIT binary patch delta 50693 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 aJ-3iF1i1*`#~bPi+gpXn0bdCEw)_nan@92h delta 35241 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 - - + + + +