From 8e3434449e16cd8df3fd31aa038f2a00e9ef060c Mon Sep 17 00:00:00 2001 From: liuxy Date: Sun, 28 Apr 2024 08:49:33 +0800 Subject: [PATCH] =?UTF-8?q?rev=EF=BC=9A1.=E7=94=9F=E4=BA=A7=E5=85=A5?= =?UTF-8?q?=E5=BA=93=EF=BC=9A650=E7=9A=84=E7=AE=B1=E5=AD=90=E4=BC=98?= =?UTF-8?q?=E5=85=88=E5=85=A51=E5=B1=82=202.1=E5=B1=82=E7=A9=BA=E6=89=98?= =?UTF-8?q?=E7=9B=98=E6=89=A9=E5=AE=B9=203.=E7=AB=8B=E5=BA=93=E4=B8=BB?= =?UTF-8?q?=E5=AD=98=E5=8C=BA=E4=BB=93=E4=BD=8D=E9=A2=84=E8=AD=A6=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=204.=E4=BB=93=E4=BD=8D=E6=9F=A5=E8=AF=A2=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BC=98=E5=8C=96=EF=BC=9A=E5=A2=9E=E5=8A=A0=E7=AB=8B?= =?UTF-8?q?=E5=BA=93=E5=B1=82=E6=95=B0=E3=80=81=E6=98=AF=E5=90=A6=E7=A9=BA?= =?UTF-8?q?=E4=BD=8D=E6=9D=A1=E4=BB=B6=E6=9F=A5=E8=AF=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/StructattrServiceImpl.java | 1 + .../wms/basedata/st/wql/QST_STRUCT_ATTR.wql | 8 +- .../acs/service/impl/AcsToWmsServiceImpl.java | 125 ++++++++ .../wms/pda/st/service/impl/ThreadDemo.java | 83 +++++ .../sch/manage/AutoQueryStructattrNum.java | 107 +++++++ .../main/java/org/nl/wms/sch/wql/AUTO002.wql | 93 ++++++ .../inbill/service/CheckOutBillService.java | 7 + .../impl/RawAssistIStorServiceImpl.java | 101 ++++++- .../st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql | 39 ++- .../inbill/wql/ST_UPDATESTRUCTSECTONE_01.wql | 199 ++++++++++++ .../service/impl/HandMoveStorServiceImpl.java | 98 ++++++ .../service/impl/CheckOutBillServiceImpl.java | 284 ++++++++++++++++++ .../st/outbill/util/TaskInsertDisManage.java | 34 +++ .../st/outbill/util/TaskUpdateIvtManage.java | 33 ++ .../nl/wms/st/outbill/util/ThreadManage.java | 147 +++++++++ .../src/views/system/notice/NoticeIcon.vue | 31 +- .../views/wms/basedata/st/struct/index.vue | 42 +++ 17 files changed, 1419 insertions(+), 13 deletions(-) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pda/st/service/impl/ThreadDemo.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoQueryStructattrNum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO002.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/ST_UPDATESTRUCTSECTONE_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskInsertDisManage.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskUpdateIvtManage.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/ThreadManage.java diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java index 3fe0b3eef..a87c8d153 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java @@ -60,6 +60,7 @@ public class StructattrServiceImpl implements StructattrService { map.put("lock_type", (String) whereJson.get("lock_type")); map.put("layer_num", (String) whereJson.get("layer_num")); map.put("is_used", (String) whereJson.get("is_used")); + map.put("is_have", (String) whereJson.get("is_have")); //获取人员对应的仓库 UserStorServiceImpl userStorService = new UserStorServiceImpl(); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCT_ATTR.wql b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCT_ATTR.wql index 29a15aa70..28a9eea90 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCT_ATTR.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCT_ATTR.wql @@ -24,6 +24,7 @@ 输入.have_vehicle TYPEAS s_string 输入.layer_num TYPEAS s_string 输入.in_stor_id TYPEAS f_string + 输入.is_have TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -78,8 +79,11 @@ OPTION 输入.is_used <> "" struct.is_used = 输入.is_used ENDOPTION - OPTION 输入.lock_type = "1" - (struct.storagevehicle_code is null or struct.storagevehicle_code = '') + OPTION 输入.is_have = "1" + IFNULL(struct.storagevehicle_code, '') = '' + ENDOPTION + OPTION 输入.is_have = "2" + IFNULL(struct.storagevehicle_code, '') <> '' ENDOPTION ENDSELECT 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 74efb63a3..f4e103705 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 @@ -22,6 +22,7 @@ import org.nl.system.service.notice.ISysNoticeService; import org.nl.system.service.notice.NoticeTypeEnum; import org.nl.system.service.param.impl.SysParamServiceImpl; import org.nl.wms.ext.acs.service.AcsToWmsService; +import org.nl.wms.pda.mps.eum.RegionTypeEnum; import org.nl.wms.pda.mps.service.CasingService; import org.nl.wms.pda.mps.service.ShippingService; import org.nl.wms.pda.mps.service.impl.BakingServiceImpl; @@ -33,6 +34,7 @@ import org.nl.wms.sch.tasks.PaperTrussTask; import org.nl.wms.sch.tasks.SendOutTask; import org.nl.wms.st.inbill.service.RawAssistIStorService; import org.nl.wms.st.inbill.service.StorPublicService; +import org.nl.wms.st.instor.service.impl.HandMoveStorServiceImpl; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.http.HttpStatus; @@ -42,8 +44,10 @@ import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -303,6 +307,9 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { b、没有,则优先找空的巷道;按空位置顺序分配; 3、任务下发,判断巷道的任务类型,只能为空盘入库或者无任务类型; * */ + // 判断是否需要扩容 + isExpansion(); + vehicle_code = CodeUtil.getNewCode("VEHICCLE_CODE_KTP"); JSONArray emptyArr = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParam("flag", "21").process().getResultJSONArray(0); @@ -1673,4 +1680,122 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { } } + + /** + * 判断是否需要扩容 + */ + @Transactional + public void isExpansion() { + WQLObject attr = WQLObject.getWQLObject("st_ivt_structattr"); + WQLObject point = WQLObject.getWQLObject("sch_base_point"); + + // 查询空托盘中的空排还剩下多少 + List empList = WQL.getWO("ST_UPDATESTRUCTSECTONE_01").addParam("flag", "1") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + if (empList.size() >= 3) { + return; + } + + // 进行扩容:找未锁定、空的一排主存区 + String block_num = ""; + String row_num = ""; + // 是否需要移库 + boolean is_move = false; + + List zcList = WQL.getWO("ST_UPDATESTRUCTSECTONE_01").addParam("flag", "2") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + if (ObjectUtil.isNotEmpty(zcList)) { + block_num = zcList.get(0).getString("block_num"); + row_num = zcList.get(0).getString("row_num"); + } else { + // 需要进行移库:找木箱数量较少的那一排移库 + List moveList = WQL.getWO("ST_UPDATESTRUCTSECTONE_01").addParam("flag", "3") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + if (ObjectUtil.isNotEmpty(moveList)) { + // 判断是否有锁 + String block_num_in = moveList.stream() + .map(row -> row.getString("block_num")) + .collect(Collectors.joining("','")); + + String row_num_in = moveList.stream() + .map(row -> row.getString("row_num")) + .collect(Collectors.joining("','")); + + List rowList = attr.query("block_num in ('" + block_num_in + "') AND row_num in ('" + row_num_in + "') and layer_num = '1' and sect_code = 'ZC01'") + .getResultJSONArray(0).toJavaList(JSONObject.class); + + for (int i = 0; i < moveList.size(); i++) { + JSONObject json = moveList.get(i); + + List collect = rowList.stream() + .filter(row -> row.getString("block_num").equals(json.getString("block_num")) && + row.getString("row_num").equals(json.getString("row_num")) + ) + .collect(Collectors.toList()); + + // 判断是否全部都为未锁定 + boolean isLock = collect.stream() + .allMatch(row -> row.getString("lock_type").equals("1")); + + if (isLock) { + block_num = json.getString("block_num"); + row_num = json.getString("row_num"); + is_move = true; + break; + } + } + } + } + + // 判断块、排是否为空 + if (ObjectUtil.isEmpty(block_num) && ObjectUtil.isEmpty(row_num)) { + log.info("1层空托盘区扩容失败:没有匹配到有空位的主存区!"); + return; + } + + try { + // 判断是否需要移库 + if (is_move) { + // 查询出这排需要移库的木箱 -- 默认右通(双通) + List needMoveList = attr.query("sect_code = 'ZC01' and block_num = '" + block_num + "' and row_num = '" + row_num + "' and layer_num = '1' and IFNULL(storagevehicle_code,'') <> '' order by out_order_seq ASC") + .getResultJSONArray(0).toJavaList(JSONObject.class); + + // 判断左通、右通 + if (needMoveList.get(0).getString("placement_type").equals("02")) { + // 左通 -- 根据出库顺序进行排序 + needMoveList = attr.query("sect_code = 'ZC01' and block_num = '" + block_num + "' and row_num = '" + row_num + "' and layer_num = '1' and IFNULL(storagevehicle_code,'') <> '' order by out_order_seq DESC") + .getResultJSONArray(0).toJavaList(JSONObject.class); + } + + // 调用移库方法 + JSONObject moveParam = new JSONObject(); + moveParam.put("needMoveList", needMoveList); + moveParam.put("task_group_id", IdUtil.getSnowflake(1, 1).nextId()); + + HandMoveStorServiceImpl bean = SpringContextHolder.getBean(HandMoveStorServiceImpl.class); + bean.createMoveExpansion(moveParam); + } + + } catch (Exception e) { + log.info("1层空托盘区扩容失败:"+e.getMessage()); + return; + } + + // 更新仓位为空托盘区 + JSONObject jsonParam = new JSONObject(); + jsonParam.put("sect_id", RegionTypeEnum.KTP01.getId()); + jsonParam.put("sect_code", "KTP01"); + jsonParam.put("sect_name", RegionTypeEnum.KTP01.getName()); + attr.update(jsonParam,"sect_code = 'ZC01' AND block_num = '"+block_num+"' AND row_num = '"+row_num+"' AND layer_num = '1'"); + + // 更新点位为主存区域 + jsonParam.put("region_id", RegionTypeEnum.KTP01.getId()); + jsonParam.put("region_code", "KTP01"); + jsonParam.put("region_name", RegionTypeEnum.KTP01.getName()); + point.update(jsonParam,"region_code = 'ZC01' AND block_num = '"+block_num+"' AND row_num = '"+row_num+"' AND layer_num = '1'"); + + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/st/service/impl/ThreadDemo.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/st/service/impl/ThreadDemo.java new file mode 100644 index 000000000..0a465eba2 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/st/service/impl/ThreadDemo.java @@ -0,0 +1,83 @@ +package org.nl.wms.pda.st.service.impl; + +import cn.hutool.core.util.NumberUtil; +import org.nl.modules.common.exception.BadRequestException; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class ThreadDemo { + public static void main(String[] args) throws InterruptedException { + + // 任务数据 + List arr = createArr(); + + // 1个线程分配10个数据 + int ceil = (int) Math.ceil(NumberUtil.div(arr.size(), 10)); + + ExecutorService executorService = Executors.newFixedThreadPool(ceil); + + for (int i = 0; i < ceil; i++) { + + List integers ; + + // 分割集合 + if (i + 1 == ceil) { + integers = arr.subList( i * 10, arr.size()); + } else { + integers = arr.subList( i * 10, (i + 1) * 10); + + } + + // 提交任务 + executorService.submit(new Task1(integers)); + + } + + // 关闭线程 - 但不会立刻关闭 + executorService.shutdown(); + + /* // 等待任务完成 + boolean terminated = executorService.awaitTermination(2, TimeUnit.MINUTES); + + if (!terminated) { + throw new BadRequestException("时间过长!"); + }*/ + + + } + + private static List createArr() { + List objects = new ArrayList<>(); + + for (int i = 1; i <= 109; i++) { + objects.add(i); + } + return objects; + } +} + +class Task1 implements Runnable { + + List b ; + + public Task1(List a) { + b = a; + } + + @Override + public void run() { + + for (int i = 0; i < b.size(); i++) { + Integer integer = b.get(i); + // 任务逻辑 + System.out.println("我是任务==="+ integer +"==="+ Thread.currentThread().getName()); + + } + + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoQueryStructattrNum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoQueryStructattrNum.java new file mode 100644 index 000000000..739ee54fa --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoQueryStructattrNum.java @@ -0,0 +1,107 @@ +package org.nl.wms.sch.manage; + + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.nl.common.utils.IdUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.util.SpringContextHolder; +import org.nl.system.service.notice.ISysNoticeService; +import org.nl.system.service.notice.dao.SysNotice; +import org.nl.system.service.param.impl.SysParamServiceImpl; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 自动查询立库每层的可用仓位 + */ +@Slf4j +@Service +public class AutoQueryStructattrNum { + + @Autowired + private RedissonClient redissonClient; + + @Autowired + private ISysNoticeService iSysNoticeService; + + @SneakyThrows + public void run() { + RLock lock = redissonClient.getLock(this.getClass().getName()); + boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS); + try { + if (tryLock){ + // 查询各个层的可用主存区空位情况 + List empList = WQL.getWO("AUTO002").addParam("flag", "1") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询各个层的可用主存区有货情况 + List haveList = WQL.getWO("AUTO002").addParam("flag", "2") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 获取系统参数 + String download_attr_num = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("download_attr_num").getValue(); + + // 需要插入的集合 + List daoList = new ArrayList<>(); + + for (int i = 0; i < empList.size(); i++) { + JSONObject json = empList.get(i); + + if (json.getDoubleValue("num") <= Double.parseDouble(download_attr_num)) { + + // 已用仓位 + double aDouble = haveList.stream() + .filter(row -> row.getString("layer_num").equals(json.getString("layer_num"))) + .map(row -> row.getDoubleValue("num")) + .reduce(Double::sum).orElse(0.00); + + + // 计算主存区和 + double add = NumberUtil.add(json.getDoubleValue("num"), aDouble); + + // 空位占比 + double emp_pro = NumberUtil.round(NumberUtil.div(json.getDoubleValue("num"), add) * 100, 2).doubleValue(); + // 有货占比 + double have_pro = NumberUtil.round(NumberUtil.div(aDouble, add) * 100, 2).doubleValue(); + + // 内容 + String notice_title = "立库"+json.getString("layer_num")+ "层主存区仓位不足"+download_attr_num+"个!可用仓位:" + +json.getString("num")+ "个 占比:"+emp_pro+"% ,已用仓位:"+NumberUtil.round(aDouble, 0) +"个 占比:"+have_pro+"%"; + + SysNotice dao = SysNotice.builder() + .notice_id(IdUtil.getStringId()) + .notice_title(notice_title) + .notice_content(notice_title) + .notice_type("2") + .have_read("1") + .deal_status("1") + .create_time(DateUtil.now()) + .build(); + + daoList.add(dao); + } + } + + // 插入 + iSysNoticeService.saveBatch(daoList); + } + }finally { + if (tryLock) { + lock.unlock(); + } + } + + } + + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO002.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO002.wql new file mode 100644 index 000000000..7efd7026f --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO002.wql @@ -0,0 +1,93 @@ +[交易说明] + 交易名: 查询仓库空位情况 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + layer_num, + count(struct_code) AS num + FROM + st_ivt_structattr + WHERE + is_delete = '0' + AND is_used = '1' + AND IFNULL(storagevehicle_code,'') = '' + AND lock_type = '1' + AND sect_code = 'ZC01' + + group by layer_num + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "2" + QUERY + SELECT + layer_num, + count(struct_code) AS num + FROM + st_ivt_structattr + WHERE + is_delete = '0' + AND is_used = '1' + AND IFNULL(storagevehicle_code,'') <> '' + AND sect_code = 'ZC01' + + group by layer_num + + UNION + + SELECT + layer_num, + count(struct_code) AS num + FROM + st_ivt_structattr + WHERE + is_delete = '0' + AND is_used = '1' + AND IFNULL(storagevehicle_code,'') = '' + AND lock_type <> '1' + AND sect_code = 'ZC01' + + group by layer_num + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/CheckOutBillService.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/CheckOutBillService.java index 207d6df7e..5280312dc 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/CheckOutBillService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/CheckOutBillService.java @@ -118,6 +118,13 @@ public interface CheckOutBillService { */ void allDiv(JSONObject whereJson); + /** + * 全部分配,对同一出库单明细进行分配(多线程) + * + * @param whereJson / + */ + void allDiv2(JSONObject whereJson); + /** * 对一条明细自动分配 * diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java index 0a10cae91..aaeb2f4d7 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java @@ -974,13 +974,13 @@ public class RawAssistIStorServiceImpl implements RawAssistIStorService { /* * 判断木箱高度能入第几层: - * 1.低于650mm 三层都可以入 + * 1.低于650mm 优先入1层 没位置在入 2/3层 * 2.650mm > 木箱 <= 800mm, 只能入二、三层 * 3.第三层要根据实际高度分配货位 */ // 入库木箱下限 String in_download_box_high = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("in_download_box_high").getValue(); - // 入库木箱上线 + // 入库木箱上限 String in_up_box_high = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("in_up_box_high").getValue(); double box_high = sub_jo.getDoubleValue("box_high"); @@ -999,7 +999,37 @@ public class RawAssistIStorServiceImpl implements RawAssistIStorService { row_map.put("in_layer_num", in_layer_num); //查询到当前可用的巷道 - JSONArray rowArr2 = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParamMap(row_map).process().getResultJSONArray(0); + JSONArray rowArr2 = new JSONArray(); + + if (box_high <= Double.parseDouble(in_download_box_high)) { + // 优先入1层 + row_map.put("layer_num", "1"); + + rowArr2 = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParamMap(row_map).process().getResultJSONArray(0); + + if (ObjectUtil.isEmpty(rowArr2)) { + // 如果1层没有相同物料订单号的则找有空位的一排 + row_map.put("flag", "1111"); + rowArr2 = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParamMap(row_map).process().getResultJSONArray(0); + + // 如果为空则进行扩容 + if (ObjectUtil.isEmpty(rowArr2)) { + boolean is_expansion = updateStructSectOne(); + + if (is_expansion) { + // 如果为true则在进行查询一次 + rowArr2 = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParamMap(row_map).process().getResultJSONArray(0); + } + } + } + } + + if (ObjectUtil.isEmpty(rowArr2)) { + row_map.put("layer_num", ""); + row_map.put("flag", "111"); + rowArr2 = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParamMap(row_map).process().getResultJSONArray(0); + } + JSONArray rowArr = new JSONArray(); for (int i = 0; i < rowArr2.size(); i++) { JSONObject jo = rowArr2.getJSONObject(i); @@ -1053,6 +1083,29 @@ public class RawAssistIStorServiceImpl implements RawAssistIStorService { break; } else { // 双通 + // 判断这一排全部是否是空位 + List attrList = WQLObject.getWQLObject("st_ivt_structattr") + .query("block_num = '" + block_num + "' and placement_type = '" + placement_type + "' and row_num = '" + row_num + "' and is_used = '1' and is_delete = '0' order by out_order_seq DESC") + .getResultJSONArray(0).toJavaList(JSONObject.class); + + // 如果这排全部是空位 并且没有被锁定则返回一个货位 + boolean is_all = attrList.stream() + .allMatch(row -> ObjectUtil.isEmpty(row.getString("storagevehicle_code")) + && row.getString("lock_type").equals("1") + ); + + if (is_all) { + struct_jo = attrList.get(0); + + // 判断是否是第三层 且高度是否超过仓位高度 + if (StrUtil.equals(struct_jo.getString("layer_num"), "3")) { + if (box_high > struct_jo.getDoubleValue("height")) { + struct_jo = null; + continue; + } + } + break; + } // 先倒序找到第一个木箱、判断上一个是否有货位 JSONObject jsonDescBox = WQLObject.getWQLObject("st_ivt_structattr").query("lock_type = '1' AND block_num = '" + block_num + "'AND placement_type = '" + placement_type + "' AND row_num = '" + row_num + "' AND is_delete = '0' AND is_used = '1' AND IFNULL(storagevehicle_code,'') <> '' order by out_order_seq DESC").uniqueResult(0); @@ -2624,4 +2677,46 @@ public class RawAssistIStorServiceImpl implements RawAssistIStorService { jsonParam.put("region_name", RegionTypeEnum.ZZ01.getName()); point.update(jsonParam,"region_code = 'ZC01' AND block_num = '"+block_num+"' AND row_num = '"+row_num+"' AND layer_num = '"+layer_num+"'"); } + + /** + * 1层主存区扩容:空托盘区 ==> 主存区 + */ + public boolean updateStructSectOne() { + WQLObject attr = WQLObject.getWQLObject("st_ivt_structattr"); + WQLObject point = WQLObject.getWQLObject("sch_base_point"); + /* + * 1.找空托盘区空的一排进行扩容 + * + */ + // 找空托盘区空的一排 + List rowList = WQL.getWO("ST_UPDATESTRUCTSECTONE_01").addParam("flag", "1") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 如果没有空排或者空排低于2排则不允许扩容 + if (ObjectUtil.isEmpty(rowList) || rowList.size() <= 2) { + log.info("空托盘区需预留2排空位,不容许扩容!"); + return false; + } + + try { + JSONObject json = rowList.get(0); + + // 更新仓位为主存区 + JSONObject jsonParam = new JSONObject(); + jsonParam.put("sect_id", RegionTypeEnum.ZC01.getId()); + jsonParam.put("sect_code", "ZC01"); + jsonParam.put("sect_name", RegionTypeEnum.ZC01.getName()); + attr.update(jsonParam,"sect_code = 'KTP01' AND block_num = '"+json.getString("block_num")+"' AND row_num = '"+json.getString("row_num")+"' AND layer_num = '1'"); + + // 更新点位为主存区域 + jsonParam.put("region_id", RegionTypeEnum.ZC01.getId()); + jsonParam.put("region_code", "ZC01"); + jsonParam.put("region_name", RegionTypeEnum.ZC01.getName()); + point.update(jsonParam,"region_code = 'KTP01' AND block_num = '"+json.getString("block_num")+"' AND row_num = '"+json.getString("row_num")+"' AND layer_num = '1'"); + } catch (Exception e) { + System.out.println("1层主存区扩容失败:"+e.getMessage()); + return false; + } + return true; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql index d187cda6c..f34164670 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql @@ -46,7 +46,7 @@ 输入.sap_pcsn_in TYPEAS f_string 输入.vbeln_in TYPEAS f_string 输入.box_no_in TYPEAS f_string - + 输入.layer_num TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -474,12 +474,49 @@ LEFT JOIN md_me_materialbase mb ON mb.material_id = ivt.material_id WHERE sa.sect_id = 输入.sect_id + AND IFNULL(sa.storagevehicle_code,"") = '' + AND sa.is_used = '1' + AND sa.is_delete = '0' + AND sa.lock_type = '1' OPTION 输入.material_code <> "" mb.material_code = 输入.material_code ENDOPTION OPTION 输入.sale_order_name <> "" sub.sale_order_name = 输入.sale_order_name ENDOPTION + + OPTION 输入.layer_num <> "" + sa.layer_num = 输入.layer_num + ENDOPTION + + GROUP BY + sa.block_num,sa.row_num,sa.placement_type + ORDER BY + sa.placement_type desc,num + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "1111" + QUERY + SELECT + count(sa.struct_code) AS num, + sa.block_num, + sa.row_num, + sa.placement_type + FROM + st_ivt_structattr sa + WHERE + sa.sect_id = 输入.sect_id + and sa.is_used = '1' + and sa.is_delete = '0' + and ifnull(sa.storagevehicle_code,'') = '' + and sa.lock_type = '1' + + OPTION 输入.layer_num <> "" + sa.layer_num = 输入.layer_num + ENDOPTION + GROUP BY sa.block_num,sa.row_num,sa.placement_type ORDER BY diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/ST_UPDATESTRUCTSECTONE_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/ST_UPDATESTRUCTSECTONE_01.wql new file mode 100644 index 000000000..8867d0063 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/ST_UPDATESTRUCTSECTONE_01.wql @@ -0,0 +1,199 @@ +[交易说明] + 交易名: 更新仓位属性查询 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + * + FROM + ( + SELECT + sa.block_num, + sa.row_num, + COUNT( sa.struct_code ) AS struct_num + FROM + st_ivt_structattr sa + WHERE + sa.is_delete = '0' + AND sa.is_used = '1' + AND sa.sect_code = 'KTP01' + GROUP BY + sa.block_num, + sa.row_num + ) a + WHERE + EXISTS ( + SELECT + * + FROM + ( + SELECT + block_num, + row_num, + COUNT( sa2.struct_code ) AS struct_num + FROM + st_ivt_structattr sa2 + WHERE + sa2.lock_type = '1' + AND sa2.is_used = '1' + AND sa2.is_delete = '0' + AND sa2.sect_code = 'KTP01' + AND IFNULL( sa2.storagevehicle_code, '' ) = '' + GROUP BY + sa2.block_num, + sa2.row_num + ) b + WHERE + b.block_num = a.block_num + AND b.row_num = a.row_num + AND a.struct_num = b.struct_num + ) ORDER BY struct_num DESC + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "2" + QUERY + SELECT + * + FROM + ( + SELECT + sa.block_num, + sa.row_num, + COUNT( sa.struct_code ) AS struct_num + FROM + st_ivt_structattr sa + WHERE + sa.is_delete = '0' + AND sa.is_used = '1' + AND sa.layer_num = '1' + AND sa.sect_code = 'ZC01' + GROUP BY + sa.block_num, + sa.row_num + ) a + WHERE + EXISTS ( + SELECT + * + FROM + ( + SELECT + block_num, + row_num, + COUNT( sa2.struct_code ) AS struct_num + FROM + st_ivt_structattr sa2 + WHERE + sa2.lock_type = '1' + AND sa2.is_used = '1' + AND sa2.is_delete = '0' + AND sa2.sect_code = 'ZC01' + AND sa2.layer_num = '1' + AND IFNULL( sa2.storagevehicle_code, '' ) = '' + GROUP BY + sa2.block_num, + sa2.row_num + ) b + WHERE + b.block_num = a.block_num + AND b.row_num = a.row_num + AND a.struct_num = b.struct_num + ) ORDER BY struct_num DESC + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "3" + QUERY + SELECT + * + FROM + ( + SELECT + sa.block_num, + sa.row_num, + COUNT( sa.struct_code ) AS struct_num + FROM + st_ivt_structattr sa + WHERE + sa.is_delete = '0' + AND sa.is_used = '1' + AND sa.layer_num = '1' + AND sa.sect_code = 'ZC01' + AND IFNULL( sa.storagevehicle_code, '' ) = '' + GROUP BY + sa.block_num, + sa.row_num + ) a + WHERE + EXISTS ( + SELECT + * + FROM + ( + SELECT + block_num, + row_num, + COUNT( sa2.struct_code ) AS struct_num + FROM + st_ivt_structattr sa2 + WHERE + sa2.lock_type = '1' + AND sa2.is_used = '1' + AND sa2.is_delete = '0' + AND sa2.sect_code = 'ZC01' + AND sa2.layer_num = '1' + AND IFNULL( sa2.storagevehicle_code, '' ) <> '' + GROUP BY + sa2.block_num, + sa2.row_num + ) b + WHERE + b.block_num = a.block_num + AND b.row_num = a.row_num + + ) ORDER BY struct_num DESC + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java index 5f4fe2fd1..ab55d7e6c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java @@ -20,6 +20,7 @@ import org.nl.modules.wql.util.WqlUtil; import org.nl.wms.basedata.st.service.impl.UserStorServiceImpl; import org.nl.wms.pda.mps.eum.RegionTypeEnum; import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.OutTask; import org.nl.wms.st.inbill.service.RawAssistIStorService; import org.nl.wms.st.inbill.service.StorPublicService; import org.nl.wms.st.instor.service.HandMoveStorService; @@ -31,6 +32,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.function.Consumer; import java.util.stream.Collectors; /** @@ -43,6 +45,8 @@ public class HandMoveStorServiceImpl implements HandMoveStorService { private final StorPublicService storPublicService; private final HandMoveStorAcsTask handMoveStorAcsTask; private final EmpMoveTask empMoveTask; + private final OutTask outTask; + private final RawAssistIStorService rawAssistIStorService; @Override public Map pageQuery(Map whereJson, Pageable page) { @@ -1595,4 +1599,98 @@ public class HandMoveStorServiceImpl implements HandMoveStorService { } wo_mst.update(jo_mst); } + + /** + * 扩容移库 + * @param whereJson / + */ + public void createMoveExpansion(JSONObject whereJson) { + //任务表 + WQLObject wo_Task = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + + JSONArray needMoveList = whereJson.getJSONArray("needMoveList"); + + for (int i = 0; i < needMoveList.size(); i++) { + JSONObject json = needMoveList.getJSONObject(i); + + JSONObject jsonAttr = attrTab.query("struct_code = '" + json.getString("struct_code") + "'").uniqueResult(0); + + JSONObject mapParam = new JSONObject();// 生成移库单传入参数 + JSONArray table = new JSONArray(); // 明细参数 + + mapParam.put("bill_type", "22"); + mapParam.put("buss_type", "22"); + mapParam.put("bill_status", "10"); + + mapParam.put("biz_date", DateUtil.today()); + mapParam.put("stor_code", "CP01"); + mapParam.put("stor_id", "1582991156504039424"); + mapParam.put("stor_name", "成品仓库"); + mapParam.put("is_task", "1"); + + // 查询移入货位 + JSONObject moveParam = new JSONObject(); + moveParam.put("box_no", json.getString("storagevehicle_code")); + moveParam.put("sect_id", RegionTypeEnum.ZZ01.getId()); + moveParam.put("layer_num", jsonAttr.getString("layer_num")); + JSONObject jsonMove = rawAssistIStorService.autoDisMove(moveParam); + // 查询移出货位的库存物料 + JSONObject jsonMoveIvt = WQL.getWO("ST_OUTIVT03") + .addParam("flag", "6") + .addParam("struct_id", json.getString("struct_id")) + .process().uniqueResult(0); + + // 移库单明细 + JSONObject jsonMoveDtl = new JSONObject(); + jsonMoveDtl.put("is_task", "2"); + jsonMoveDtl.put("turnout_sect_id", json.getLongValue("sect_id")); + jsonMoveDtl.put("turnout_sect_code", json.getString("sect_code")); + jsonMoveDtl.put("turnout_sect_name", json.getString("sect_name")); + jsonMoveDtl.put("turnout_struct_id", json.getLongValue("struct_id")); + jsonMoveDtl.put("turnout_struct_code", json.getString("struct_code")); + jsonMoveDtl.put("turnout_struct_name", json.getString("struct_name")); + jsonMoveDtl.put("material_id", jsonMoveIvt.getLongValue("material_id")); + jsonMoveDtl.put("pcsn", jsonMoveIvt.getString("pcsn")); + jsonMoveDtl.put("quality_scode", "01"); + jsonMoveDtl.put("qty_unit_id", jsonMoveIvt.getLongValue("qty_unit_id")); + jsonMoveDtl.put("qty_unit_name", jsonMoveIvt.getString("unit_name")); + jsonMoveDtl.put("qty", jsonMoveIvt.getDoubleValue("canuse_qty")); + jsonMoveDtl.put("storagevehicle_code", json.getString("storagevehicle_code")); + jsonMoveDtl.put("turnin_sect_id", jsonMove.getLongValue("sect_id")); + jsonMoveDtl.put("turnin_sect_code", jsonMove.getString("sect_code")); + jsonMoveDtl.put("turnin_sect_name", jsonMove.getString("sect_name")); + jsonMoveDtl.put("turnin_struct_id", jsonMove.getLongValue("struct_id")); + jsonMoveDtl.put("turnin_struct_code", jsonMove.getString("struct_code")); + jsonMoveDtl.put("turnin_struct_name", jsonMove.getString("struct_name")); + + // 生成任务 + JSONObject param2 = new JSONObject(); + param2.put("task_type", "010503"); + param2.put("vehicle_code", json.getString("storagevehicle_code")); + param2.put("point_code1", json.getString("struct_code")); + param2.put("point_code2", jsonMove.getString("struct_code")); + param2.put("task_group_id", whereJson.getLongValue("task_group_id")); // 任务组 + param2.put("sort_seq", i + 1); // 任务组顺序号 + String move_task_id = outTask.createTask(param2); + + // 回显移库明细任务id + jsonMoveDtl.put("task_id", move_task_id); + table.add(jsonMoveDtl); + // 更新任务处理类 + JSONObject jsonTaskMove = wo_Task.query("task_id = '" + move_task_id + "'").uniqueResult(0); + jsonTaskMove.put("task_type", "010505"); + jsonTaskMove.put("handle_class", HandMoveStorAcsTask.class.getName()); + jsonTaskMove.put("remark", "1层空托盘扩容移库"); + wo_Task.update(jsonTaskMove); + + mapParam.put("tableData", table); + // 调用移库单新增方法 + if (ObjectUtil.isNotEmpty(needMoveList)) { + insertDtl2(mapParam); + } + + handMoveStorAcsTask.immediateNotifyAcs(null); + } + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java index 272599cea..a3e6bf81a 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java @@ -35,6 +35,7 @@ import org.nl.wms.st.inbill.service.StorPublicService; import org.nl.wms.st.instor.service.HandMoveStorService; import org.nl.wms.st.instor.service.impl.HandMoveStorServiceImpl; import org.nl.wms.st.instor.task.HandMoveStorAcsTask; +import org.nl.wms.st.outbill.util.ThreadManage; import org.nl.wms.st.returns.service.InAndOutReturnService; import org.nl.wms.st.returns.service.impl.InAndOutRetrunServiceImpl; import org.nl.wms.util.TranUtil; @@ -1513,6 +1514,289 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { } } + @Override + @Transactional(rollbackFor = Exception.class) + public void allDiv2(JSONObject whereJson) { + //出库分配表 + WQLObject wo_dis = WQLObject.getWQLObject("ST_IVT_IOStorInvDis"); + //出库明细表 + WQLObject wo_dtl = WQLObject.getWQLObject("ST_IVT_IOStorInvDtl"); + //出库主表 + WQLObject wo_mst = WQLObject.getWQLObject("ST_IVT_IOStorInv"); + //库区表 + WQLObject wo_sect = WQLObject.getWQLObject("st_ivt_sectattr"); + + //定义需要更新的仓位集合 + HashMap Struct_map = new HashMap(); + String iostorinv_id = whereJson.getString("iostorinv_id"); + //查询主表信息 + JSONObject jo_mst = wo_mst.query("iostorinv_id = '" + iostorinv_id + "'").uniqueResult(0); + if (ObjectUtil.isEmpty(jo_mst)) { + throw new BadRequestException("查不到出库单信息"); + } + + // 如果是发货出库则判断运费和物流公司不能为空 + String bill_type = jo_mst.getString("bill_type"); + if (StrUtil.equals(bill_type, "1001")) { + String trans_code = jo_mst.getString("trans_code"); + String estimated_freight = jo_mst.getString("estimated_freight"); + + if (ObjectUtil.isEmpty(trans_code)) { + throw new BadRequestException("物流公司不能为空"); + } + if (ObjectUtil.isEmpty(estimated_freight)) { + throw new BadRequestException("预估运费不能为空"); + } + + } + + //查询生成和未分配完的明细 + JSONArray dtls = WQL.getWO("QST_IVT_CHECKOUTBILL") + .addParam("flag", "2") + .addParam("bill_status", "30") + .addParam("unassign_flag", "1") + .addParam("iostorinv_id", iostorinv_id) + .addParam("iostorinvdtl_id", whereJson.getString("iostorinvdtl_id")) + .process() + .getResultJSONArray(0); + if (ObjectUtil.isEmpty(dtls)) { + throw new BadRequestException("当前订单无可分配出库明细"); + } + + for (int i = 0; i < dtls.size(); i++) { + JSONObject dtl = dtls.getJSONObject(i); + double unassign_qty = dtl.getDoubleValue("unassign_qty"); + /* + * 分配规则: + * top1.有销售订单号:用销售订单号、物料去找这批物料最早入库的所在的巷道 + * top2.没有销售订单号,有子卷号:固定出某个木箱 + * top3.没有销售订单号,没有子卷号:找此物料最早入库的所在巷道 + */ + boolean is_top3 = false; + if (ObjectUtil.isEmpty(dtl.getString("source_bill_code")) && ObjectUtil.isEmpty(dtl.getString("pcsn"))) { + is_top3 = true; + } + JSONObject jsonMap = new JSONObject(); + // 已分配重量 + double assign_qty = dtl.getDoubleValue("assign_qty"); + + // 需要更新库存的集合 + List updateIvtList = new ArrayList<>(); + // 需要插入分配明细的集合 + List instDisList = new ArrayList<>(); + + if (ObjectUtil.isNotEmpty(dtl.getString("source_bill_code")) || is_top3) { + while (unassign_qty > 0) { + // 1.有销售订单号 + jsonMap.put("flag", "1"); + jsonMap.put("material_id", dtl.getString("material_id")); + jsonMap.put("sale_order_name", dtl.getString("source_bill_code")); + jsonMap.put("sect_id", whereJson.getString("sect_id")); + jsonMap.put("stor_id", whereJson.getString("stor_id")); + + JSONObject jsonOneIvt = WQL.getWO("ST_OUTIVT01").addParamMap(jsonMap).process().uniqueResult(0); + if (ObjectUtil.isEmpty(jsonOneIvt)) { + throw new BadRequestException("库存不足"); + } + + // 查询这一巷道所有此物料此库存此销售订单的库存 + jsonMap.put("flag", "2"); + jsonMap.put("row_num", jsonOneIvt.getString("row_num")); + jsonMap.put("block_num", jsonOneIvt.getString("block_num")); + JSONArray ivtAllArr = WQL.getWO("ST_OUTIVT01").addParamMap(jsonMap).process().getResultJSONArray(0); + + for (int j = 0; j < ivtAllArr.size(); j++) { + JSONObject ivt = ivtAllArr.getJSONObject(j); + double canuse_qty = ivt.getDoubleValue("canuse_qty"); + assign_qty = NumberUtil.add(assign_qty, canuse_qty); + + if (unassign_qty >= canuse_qty) { + unassign_qty = NumberUtil.sub(unassign_qty, canuse_qty); + } else { + unassign_qty = 0; + } + + // 查询此木箱下的所有子卷 + jsonMap.put("flag", "3"); + jsonMap.put("storagevehicle_code", ivt.getString("storagevehicle_code")); + JSONArray ivtAllArr2 = WQL.getWO("ST_OUTIVT01").addParamMap(jsonMap).process().getResultJSONArray(0); + + for (int k = 0; k < ivtAllArr2.size(); k++) { + // 更新库存 + JSONObject ivt2 = ivtAllArr2.getJSONObject(k); + ivt2.put("change_qty", ivt2.getDoubleValue("canuse_qty")); + ivt2.put("bill_type_scode", jo_mst.getString("bill_type")); + ivt2.put("inv_id", dtl.getString("iostorinv_id")); + ivt2.put("bill_code", jo_mst.getString("bill_code")); + ivt2.put("bill_table", "ST_IVT_IOStorInv"); + // 放在更新库存的集合当中 + updateIvtList.add(ivt2); + // storPublicService.IOStor(ivt2, "11"); + + + //生成分配明细 + dtl.put("iostorinvdis_id", IdUtil.getSnowflake(1, 1).nextId()); + dtl.put("sect_id", ivt2.getString("sect_id")); + dtl.put("sect_code", ivt2.getString("sect_code")); + dtl.put("sect_name", ivt2.getString("sect_name")); + dtl.put("struct_id", ivt2.getString("struct_id")); + dtl.put("struct_code", ivt2.getString("struct_code")); + dtl.put("struct_name", ivt2.getString("struct_name")); + dtl.put("pcsn", ivt2.getString("pcsn")); + dtl.put("box_no", ivt2.getString("storagevehicle_code")); + dtl.put("storagevehicle_id", ivt2.getString("storagevehicle_id")); + dtl.put("storagevehicle_code", ivt2.getString("storagevehicle_code")); + dtl.put("storagevehicle_type", ivt2.getString("storagevehicle_type")); + dtl.put("is_issued", "0"); + dtl.put("plan_qty", ivt2.getDoubleValue("change_qty")); + dtl.put("real_qty", ivt2.getDoubleValue("change_qty")); + dtl.put("is_overdue", ivt2.getString("is_overdue")); + dtl.put("instorage_time", ivt2.getString("instorage_time")); + + // 如果所属仓位是虚拟区 则将分配明细状态变为生成 + JSONObject jsonSect = wo_sect.query("sect_id = '" + ivt2.getString("sect_id") + "'").uniqueResult(0); + if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { + dtl.put("work_status", "01"); + } else { + dtl.put("work_status", "00"); + } + + if (jo_mst.getString("is_overdue").equals("1")) { + // 判断是否超期 + if (ivt2.getString("is_overdue").equals("1")) { + dtl.put("work_status", "01"); + } + } + // 放在插入分配明细的集合当中 + instDisList.add(dtl); + // wo_dis.insert(dtl); + } + //记录需锁定的仓位 + Struct_map.put(ivt.getString("struct_id"), ivt); + // 为零结束 + if (unassign_qty == 0) { + break; + } + } + } + + } else { + // 确定子卷: 根据子卷找到库存出掉 + jsonMap.put("flag", "1"); + jsonMap.put("material_id", dtl.getString("material_id")); + jsonMap.put("pcsn", dtl.getString("pcsn")); + jsonMap.put("box_no", dtl.getString("box_no")); + jsonMap.put("sect_id", whereJson.getString("sect_id")); + jsonMap.put("stor_id", whereJson.getString("stor_id")); + + JSONObject jsonIvt = WQL.getWO("ST_OUTIVT01").addParamMap(jsonMap).process().uniqueResult(0); + if (ObjectUtil.isEmpty(jsonIvt)) { + throw new BadRequestException("库存不足"); + } + + double canuse_qty = jsonIvt.getDoubleValue("canuse_qty"); + jsonIvt.put("change_qty", canuse_qty + ""); + unassign_qty = 0; + assign_qty = NumberUtil.add(assign_qty, canuse_qty); + + //更新库存 + jsonIvt.put("bill_type_scode", jo_mst.getString("bill_type")); + jsonIvt.put("inv_id", dtl.getString("iostorinv_id")); + jsonIvt.put("bill_code", jo_mst.getString("bill_code")); + jsonIvt.put("bill_table", "ST_IVT_IOStorInv"); + // 放入需要更新库存的集合当中 + updateIvtList.add(jsonIvt); + // storPublicService.IOStor(jsonIvt, "11"); + + //生成分配明细 + dtl.put("iostorinvdis_id", IdUtil.getSnowflake(1, 1).nextId()); + dtl.put("sect_id", jsonIvt.getString("sect_id")); + dtl.put("sect_code", jsonIvt.getString("sect_code")); + dtl.put("sect_name", jsonIvt.getString("sect_name")); + dtl.put("struct_id", jsonIvt.getString("struct_id")); + dtl.put("struct_code", jsonIvt.getString("struct_code")); + dtl.put("struct_name", jsonIvt.getString("struct_name")); + dtl.put("pcsn", jsonIvt.getString("pcsn")); + dtl.put("box_no", jsonIvt.getString("storagevehicle_code")); + dtl.put("storagevehicle_id", jsonIvt.getString("storagevehicle_id")); + dtl.put("storagevehicle_code", jsonIvt.getString("storagevehicle_code")); + dtl.put("storagevehicle_type", jsonIvt.getString("storagevehicle_type")); + dtl.put("is_issued", "0"); + dtl.put("plan_qty", jsonIvt.getDoubleValue("change_qty")); + dtl.put("real_qty", jsonIvt.getDoubleValue("change_qty")); + dtl.put("is_overdue", jsonIvt.getString("is_overdue")); + dtl.put("instorage_time", jsonIvt.getString("instorage_time")); + // 如果所属仓位是虚拟区 则将分配明细状态变为生成 + JSONObject jsonSect = wo_sect.query("sect_id = '" + jsonIvt.getString("sect_id") + "'").uniqueResult(0); + if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { + dtl.put("work_status", "01"); + } else { + dtl.put("work_status", "00"); + } + + // 判断是否超期 + if (jo_mst.getString("is_overdue").equals("1")) { + if (jsonIvt.getString("is_overdue").equals("1")) { + dtl.put("work_status", "01"); + } + } + + // 放入需要插入分配明细的集合当中 + instDisList.add(dtl); + // wo_dis.insert(dtl); + + //记录需锁定的仓位 (如果此明细有相同物料的且子卷号不能为空的则在最后一个明细分配完成后锁定仓位) + JSONObject map = new JSONObject(); + map.put("flag", "5"); + map.put("material_id", dtl.getString("material_id")); + map.put("box_no", dtl.getString("box_no")); + map.put("iostorinv_id", iostorinv_id); + map.put("iostorinvdtl_id", dtl.getString("iostorinvdtl_id")); + JSONArray dtlArr = WQL.getWO("ST_OUTIVT01").addParamMap(map).process().getResultJSONArray(0); + if (dtlArr.size() == 0) { + Struct_map.put(jsonIvt.getString("struct_id"), jsonIvt); + } + + } + HashMap map_dtl = new HashMap(); + //更新明细 + map_dtl.put("unassign_qty", unassign_qty + ""); + map_dtl.put("assign_qty", assign_qty + ""); + if (unassign_qty == 0) { + map_dtl.put("bill_status", "40"); + } else { + map_dtl.put("bill_status", "30"); + } + wo_dtl.update(map_dtl, "iostorinvdtl_id='" + dtl.getString("iostorinvdtl_id") + "'"); + + //更新主表状态 + this.updateMststatus(iostorinv_id); + + // 开启线程池 + JSONObject param = new JSONObject(); + param.put("updateIvtList", updateIvtList); + param.put("instDisList", instDisList); + param.put("struct_map", Struct_map); + + ThreadManage bean = SpringContextHolder.getBean(ThreadManage.class); + bean.startThread(param); + + /* //锁定起点点位、仓位 + Collection c = Struct_map.values(); + Iterator it = c.iterator(); + JSONObject from_start = new JSONObject(); + from_start.put("lock_type", "3"); + for (; it.hasNext(); ) { + JSONObject Struct = it.next(); + from_start.put("struct_id", Struct.getString("struct_id")); + from_start.put("inv_type", jo_mst.getString("bill_type")); + from_start.put("inv_id", jo_mst.getString("iostorinv_id")); + from_start.put("inv_code", jo_mst.getString("bill_code")); + storPublicService.updateStructAndPoint(from_start); + }*/ + } + } + @Override @Transactional(rollbackFor = Exception.class) public void allDivOne(JSONObject whereJson) { diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskInsertDisManage.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskInsertDisManage.java new file mode 100644 index 000000000..39a15c649 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskInsertDisManage.java @@ -0,0 +1,34 @@ +package org.nl.wms.st.outbill.util; + +import com.alibaba.fastjson.JSONObject; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.st.inbill.service.StorPublicService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class TaskInsertDisManage implements Runnable { + + List disList ; + + public TaskInsertDisManage(List a) { + disList = a; + } + + @Override + public void run() { + + WQLObject disTab = WQLObject.getWQLObject("st_ivt_iostorinvdis"); + + // 业务处理: 更新库存 + for (int i = 0; i < disList.size(); i++) { + JSONObject json = disList.get(i); + + disTab.insert(json); + + } + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskUpdateIvtManage.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskUpdateIvtManage.java new file mode 100644 index 000000000..cf15ac6c2 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/TaskUpdateIvtManage.java @@ -0,0 +1,33 @@ +package org.nl.wms.st.outbill.util; + +import com.alibaba.fastjson.JSONObject; +import org.nl.modules.wql.util.SpringContextHolder; +import org.nl.wms.st.inbill.service.impl.StorPublicServiceImpl; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class TaskUpdateIvtManage implements Runnable { + + List ivtList ; + + public TaskUpdateIvtManage(List a) { + ivtList = a; + } + + @Override + public void run() { + + StorPublicServiceImpl bean = SpringContextHolder.getBean(StorPublicServiceImpl.class); + + // 业务处理: 更新库存 + for (int i = 0; i < ivtList.size(); i++) { + JSONObject json = ivtList.get(i); + + bean.IOStor(json,"11"); + + } + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/ThreadManage.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/ThreadManage.java new file mode 100644 index 000000000..7407b2540 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/util/ThreadManage.java @@ -0,0 +1,147 @@ +package org.nl.wms.st.outbill.util; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson.JSONObject; +import org.nl.modules.wql.util.SpringContextHolder; +import org.nl.wms.st.inbill.service.impl.StorPublicServiceImpl; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +public class ThreadManage { + + /** + * 开启线程池 + * @param whereJson:{ + * updateIvtList : 需更新的库存集合 + * instDisList : 需插入的分配明细集合 + * struct_map : 需更新的仓位map + * } + */ + @Transactional + public void startThread(JSONObject whereJson) { + // 需要更新的库存集合 + List updateIvtList = whereJson.getJSONArray("updateIvtList").toJavaList(JSONObject.class); + // 需要插入的分配明细集合 + List instDisList = whereJson.getJSONArray("instDisList").toJavaList(JSONObject.class); + // 需更新的仓位map + JSONObject struct_map = whereJson.getJSONObject("struct_map"); + + // 调用库存处理 + updateIvtManage(updateIvtList); + + // 调用插入分配明细处理 + insertDisManage(instDisList); + + // 调用更新仓位处理 + updateAttrManage(struct_map); + + } + + /** + * 更新库存 + * @param updateIvtList:库存集合 + */ + private void updateIvtManage(List updateIvtList) { + + // 1个线程分配10个数据 + int ceil = (int) Math.ceil(NumberUtil.div(updateIvtList.size(), 10)); + + // 创建线程池 + ExecutorService executorService = Executors.newFixedThreadPool(ceil); + + for (int i = 0; i < ceil; i++) { + + List list ; + + // 分割集合 + if (i + 1 == ceil) { + list = updateIvtList.subList( i * 10, updateIvtList.size()); + } else { + list = updateIvtList.subList( i * 10, (i + 1) * 10); + + } + + // 提交任务 + executorService.submit(new TaskUpdateIvtManage(list)); + + } + + // 关闭线程 - 但不会立刻关闭 + executorService.shutdown(); + + } + + /** + * 插入分配明细 + * @param instDisList:分配明细集合 + */ + private void insertDisManage(List instDisList) { + + // 1个线程分配10个数据 + int ceil = (int) Math.ceil(NumberUtil.div(instDisList.size(), 10)); + + // 创建线程池 + ExecutorService executorService = Executors.newFixedThreadPool(ceil); + + for (int i = 0; i < ceil; i++) { + + List list ; + + // 分割集合 + if (i + 1 == ceil) { + list = instDisList.subList( i * 10, instDisList.size()); + } else { + list = instDisList.subList( i * 10, (i + 1) * 10); + + } + + // 提交任务 + executorService.submit(new TaskInsertDisManage(list)); + + } + + // 关闭线程 - 但不会立刻关闭 + executorService.shutdown(); + } + + + /** + * 更新仓位 + * @param Struct_map + */ + private void updateAttrManage(JSONObject Struct_map) { + + // 创建线程池 + ExecutorService executorService = Executors.newFixedThreadPool(10); + + // 业务处理 + StorPublicServiceImpl bean = SpringContextHolder.getBean(StorPublicServiceImpl.class); + + executorService.submit(() -> { + Collection c = Struct_map.values(); + Iterator it = c.iterator(); + JSONObject from_start = new JSONObject(); + from_start.put("lock_type", "3"); + for (; it.hasNext(); ) { + JSONObject Struct = (JSONObject) it.next(); + from_start.put("struct_id", Struct.getString("struct_id")); + from_start.put("inv_type", "1111"); + from_start.put("inv_id", "2222"); + from_start.put("inv_code", "3333"); + bean.updateStructAndPoint(from_start); + } + }); + + // 关闭线程 - 但不会立刻关闭 + executorService.shutdown(); + } + +} diff --git a/lms/nladmin-ui/src/views/system/notice/NoticeIcon.vue b/lms/nladmin-ui/src/views/system/notice/NoticeIcon.vue index 4ae56e9ee..4d5037190 100644 --- a/lms/nladmin-ui/src/views/system/notice/NoticeIcon.vue +++ b/lms/nladmin-ui/src/views/system/notice/NoticeIcon.vue @@ -1,21 +1,22 @@