From 2fbac5ca01f97cff3afb415c0d389dce73d9c26f Mon Sep 17 00:00:00 2001 From: liuxy Date: Thu, 1 Feb 2024 10:11:00 +0800 Subject: [PATCH] =?UTF-8?q?add:=E6=9C=A8=E7=AE=B1=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/nl/b_lms/sch/tasks/TwoInBoxTask.java | 181 +++++++ .../service/IBstIvtBoxinfoService.java | 15 + .../impl/BstIvtBoxinfoServiceImpl.java | 33 ++ .../storage_manage/ios/enums/IOSEnum.java | 2 +- .../util/impl/InBoxManageServiceImpl.java | 474 +++++++++++++++++- .../util/impl/InBussManageServiceImpl.java | 1 + .../util/impl/InVehicleManageServiceImpl.java | 1 + .../impl/OutVehicleManageServiceImpl.java | 1 + .../service/iostorInv/util/wql/BST_INBOX.wql | 166 ++++++ .../nl/wms/pda/mps/eum/RegionTypeEnum.java | 3 +- .../outbill/rest/CheckOutBillController.java | 8 + 11 files changed, 880 insertions(+), 5 deletions(-) create mode 100644 lms/nladmin-system/src/main/java/org/nl/b_lms/sch/tasks/TwoInBoxTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/wql/BST_INBOX.wql diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/sch/tasks/TwoInBoxTask.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/sch/tasks/TwoInBoxTask.java new file mode 100644 index 000000000..34135ed52 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/sch/tasks/TwoInBoxTask.java @@ -0,0 +1,181 @@ +package org.nl.b_lms.sch.tasks; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.nl.b_lms.storage_manage.ios.enums.IOSEnum; +import org.nl.common.utils.SecurityUtils; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.AcsTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * 二期空木箱入库任务类 + * Created by Lxy on 2024/1/19. + */ +public class TwoInBoxTask extends AbstractAcsTask { + + /** + * 处理类 + */ + private final String THIS_CLASS = TwoInBoxTask.class.getName(); + + @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); + + char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1); + AcsTaskDto dto = AcsTaskDto.builder() + .ext_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")) + .priority(json.getString("priority")) + .class_type(json.getString("task_type")) + .dtl_type(String.valueOf(dtl_type)) + .remark(json.getString("remark")) + .build(); + resultList.add(dto); + } + return resultList; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateTaskStatus(JSONObject taskObj, String status) { + + // 仓位表 + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + // 载具扩展属性表 + WQLObject veExtTab = WQLObject.getWQLObject("md_pb_storagevehicleext"); + + // 更新任务的参数 + JSONObject map = new JSONObject(); + + /* + * 1-执行中, 2-完成 ,0-acs取消 + */ + // 执行中 + if (status.equals(TaskStatusEnum.EXECUTING.getCode())) { + + map.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + } + + // 完成 + if (status.equals(TaskStatusEnum.FINISHED.getCode())) { + + map.put("task_status", TaskStatusEnum.FINISHED.getCode()); + + // 更新仓位 + JSONObject jsonAttr = attrTab.query("struct_code = '" + taskObj.getString("point_code2") + "'").uniqueResult(0); + jsonAttr.put("lock_type",IOSEnum.LOCK_TYPE.code("未锁定")); + jsonAttr.put("storagevehicle_code",taskObj.getString("vehicle_code")); + attrTab.update(jsonAttr); + } + + // 取消 + if (status.equals(IOSEnum.IS_NOTANDYES.code("否"))) { + + if (taskObj.getIntValue("task_status") > Integer.valueOf(TaskStatusEnum.ISSUE.getCode())) { + throw new BadRequestException("任务已执行不能取消"); + } + + // 更新任务表删除字段 + map.put("is_delete", IOSEnum.IS_NOTANDYES.code("是")); + + // 解锁仓位 + JSONObject jsonAttr = attrTab.query("struct_code = '" + taskObj.getString("point_code2") + "'").uniqueResult(0); + jsonAttr.put("lock_type",IOSEnum.LOCK_TYPE.code("未锁定")); + attrTab.update(jsonAttr); + + // 删除载具对应木箱记录 + veExtTab.delete("pcsn = '"+taskObj.getString("vehicle_code")+"'"); + + } + + map.put("update_optid", SecurityUtils.getCurrentUserId()); + map.put("update_optname", SecurityUtils.getCurrentNickName()); + map.put("update_time", DateUtil.now()); + + WQLObject.getWQLObject("SCH_BASE_Task").update(map, "task_id = '" + taskObj.getString("task_id") + "'"); + } + + @Override + public void findStartPoint() { + + } + + @Override + public void findNextPoint() { + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String createTask(JSONObject form) { + + if (StrUtil.isBlank(form.getString("task_type"))) { + throw new BadRequestException("业务类型不能为空!"); + } + + if (StrUtil.isBlank(form.getString("start_device_code"))) { + throw new BadRequestException("起点不能为空!"); + } + + if (StrUtil.isBlank(form.getString("next_device_code"))) { + throw new BadRequestException("终点不能为空!"); + } + + if (StrUtil.isBlank(form.getString("vehicle_code"))) { + throw new BadRequestException("木箱号不能为空!"); + } + + JSONObject json = new JSONObject(); + json.put("task_id", IdUtil.getSnowflake(1, 1).nextId()); + json.put("task_code", IdUtil.getSnowflake(1, 1).nextId()); + json.put("task_type", form.getString("task_type")); + json.put("vehicle_code", form.getString("vehicle_code")); + json.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + json.put("point_code1", form.getString("start_device_code")); + json.put("point_code2", form.getString("next_device_code")); + json.put("handle_class", this.getClass().getName()); + json.put("create_id", SecurityUtils.getCurrentUserId()); + json.put("create_name", SecurityUtils.getCurrentUsername()); + json.put("create_time", DateUtil.now()); + json.put("priority", "1"); + json.put("acs_task_type", "7"); + + WQLObject.getWQLObject("SCH_BASE_Task").insert(json); + return json.getString("task_id"); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void forceFinish(String task_id) { + JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); + this.updateTaskStatus(taskObj, TaskStatusEnum.FINISHED.getCode()); + } + + @Override + public void cancel(String task_id) { + JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); + this.updateTaskStatus(taskObj, IOSEnum.ACS_RESULT.code("取消")); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/IBstIvtBoxinfoService.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/IBstIvtBoxinfoService.java index 0044b256e..cca13e463 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/IBstIvtBoxinfoService.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/IBstIvtBoxinfoService.java @@ -1,5 +1,6 @@ package org.nl.b_lms.storage_manage.database.service; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo; @@ -13,4 +14,18 @@ import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo; */ public interface IBstIvtBoxinfoService extends IService { + /** + * 根据mes信息插入木箱信息 + * @param whereJson:{ + * Length:长 + * Width:宽 + * Height:高 + * ProductName:物料编码 + * Description:物料名称(根据"|"截取第三个和第四个之间的数值 = 子卷数) + * ContainerName:木箱号 + * } + * @return BstIvtBoxinfo: 木箱信息实体类 + */ + BstIvtBoxinfo mesInsert(JSONObject whereJson); + } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/impl/BstIvtBoxinfoServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/impl/BstIvtBoxinfoServiceImpl.java index d6b4a1725..71fe13d02 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/impl/BstIvtBoxinfoServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/database/service/impl/BstIvtBoxinfoServiceImpl.java @@ -1,9 +1,12 @@ package org.nl.b_lms.storage_manage.database.service.impl; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService; import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo; import org.nl.b_lms.storage_manage.database.service.dao.mapper.BstIvtBoxinfoMapper; +import org.nl.common.utils.IdUtil; import org.springframework.stereotype.Service; /** @@ -17,4 +20,34 @@ import org.springframework.stereotype.Service; @Service public class BstIvtBoxinfoServiceImpl extends ServiceImpl implements IBstIvtBoxinfoService { + @Override + public BstIvtBoxinfo mesInsert(JSONObject whereJson) { + + BstIvtBoxinfo boxDao = BstIvtBoxinfo.builder() + .box_id(IdUtil.getLongId()) + .box_high(whereJson.getString("Height")) + .box_length(whereJson.getString("Length")) + .box_width(whereJson.getString("Width")) + .material_code(whereJson.getString("ProductName")) + .material_name(whereJson.getString("Description")) + .box_no(whereJson.getString("ContainerName")) + .insert_time(DateUtil.now()) + .build(); + + // 截取子卷号 + String description = whereJson.getString("Description"); + + try { + String one = description.substring(description.indexOf("|") + 1); + String two = one.substring(one.indexOf("|") + 1); + String num = two.substring(two.indexOf("|") + 1,two.indexOf("|") + 2); + boxDao.setNum(num); + }catch (Exception e) { + boxDao.setNum("截取失败,请检查mes数据!"); + } + + this.save(boxDao); + + return boxDao; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/enums/IOSEnum.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/enums/IOSEnum.java index 87abb2156..a47f0d5d1 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/enums/IOSEnum.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/enums/IOSEnum.java @@ -60,7 +60,7 @@ public enum IOSEnum { //仓位锁定类型 LOCK_TYPE(MapOf.of("未锁定", "1", "入库锁", "2", "出库锁", "3", "空托盘出库锁", "4", - "空托盘入库锁", "5", "移出锁", "6", "移入锁", "7", "其它", "99" + "空托盘入库锁", "5", "移出锁", "6", "移入锁", "7","木箱入库锁","8", "其它", "99" )), //仓库id diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBoxManageServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBoxManageServiceImpl.java index 9e4948d13..5cd0ea734 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBoxManageServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBoxManageServiceImpl.java @@ -1,8 +1,27 @@ package org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import org.nl.b_lms.sch.tasks.TwoInBoxTask; +import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService; +import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo; +import org.nl.b_lms.storage_manage.ios.enums.IOSEnum; import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service.InBoxManageService; +import org.nl.common.utils.IdUtil; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.pda.mps.eum.RegionTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; /** *

