From 714e30a1b9e3c154c46bb13c7a52ddbf0731f7d9 Mon Sep 17 00:00:00 2001 From: wusiyu <2015098864@qq.com> Date: Thu, 4 Jun 2026 10:26:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=93=E5=BA=93=E7=AE=A1=E7=90=86=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/StGraphiteMoldOutServiceImpl.java | 216 ++++++++---------- 1 file changed, 92 insertions(+), 124 deletions(-) diff --git a/blade-service/blade-wms/src/main/java/org/springblade/wms/service/impl/StGraphiteMoldOutServiceImpl.java b/blade-service/blade-wms/src/main/java/org/springblade/wms/service/impl/StGraphiteMoldOutServiceImpl.java index bbaed0734..929e3a5f5 100644 --- a/blade-service/blade-wms/src/main/java/org/springblade/wms/service/impl/StGraphiteMoldOutServiceImpl.java +++ b/blade-service/blade-wms/src/main/java/org/springblade/wms/service/impl/StGraphiteMoldOutServiceImpl.java @@ -1,6 +1,5 @@ package org.springblade.wms.service.impl; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; @@ -22,8 +21,6 @@ import org.springblade.wms.mapper.StGraphiteMoldOutMapper; import org.springblade.wms.mapper.StRealtimeStockMapper; import org.springblade.wms.mapper.StStockInoutRecordMapper; import org.springblade.wms.pojo.dto.StGraphiteMoldOutDTO; -import org.springblade.wms.pojo.dto.StockOccupyTempDTO; -import org.springblade.wms.pojo.dto.SubItemStockDTO; import org.springblade.wms.pojo.entity.*; import org.springblade.wms.pojo.vo.StGraphiteMoldOutVO; import org.springblade.wms.service.*; @@ -105,83 +102,36 @@ public class StGraphiteMoldOutServiceImpl extends BaseServiceImpl sourceSubStockList = new ArrayList<>(); - for (DsPartEntity bom : allChildPartList) { - SubItemStockDTO item = new SubItemStockDTO(); - item.setSubGoodsCode(bom.getPartCode()); - // 单套子件耗用数量 - DsPartRelationEntity dsPartRelation = stGlassCakeOutMapper.getPartQuota(faYieldOrder.getPartCode(), item.getSubGoodsCode()); - item.setSingleUseQty(dsPartRelation.getQuota()); + int maxCanMakeSet = (int) Math.floor(totalNeedSetInt); + for (DsPartEntity sub : allChildPartList) { + String subCode = sub.getPartCode(); + DsPartRelationEntity dsPartRelation = stGlassCakeOutMapper.getPartQuota(faYieldOrder.getPartCode(), subCode); + double singleUse = dsPartRelation.getQuota(); + // 查询该子件所有可用库存 - List stockAll = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(item.getSubGoodsCode()); - item.setStockList(stockAll); - // 实时剩余可用总库存(动态变化,逐套消耗) - double usableTotal = 0D; - if (CollUtil.isNotEmpty(stockAll)) { - usableTotal = stockAll.stream() - .mapToDouble(s -> s.getQuantity() - Optional.ofNullable(s.getOccupyQuantity()).orElse(0D)) - .sum(); + List stockList = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(subCode); + if (stockList == null || stockList.isEmpty()) { + maxCanMakeSet = 0; + break; } - item.setRemainUsable(usableTotal); - sourceSubStockList.add(item); - } - - // 存放最终要生成的出库明细、占用、锁库数据 - List needOccupyList = new ArrayList<>(); - // 成功齐套的套数 - int successSet = 0; - - // 2、逐套循环校验,能齐一套算一套 - for (; successSet < totalNeedSetInt; ) { - boolean oneSetAllOk = true; - // 本套需要占用的临时数据 - List tempOccupy = new ArrayList<>(); - - for (SubItemStockDTO sub : sourceSubStockList) { - double needPerSet = sub.getSingleUseQty(); - // 当前子件剩余可用不足单套用量 → 本套不齐套,跳出 - if (sub.getRemainUsable() < needPerSet - 0.001) { - oneSetAllOk = false; - break; - } - // 从子件库存里扣对应数量,优先耗前面批次库存 - double surplusNeed = needPerSet; - List stockList = sub.getStockList(); - for (StRealtimeStock stock : stockList) { - if (surplusNeed <= 0.001) break; - double occ = Optional.ofNullable(stock.getOccupyQuantity()).orElse(0D); - double usable = stock.getQuantity() - occ; - if (usable <= 0) continue; - - double takeQty = Math.min(usable, surplusNeed); - // 暂存本次占用信息,齐套成功才真正落库 - StockOccupyTempDTO temp = new StockOccupyTempDTO(); - temp.setStock(stock); - temp.setTakeQty(takeQty); - temp.setSubGoodsCode(sub.getSubGoodsCode()); - tempOccupy.add(temp); - - surplusNeed -= takeQty; - } - // 子件总可用扣减本套耗用 - sub.setRemainUsable(sub.getRemainUsable() - needPerSet); - } + // 总可用库存 + double totalUsable = stockList.stream() + .mapToDouble(s -> s.getQuantity() - Optional.ofNullable(s.getOccupyQuantity()).orElse(0D)) + .filter(v -> v > 0) + .sum(); - if (oneSetAllOk) { - // 本套齐套,临时占用转正,加入最终列表 - needOccupyList.addAll(tempOccupy); - successSet++; - } else { - // 任意子件不齐套,终止整套循环,不再尝试后续套数 - break; - } + // 当前子件最多可做套数 + int subCanMake = (int) Math.floor(totalUsable / singleUse); + maxCanMakeSet = Math.min(maxCanMakeSet, subCanMake); } - if (CollUtil.isEmpty(needOccupyList)) { - log.info("父件{}无任何可齐套库存,需求{}套,生成0套预出库", partOne.getPartCode(), totalNeedSet); + // 无可齐套套数,直接返回 + if (maxCanMakeSet <= 0) { + log.info("父件【{}】无可用齐套库存,需求{}套,生成0套预出库", faYieldOrder.getPartCode(), totalNeedSetInt); return Collections.emptyList(); } + log.info("父件【{}】最终可齐套套数:{} 套", faYieldOrder.getPartCode(), maxCanMakeSet); List preOutStockList = new ArrayList<>(); @@ -195,59 +145,77 @@ public class StGraphiteMoldOutServiceImpl extends BaseServiceImpl stockList = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(subCode); + double remainNeed = totalNeed; + + // 遍历库存,一个不够用下一个,自动生成多条出库 + for (StRealtimeStock maxStock : stockList) { + if (remainNeed <= 0.001) { + break; + } + + double occupyQty = Optional.ofNullable(maxStock.getOccupyQuantity()).orElse(0D); + double usableQty = maxStock.getQuantity() - occupyQty; + if (usableQty <= 0) { + continue; + } + + // 本次实际扣减数量 + double actualTake = Math.min(usableQty, remainNeed); + StGraphiteMoldOut preOutStock = new StGraphiteMoldOut(); + preOutStock.setYoCode(faYieldOrder.getYoCode()); + preOutStock.setCardNo(dto.getCardNo()); + + String parentOutCode = datePrefix + StrUtil.padPre(String.valueOf(lastNum), 4, '0'); + preOutStock.setParentOutCode(parentOutCode); + String outCode = parentOutCode + "-" + childNum; + preOutStock.setOutCode(outCode); + childNum++; // preOutStock.setOutCode(stStockInoutRecordService.generateCode()); - SubItemStockDTO currSub = sourceSubStockList.stream() - .filter(s -> s.getSubGoodsCode().equals(temp.getSubGoodsCode())) - .findFirst().get(); - preOutStock.setNeedQuantity(currSub.getSingleUseQty() * totalNeedSet); - preOutStock.setCompleteQuantity(takeQty); - preOutStock.setGoodsId(maxStock.getGoodsId()); - StGoods stGoods = stGoodsService.getById(maxStock.getGoodsId()); - preOutStock.setGoodsName(stGoods.getGoodsName()); - preOutStock.setGoodsCode(stGoods.getGoodsCode()); - preOutStock.setSlId(maxStock.getSlId()); - StStorageLocation location = stStorageLocationService.getById(maxStock.getSlId()); - preOutStock.setLocation(location.getLocation()); - preOutStock.setShId(maxStock.getShId()); - StStorehouse storehouse = stStorehouseService.getById(maxStock.getShId()); - preOutStock.setShName(storehouse.getShName()); - preOutStock.setRlsId(maxStock.getId()); - preOutStock.setPiNo(maxStock.getPiNo()); - - preOutStock.setCurStatus(0L); - preOutStock.setCreateTime(now); - preOutStock.setUpdateTime(now); - - preOutStockList.add(preOutStock); - System.out.println("石墨模子件[编码:" + preOutStock.getGoodsCode() + "]库存充足,已构建预出库信息,库存ID:" + maxStock.getId()); - - // 更新实时库存占用数量 - double oldOccupy = Optional.ofNullable(maxStock.getOccupyQuantity()).orElse(0D); - maxStock.setOccupyQuantity(oldOccupy + takeQty); - stRealtimeStockService.updateById(maxStock); - - StRealtimeStockLock lock = new StRealtimeStockLock(); - lock.setId(IdUtil.getSnowflake().nextId()); - lock.setRlsId(maxStock.getId()); - lock.setWoNo(preOutStock.getCardNo()); - lock.setOccupyQuantity(takeQty); - lock.setStatus(0); - stRealtimeStockMapper.insertStockLock(lock); + preOutStock.setNeedQuantity(singleUse * totalNeedSet); + preOutStock.setCompleteQuantity(totalNeed); + preOutStock.setGoodsId(maxStock.getGoodsId()); + StGoods stGoods = stGoodsService.getById(maxStock.getGoodsId()); + preOutStock.setGoodsName(stGoods.getGoodsName()); + preOutStock.setGoodsCode(stGoods.getGoodsCode()); + preOutStock.setSlId(maxStock.getSlId()); + StStorageLocation location = stStorageLocationService.getById(maxStock.getSlId()); + preOutStock.setLocation(location.getLocation()); + preOutStock.setShId(maxStock.getShId()); + StStorehouse storehouse = stStorehouseService.getById(maxStock.getShId()); + preOutStock.setShName(storehouse.getShName()); + preOutStock.setRlsId(maxStock.getId()); + preOutStock.setPiNo(maxStock.getPiNo()); + + preOutStock.setCurStatus(0L); + preOutStock.setCreateTime(now); + preOutStock.setUpdateTime(now); + + preOutStockList.add(preOutStock); + System.out.println("石墨模子件[编码:" + preOutStock.getGoodsCode() + "]库存充足,已构建预出库信息,库存ID:" + maxStock.getId()); + + // 更新实时库存占用数量 + maxStock.setOccupyQuantity(occupyQty + actualTake); + stRealtimeStockService.updateById(maxStock); + + StRealtimeStockLock lock = new StRealtimeStockLock(); + lock.setId(IdUtil.getSnowflake().nextId()); + lock.setRlsId(maxStock.getId()); + lock.setWoNo(preOutStock.getCardNo()); + lock.setOccupyQuantity(actualTake); + lock.setStatus(0); + stRealtimeStockMapper.insertStockLock(lock); + + remainNeed -= actualTake; + } } System.out.println("石墨模子件预出库全部完成!");