@@ -15,14 +34,463 @@ import org.springframework.stereotype.Service; @Service public class InBoxManageServiceImpl implements InBoxManageService { + /** + * 入库不需要查询的排集合 + */ + private List notInRowList = new ArrayList<>(); + + /** + * 入库不需要查询的巷道集合 + */ + private List notInBlockList = new ArrayList<>(); + + /** + * 木箱信息服务 + */ + @Autowired + private IBstIvtBoxinfoService iBstIvtBoxinfoService; + @Override + @Transactional public void inBox(JSONObject whereJson) { /* - * 1.找木箱区的一个仓位 - * 2.查询mes木箱信息,插入木箱信息表 - * 3.插入木箱对应载具表 + * 1.查询mes木箱信息,插入木箱信息表 + * 2.找木箱区的一个仓位 + * 3.插入木箱对象载具表 + */ + // 点位表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + // 仓位表 + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + // 载具表 + WQLObject vehicleTab = WQLObject.getWQLObject("md_pb_storagevehicleinfo"); + // 载具扩展属性表 + WQLObject veExtTab = WQLObject.getWQLObject("md_pb_storagevehicleext"); + + /* + * 查询mes木箱信息,插入木箱信息表 */ + // 调用mes接口 + JSONObject mesBoxInfo = new JSONObject(); + // 插入木箱信息表 +// BstIvtBoxinfo boxDao = iBstIvtBoxinfoService.mesInsert(mesBoxInfo); + BstIvtBoxinfo boxDao = BstIvtBoxinfo.builder().build(); + + /* + * 找一个木箱区的一个仓位,生辰任务并下发 + */ + // 判断起点点位是否存在 + JSONObject jsonPoint = pointTab.query("point_code = '" + whereJson.getString("device_code") + "' AND is_delete = '" + + IOSEnum.IS_NOTANDYES.code("否") + "' AND is_used = '" + + IOSEnum.IS_NOTANDYES.code("是") + "'") + .uniqueResult(0); + + if (ObjectUtil.isEmpty(jsonPoint)) { + throw new BadRequestException("起始点位不存在或未启用!"); + } + + // 找一个木箱区空位 + JSONObject jsonParam = new JSONObject(); + jsonParam.put("stor_id", IOSEnum.STOR_ID.code("二期")); + jsonParam.put("sect_id", RegionTypeEnum.TWO_MX01.getId()); + jsonParam.put("box_length", boxDao.getBox_length()); + jsonParam.put("box_width", boxDao.getBox_width()); + jsonParam.put("box_high", boxDao.getBox_high()); + + JSONObject jsonAttr = getStruct(jsonParam); + + if (ObjectUtil.isEmpty(jsonAttr)) { + notInRowList.clear(); + notInBlockList.clear(); + throw new BadRequestException("仓位不足!"); + } + + // 生成任务 + JSONObject jsonTaskParam = new JSONObject(); + jsonTaskParam.put("task_type", "010502"); + jsonTaskParam.put("start_device_code", whereJson.getString("device_code")); + jsonTaskParam.put("next_device_code", jsonAttr.getString("struct_code")); + jsonTaskParam.put("vehicle_code", whereJson.getString("box_no")); + + TwoInBoxTask taskBean = new TwoInBoxTask(); + taskBean.createTask(jsonTaskParam); + + taskBean.immediateNotifyAcs(null); + + // 锁定终点 + jsonAttr.put("lock_type", IOSEnum.LOCK_TYPE.code("木箱入库锁")); + attrTab.update(jsonAttr); + + // 清空缓存 + notInRowList.clear(); + notInBlockList.clear(); + + /* + * 插入木箱对应载具表 + */ + JSONObject jsonVehicle = vehicleTab.query("storagevehicle_code = '" + whereJson.getString("vehicle_code") + "'") + .uniqueResult(0); + + if (ObjectUtil.isEmpty(jsonVehicle)) { + throw new BadRequestException("载具不存在!"); + } + + JSONObject jsonVeExt = new JSONObject(); + jsonVeExt.put("storagevehicleext_id", IdUtil.getLongId()); + jsonVeExt.put("storagevehicle_id", jsonVehicle.getLongValue("storagevehicle_id")); + jsonVeExt.put("storagevehicle_code", jsonVehicle.getString("storagevehicle_code")); + jsonVeExt.put("storagevehicle_type", jsonVehicle.getString("storagevehicle_type")); + jsonVeExt.put("pcsn", whereJson.getString("box_no")); + jsonVeExt.put("device_uuid", IdUtil.getLongId()); + veExtTab.insert(jsonVeExt); + } + + /** + * 找一个空仓位(木箱区) + * @param jsonParam { + * stor_id:仓库标识 + * sect_id:库区标识 + * box_length:木箱长度 + * box_width:木箱宽度 + * box_high:木箱高度 + * } + * @return JSONObject : 仓位对象 + */ + private JSONObject getStruct(JSONObject jsonParam) { + // 仓位表 + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + + /* + * 判断是否有仓位 + * 判断条件:库区、仓库、是否启用、是否删除、未锁定、没有载具 + */ + JSONArray structArray = attrTab.query("IFNULL(storagevehicle_code,'') = '' " + + "AND is_used = '" + IOSEnum.IS_NOTANDYES.code("是") + "' AND is_delete = '" + IOSEnum.IS_NOTANDYES.code("否") + "' " + + "AND lock_type = '" + IOSEnum.LOCK_TYPE.code("未锁定") + "' AND stor_id = '"+jsonParam.getString("stor_id")+"' " + + "AND sect_id = '"+jsonParam.getString("sect_id")+"'").getResultJSONArray(0); + + if (ObjectUtil.isEmpty(structArray)) { + notInRowList.clear(); + notInBlockList.clear(); + throw new BadRequestException("仓位不足!"); + } + + // 确定巷道:查看每个巷道最小木箱数的巷道,获取最小木箱数的巷道 + String block_num = getMinBlock(jsonParam); + + // 确定排:查看每排的木箱数量,找到数量最小的那排 + jsonParam.put("block_num",block_num); + String row_num = getMinRow(jsonParam); + + // 确定仓位: 找到仓位 + jsonParam.put("row_num",row_num); + JSONObject jsonAttr = queryStruct(jsonParam); + + // 为空则新找巷道 + if (ObjectUtil.isEmpty(jsonAttr)) { + + jsonParam.put("flag", "1"); + notInBlockList.add(jsonParam.getString("block_num")); + + String join = "('" + String.join("','", notInBlockList) + "')"; + jsonParam.put("not_block", join); + + List blockList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + for (int i = 0; i < blockList.size(); i++) { + JSONObject json = blockList.get(i); + json.put("stor_id", jsonParam.getString("stor_id")); + json.put("sect_id", jsonParam.getString("sect_id")); + json.put("box_length", jsonParam.getString("box_length")); + json.put("box_width", jsonParam.getString("box_width")); + json.put("box_high", jsonParam.getString("box_high")); + + String row_num_2 = getMinRow(json); + json.put("row_num",row_num_2); + JSONObject jsonAttr_2 = queryStruct(json); + + if (ObjectUtil.isNotEmpty(jsonAttr_2)) { + jsonAttr = jsonAttr_2; + break; + } else { + continue; + } + } + } + + return jsonAttr; + } + + /** + * 确定巷道 + * @param jsonParam { + * stor_id: 仓库标识 + * sect_id: 库区标识 + * box_length:木箱长度 + * box_width:木箱宽度 + * box_high:木箱高度 + * } + * @return String 巷道 + */ + private String getMinBlock(JSONObject jsonParam) { + jsonParam.put("flag", "1"); + + // 获取仓库、库区有空位的巷道 + List blockList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + /* + * 查询所属巷道所有木箱 + */ + String block_in = blockList.stream() + .map(row -> row.getString("block_num")) + .collect(Collectors.joining("','")); + + jsonParam.put("flag", "2"); + jsonParam.put("block_in", "('"+block_in+"')"); + + List boxAllList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 为空说明没有木箱,返回最小巷道 + if (ObjectUtil.isEmpty(boxAllList)) { + return blockList.get(0).getString("block_num"); + } + + // 计算每个巷道的木箱数 + ArrayList blockBoxList = new ArrayList<>(); + + for (int i = 0; i < blockList.size(); i++) { + JSONObject jsonBlock = blockList.get(i); + + List box_num = boxAllList.stream() + .filter(row -> row.getString("block_num").equals(jsonBlock.getString("block_num"))) + .collect(Collectors.toList()); + + jsonBlock.put("box_num", String.valueOf(box_num.size())); + blockBoxList.add(jsonBlock); + } + + // 最小木箱数的巷道 + List boxNumList = blockBoxList.stream() + .sorted(Comparator.comparing(row -> row.getString("box_num"))) + .collect(Collectors.toList()); + + return boxNumList.get(0).getString("block_num"); + } + + /** + * 确定排 + * @param jsonParam { + * stor_id: 仓库标识 + * sect_id: 库区标识 + * block_num: 巷道 + * box_length:木箱长度 + * box_width:木箱宽度 + * box_high:木箱高度 + * } + * @return String 排 + */ + private String getMinRow(JSONObject jsonParam) { + + jsonParam.put("flag", "3"); + + // 获取此仓库、库区、巷道 有空位的排 + List rowList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + /* + * 查询所属排的所有木箱 + */ + String row_in = rowList.stream() + .map(row -> row.getString("row_num")) + .collect(Collectors.joining("','")); + + jsonParam.put("flag", "2"); + jsonParam.put("row_in", "('"+row_in+"')"); + + List boxAllList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 为空说明没有木箱,返回最小排 + if (ObjectUtil.isEmpty(boxAllList)) { + if (ObjectUtil.isNotEmpty(rowList)) { + return rowList.get(0).getString("row_num"); + } + } + + // 计算最小排的托盘 + ArrayList rowkBoxList = new ArrayList<>(); + + for (int i = 0; i < rowList.size(); i++) { + JSONObject jsonRow = rowList.get(i); + + List box_num = boxAllList.stream() + .filter(row -> row.getString("row_num").equals(jsonRow.getString("row_num"))) + .collect(Collectors.toList()); + + jsonRow.put("box_num", String.valueOf(box_num.size())); + rowkBoxList.add(jsonRow); + } + + // 最小木箱数的排 + List boxNumList = rowkBoxList.stream() + .sorted(Comparator.comparing(row -> row.getString("box_num"))) + .collect(Collectors.toList()); + + String row_num = ""; + + if (ObjectUtil.isNotEmpty(boxNumList)) { + row_num = boxNumList.get(0).getString("row_num"); + } + return row_num; + } + + /** + * 确定仓位 + * @param jsonParam { + * stor_id: 仓库标识 + * sect_id: 库区标识 + * block_num: 巷道 + * row_num: 排 + * box_length:木箱长度 + * box_width:木箱宽度 + * box_high:木箱高度 + * } + * @return JSONObject 仓位对象 + */ + private JSONObject queryStruct(JSONObject jsonParam) { + JSONObject jsonAttr = getStructOne(jsonParam); + + // 为空找此巷道新的一排 + if (ObjectUtil.isEmpty(jsonAttr)) { + notInRowList.add(jsonParam.getString("row_num")); + + if (ObjectUtil.isEmpty(jsonParam.getString("row_num"))) { + return null; + } + + String join = "('" + String.join("','", notInRowList) + "')"; + jsonParam.put("not_row_in", join); + + // 新的一排 + String row_num_new = this.getMinRow(jsonParam); + jsonParam.put("row_num",row_num_new); + + jsonAttr = this.getStructOne(jsonParam); + } + return jsonAttr; + } + + /** + * 获取一个货位公共方法 + * @param jsonParam { + * stor_id: 仓库标识 + * sect_id: 库区标识 + * block_num: 巷道 + * row_num: 排 + * box_length:木箱长度 + * box_width:木箱宽度 + * box_high:木箱高度 + * } + * @return JSONObject 仓位对象 + */ + private JSONObject getStructOne(JSONObject jsonParam) { + // 获取此仓库、库区、巷道、排的所有空位 根据列、层、深度排序 + jsonParam.put("flag", "4"); + + List rowStructList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 获取此仓库、库区、巷道、排的所有仓位 + jsonParam.put("flag", "5"); + + List structAllList = WQL.getWO("BST_INBOX").addParamMap(jsonParam) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 需要返回的仓位 + JSONObject jsonAttr = new JSONObject(); + + for (int i = 0; i < rowStructList.size(); i++) { + JSONObject json = rowStructList.get(i); + + // 判断伸位 + if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("无"))) { + // 无需深度 + jsonAttr = json; + break; + + } else if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("深"))) { + /* + * 深货位:判断浅货位是否被锁定 + */ + + // 获取此货位对应的浅货位 + List lowAttr = structAllList.stream() + .filter(row -> row.getString("col_num").equals(json.getString("col_num")) && + row.getString("layer_num").equals(json.getString("layer_num")) && + row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("浅"))) + .collect(Collectors.toList()); + + if (ObjectUtil.isEmpty(lowAttr) || lowAttr.size() != 1) { + notInRowList.clear(); + notInBlockList.clear(); + throw new BadRequestException("仓位:" + json.getString("struct_code") + "对应的浅货位错误!"); + } + + // 判断是否被锁定 + JSONObject jsonAttrLow = lowAttr.get(0); + + if (ObjectUtil.isEmpty(jsonAttrLow.getString("storagevehicle_code")) && jsonAttrLow.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) { + // 没有载具和被锁定 + jsonAttr = json; + break; + } else { + continue; + } + + } else if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("浅"))) { + /* + * 浅货位:判断深货位是否空洞,是否是相同类型的托盘 + */ + // 获取此货位对应的深货位 + List darkAttr = structAllList.stream() + .filter(row -> row.getString("col_num").equals(json.getString("col_num")) && + row.getString("layer_num").equals(json.getString("layer_num")) && + row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("深"))) + .collect(Collectors.toList()); + + if (ObjectUtil.isEmpty(darkAttr) || darkAttr.size() != 1) { + notInRowList.clear(); + notInBlockList.clear(); + throw new BadRequestException("仓位:" + json.getString("struct_code") + "对应的深货位错误!"); + } + + // 判断是否有托盘 + JSONObject jsonAttrDark = darkAttr.get(0); + + if (ObjectUtil.isNotEmpty(jsonAttrDark.getString("storagevehicle_code"))) { + + if (jsonAttrDark.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) { + jsonAttr = json; + break; + } else { + continue; + } + } else { + if (jsonAttrDark.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) { + jsonAttr = jsonAttrDark; + break; + } else { + continue; + } + } + + } + } + return jsonAttr; } } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBussManageServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBussManageServiceImpl.java index 908cfe1ed..f19e885ed 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBussManageServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InBussManageServiceImpl.java @@ -144,6 +144,7 @@ public class InBussManageServiceImpl implements InBussManageService { if (ObjectUtil.isNotEmpty(jsonAttr_2)) { jsonAttr = jsonAttr_2; + break; } else { continue; } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InVehicleManageServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InVehicleManageServiceImpl.java index 8051f477b..590dc2071 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InVehicleManageServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/InVehicleManageServiceImpl.java @@ -157,6 +157,7 @@ public class InVehicleManageServiceImpl implements InVehicleManageService { if (ObjectUtil.isNotEmpty(jsonAttr_2)) { jsonAttr = jsonAttr_2; + break; } else { continue; } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/OutVehicleManageServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/OutVehicleManageServiceImpl.java index 2d7c882a8..e5fc90f4f 100644 --- a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/OutVehicleManageServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/impl/OutVehicleManageServiceImpl.java @@ -160,6 +160,7 @@ public class OutVehicleManageServiceImpl implements OutVehicleManageService { if (ObjectUtil.isNotEmpty(jsonAttr_2)) { jsonAttr = jsonAttr_2; + break; } else { continue; } diff --git a/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/wql/BST_INBOX.wql b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/wql/BST_INBOX.wql new file mode 100644 index 000000000..728aa8ad2 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/b_lms/storage_manage/ios/service/iostorInv/util/wql/BST_INBOX.wql @@ -0,0 +1,166 @@ +[交易说明] + 交易名: 木箱入库逻辑 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.stor_id TYPEAS s_string + 输入.sect_id TYPEAS s_string + 输入.block_num TYPEAS s_string + 输入.row_num TYPEAS s_string + 输入.block_in TYPEAS f_string + 输入.row_in TYPEAS f_string + 输入.not_row_in TYPEAS f_string + 输入.not_block TYPEAS f_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + attr.block_num + FROM + st_ivt_structattr attr + WHERE + attr.is_used = '1' + AND attr.is_delete = '0' + AND attr.lock_type = '1' + AND IFNULL(attr.storagevehicle_code,'') = '' + AND attr.stor_id = 输入.stor_id + AND attr.sect_id = 输入.sect_id + + OPTION 输入.not_block <> "" + attr.block_num NOT IN 输入.not_block + ENDOPTION + + group by attr.block_num + order by attr.block_num + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "2" + QUERY + SELECT + attr.* + FROM + st_ivt_structattr attr + WHERE + attr.is_used = '1' + AND attr.is_delete = '0' + AND attr.stor_id = 输入.stor_id + AND attr.sect_id = 输入.sect_id + AND IFNULL(attr.storagevehicle_code,'') <> '' + + OPTION 输入.block_in <> "" + attr.block_num in 输入.block_in + ENDOPTION + + OPTION 输入.row_in <> "" + attr.row_num in 输入.row_in + ENDOPTION + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "3" + QUERY + SELECT + attr.row_num + FROM + st_ivt_structattr attr + WHERE + attr.is_used = '1' + AND attr.is_delete = '0' + AND attr.lock_type = '1' + AND IFNULL(attr.storagevehicle_code,'') = '' + AND attr.stor_id = 输入.stor_id + AND attr.sect_id = 输入.sect_id + + OPTION 输入.block_num <> "" + attr.block_num = 输入.block_num + ENDOPTION + + OPTION 输入.not_row_in <> "" + attr.row_num NOT IN 输入.not_row_in + ENDOPTION + + group by attr.row_num + order by attr.row_num + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "4" + QUERY + SELECT + attr.* + FROM + st_ivt_structattr attr + WHERE + attr.is_used = '1' + AND attr.is_delete = '0' + AND attr.lock_type = '1' + AND IFNULL(attr.storagevehicle_code,'') = '' + AND attr.stor_id = 输入.stor_id + AND attr.sect_id = 输入.sect_id + AND attr.block_num = 输入.block_num + AND attr.row_num = 输入.row_num + + order by attr.col_num,attr.layer_num ASC,attr.zdepth DESC + + ENDSELECT + ENDQUERY + ENDIF + + + IF 输入.flag = "5" + QUERY + SELECT + attr.* + FROM + st_ivt_structattr attr + WHERE + attr.is_used = '1' + AND attr.is_delete = '0' + AND attr.stor_id = 输入.stor_id + AND attr.sect_id = 输入.sect_id + AND attr.block_num = 输入.block_num + AND attr.row_num = 输入.row_num + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/mps/eum/RegionTypeEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/mps/eum/RegionTypeEnum.java index a80c8cecc..0fb1e4e41 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/mps/eum/RegionTypeEnum.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/mps/eum/RegionTypeEnum.java @@ -21,7 +21,8 @@ public enum RegionTypeEnum { XN01("18", "虚拟区", "1586913215886004224"), PD01("19", "盘点区", "1645705331612979200"), TWO_ZZ01("20", "二期暂存区", ""), - TWO_TTP01("21", "二期空托盘区", "1750471797729529856"); + TWO_TTP01("21", "二期空托盘区", "1750471797729529856"), + TWO_MX01("22", "二期木箱区", "1752254266938101760"); private String name; private String code; diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/rest/CheckOutBillController.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/rest/CheckOutBillController.java index 97e9a51bf..f4b9a163e 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/rest/CheckOutBillController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/rest/CheckOutBillController.java @@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.b_lms.storage_manage.ios.enums.IOSEnum; import org.nl.b_lms.storage_manage.ios.service.iostorInv.IStIvtIostorinvOutService; +import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl.InBoxManageServiceImpl; import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl.InVehicleManageServiceImpl; import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl.OutVehicleManageServiceImpl; import org.nl.modules.logging.annotation.Log; @@ -377,4 +378,11 @@ public class CheckOutBillController { return new ResponseEntity<>(HttpStatus.OK); } + @PostMapping("/testInBox") + @Log("木箱入库测试") + public ResponseEntity testInBox(@RequestBody JSONObject whereJson) { + new InBoxManageServiceImpl().inBox(whereJson); + return new ResponseEntity<>(HttpStatus.OK); + } + }