|
|
|
@ -1,6 +1,5 @@ |
|
|
|
package org.springblade.wms.service.impl; |
|
|
|
package org.springblade.wms.service.impl; |
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil; |
|
|
|
import cn.hutool.core.date.DateUtil; |
|
|
|
import cn.hutool.core.util.IdUtil; |
|
|
|
import cn.hutool.core.util.IdUtil; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
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.StRealtimeStockMapper; |
|
|
|
import org.springblade.wms.mapper.StStockInoutRecordMapper; |
|
|
|
import org.springblade.wms.mapper.StStockInoutRecordMapper; |
|
|
|
import org.springblade.wms.pojo.dto.StGraphiteMoldOutDTO; |
|
|
|
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.entity.*; |
|
|
|
import org.springblade.wms.pojo.vo.StGraphiteMoldOutVO; |
|
|
|
import org.springblade.wms.pojo.vo.StGraphiteMoldOutVO; |
|
|
|
import org.springblade.wms.service.*; |
|
|
|
import org.springblade.wms.service.*; |
|
|
|
@ -105,83 +102,36 @@ public class StGraphiteMoldOutServiceImpl extends BaseServiceImpl<StGraphiteMold |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<SubItemStockDTO> sourceSubStockList = new ArrayList<>(); |
|
|
|
int maxCanMakeSet = (int) Math.floor(totalNeedSetInt); |
|
|
|
for (DsPartEntity bom : allChildPartList) { |
|
|
|
for (DsPartEntity sub : allChildPartList) { |
|
|
|
SubItemStockDTO item = new SubItemStockDTO(); |
|
|
|
String subCode = sub.getPartCode(); |
|
|
|
item.setSubGoodsCode(bom.getPartCode()); |
|
|
|
DsPartRelationEntity dsPartRelation = stGlassCakeOutMapper.getPartQuota(faYieldOrder.getPartCode(), subCode); |
|
|
|
// 单套子件耗用数量
|
|
|
|
double singleUse = dsPartRelation.getQuota(); |
|
|
|
DsPartRelationEntity dsPartRelation = stGlassCakeOutMapper.getPartQuota(faYieldOrder.getPartCode(), item.getSubGoodsCode()); |
|
|
|
|
|
|
|
item.setSingleUseQty(dsPartRelation.getQuota()); |
|
|
|
|
|
|
|
// 查询该子件所有可用库存
|
|
|
|
// 查询该子件所有可用库存
|
|
|
|
List<StRealtimeStock> stockAll = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(item.getSubGoodsCode()); |
|
|
|
List<StRealtimeStock> stockList = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(subCode); |
|
|
|
item.setStockList(stockAll); |
|
|
|
if (stockList == null || stockList.isEmpty()) { |
|
|
|
// 实时剩余可用总库存(动态变化,逐套消耗)
|
|
|
|
maxCanMakeSet = 0; |
|
|
|
double usableTotal = 0D; |
|
|
|
break; |
|
|
|
if (CollUtil.isNotEmpty(stockAll)) { |
|
|
|
|
|
|
|
usableTotal = stockAll.stream() |
|
|
|
|
|
|
|
.mapToDouble(s -> s.getQuantity() - Optional.ofNullable(s.getOccupyQuantity()).orElse(0D)) |
|
|
|
|
|
|
|
.sum(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
item.setRemainUsable(usableTotal); |
|
|
|
|
|
|
|
sourceSubStockList.add(item); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 存放最终要生成的出库明细、占用、锁库数据
|
|
|
|
|
|
|
|
List<StockOccupyTempDTO> needOccupyList = new ArrayList<>(); |
|
|
|
|
|
|
|
// 成功齐套的套数
|
|
|
|
|
|
|
|
int successSet = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2、逐套循环校验,能齐一套算一套
|
|
|
|
|
|
|
|
for (; successSet < totalNeedSetInt; ) { |
|
|
|
|
|
|
|
boolean oneSetAllOk = true; |
|
|
|
|
|
|
|
// 本套需要占用的临时数据
|
|
|
|
|
|
|
|
List<StockOccupyTempDTO> tempOccupy = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (SubItemStockDTO sub : sourceSubStockList) { |
|
|
|
|
|
|
|
double needPerSet = sub.getSingleUseQty(); |
|
|
|
|
|
|
|
// 当前子件剩余可用不足单套用量 → 本套不齐套,跳出
|
|
|
|
|
|
|
|
if (sub.getRemainUsable() < needPerSet - 0.001) { |
|
|
|
|
|
|
|
oneSetAllOk = false; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 从子件库存里扣对应数量,优先耗前面批次库存
|
|
|
|
// 总可用库存
|
|
|
|
double surplusNeed = needPerSet; |
|
|
|
double totalUsable = stockList.stream() |
|
|
|
List<StRealtimeStock> stockList = sub.getStockList(); |
|
|
|
.mapToDouble(s -> s.getQuantity() - Optional.ofNullable(s.getOccupyQuantity()).orElse(0D)) |
|
|
|
for (StRealtimeStock stock : stockList) { |
|
|
|
.filter(v -> v > 0) |
|
|
|
if (surplusNeed <= 0.001) break; |
|
|
|
.sum(); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (oneSetAllOk) { |
|
|
|
// 当前子件最多可做套数
|
|
|
|
// 本套齐套,临时占用转正,加入最终列表
|
|
|
|
int subCanMake = (int) Math.floor(totalUsable / singleUse); |
|
|
|
needOccupyList.addAll(tempOccupy); |
|
|
|
maxCanMakeSet = Math.min(maxCanMakeSet, subCanMake); |
|
|
|
successSet++; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// 任意子件不齐套,终止整套循环,不再尝试后续套数
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(needOccupyList)) { |
|
|
|
// 无可齐套套数,直接返回
|
|
|
|
log.info("父件{}无任何可齐套库存,需求{}套,生成0套预出库", partOne.getPartCode(), totalNeedSet); |
|
|
|
if (maxCanMakeSet <= 0) { |
|
|
|
|
|
|
|
log.info("父件【{}】无可用齐套库存,需求{}套,生成0套预出库", faYieldOrder.getPartCode(), totalNeedSetInt); |
|
|
|
return Collections.emptyList(); |
|
|
|
return Collections.emptyList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
log.info("父件【{}】最终可齐套套数:{} 套", faYieldOrder.getPartCode(), maxCanMakeSet); |
|
|
|
|
|
|
|
|
|
|
|
List<StGraphiteMoldOut> preOutStockList = new ArrayList<>(); |
|
|
|
List<StGraphiteMoldOut> preOutStockList = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
@ -195,59 +145,77 @@ public class StGraphiteMoldOutServiceImpl extends BaseServiceImpl<StGraphiteMold |
|
|
|
} |
|
|
|
} |
|
|
|
int childNum = 1; |
|
|
|
int childNum = 1; |
|
|
|
|
|
|
|
|
|
|
|
// 3、遍历占用明细:更新库存占用、新增锁库、生成预出库单据
|
|
|
|
// 遍历每个子件
|
|
|
|
for (StockOccupyTempDTO temp : needOccupyList) { |
|
|
|
for (DsPartEntity subItem : allChildPartList) { |
|
|
|
lastNum++; |
|
|
|
String subCode = subItem.getPartCode(); |
|
|
|
StRealtimeStock maxStock = temp.getStock(); |
|
|
|
DsPartRelationEntity dsPartRelation = stGlassCakeOutMapper.getPartQuota(faYieldOrder.getPartCode(), subCode); |
|
|
|
Double takeQty = temp.getTakeQty(); |
|
|
|
double singleUse = dsPartRelation.getQuota(); |
|
|
|
|
|
|
|
double totalNeed = singleUse * maxCanMakeSet; // 子件总需求数量
|
|
|
|
StGraphiteMoldOut preOutStock = new StGraphiteMoldOut(); |
|
|
|
|
|
|
|
preOutStock.setYoCode(faYieldOrder.getYoCode()); |
|
|
|
// 查询该子件所有可用库存
|
|
|
|
preOutStock.setCardNo(dto.getCardNo()); |
|
|
|
List<StRealtimeStock> stockList = stRealtimeStockMapper.selectMaxUsableStockByMoldAttr(subCode); |
|
|
|
|
|
|
|
double remainNeed = totalNeed; |
|
|
|
String parentOutCode = datePrefix + StrUtil.padPre(String.valueOf(lastNum), 4, '0'); |
|
|
|
|
|
|
|
preOutStock.setParentOutCode(parentOutCode); |
|
|
|
// 遍历库存,一个不够用下一个,自动生成多条出库
|
|
|
|
String outCode = parentOutCode + "-" + childNum; |
|
|
|
for (StRealtimeStock maxStock : stockList) { |
|
|
|
preOutStock.setOutCode(outCode); |
|
|
|
if (remainNeed <= 0.001) { |
|
|
|
childNum++; |
|
|
|
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());
|
|
|
|
// preOutStock.setOutCode(stStockInoutRecordService.generateCode());
|
|
|
|
SubItemStockDTO currSub = sourceSubStockList.stream() |
|
|
|
preOutStock.setNeedQuantity(singleUse * totalNeedSet); |
|
|
|
.filter(s -> s.getSubGoodsCode().equals(temp.getSubGoodsCode())) |
|
|
|
preOutStock.setCompleteQuantity(totalNeed); |
|
|
|
.findFirst().get(); |
|
|
|
preOutStock.setGoodsId(maxStock.getGoodsId()); |
|
|
|
preOutStock.setNeedQuantity(currSub.getSingleUseQty() * totalNeedSet); |
|
|
|
StGoods stGoods = stGoodsService.getById(maxStock.getGoodsId()); |
|
|
|
preOutStock.setCompleteQuantity(takeQty); |
|
|
|
preOutStock.setGoodsName(stGoods.getGoodsName()); |
|
|
|
preOutStock.setGoodsId(maxStock.getGoodsId()); |
|
|
|
preOutStock.setGoodsCode(stGoods.getGoodsCode()); |
|
|
|
StGoods stGoods = stGoodsService.getById(maxStock.getGoodsId()); |
|
|
|
preOutStock.setSlId(maxStock.getSlId()); |
|
|
|
preOutStock.setGoodsName(stGoods.getGoodsName()); |
|
|
|
StStorageLocation location = stStorageLocationService.getById(maxStock.getSlId()); |
|
|
|
preOutStock.setGoodsCode(stGoods.getGoodsCode()); |
|
|
|
preOutStock.setLocation(location.getLocation()); |
|
|
|
preOutStock.setSlId(maxStock.getSlId()); |
|
|
|
preOutStock.setShId(maxStock.getShId()); |
|
|
|
StStorageLocation location = stStorageLocationService.getById(maxStock.getSlId()); |
|
|
|
StStorehouse storehouse = stStorehouseService.getById(maxStock.getShId()); |
|
|
|
preOutStock.setLocation(location.getLocation()); |
|
|
|
preOutStock.setShName(storehouse.getShName()); |
|
|
|
preOutStock.setShId(maxStock.getShId()); |
|
|
|
preOutStock.setRlsId(maxStock.getId()); |
|
|
|
StStorehouse storehouse = stStorehouseService.getById(maxStock.getShId()); |
|
|
|
preOutStock.setPiNo(maxStock.getPiNo()); |
|
|
|
preOutStock.setShName(storehouse.getShName()); |
|
|
|
|
|
|
|
preOutStock.setRlsId(maxStock.getId()); |
|
|
|
preOutStock.setCurStatus(0L); |
|
|
|
preOutStock.setPiNo(maxStock.getPiNo()); |
|
|
|
preOutStock.setCreateTime(now); |
|
|
|
|
|
|
|
preOutStock.setUpdateTime(now); |
|
|
|
preOutStock.setCurStatus(0L); |
|
|
|
|
|
|
|
preOutStock.setCreateTime(now); |
|
|
|
preOutStockList.add(preOutStock); |
|
|
|
preOutStock.setUpdateTime(now); |
|
|
|
System.out.println("石墨模子件[编码:" + preOutStock.getGoodsCode() + "]库存充足,已构建预出库信息,库存ID:" + maxStock.getId()); |
|
|
|
|
|
|
|
|
|
|
|
preOutStockList.add(preOutStock); |
|
|
|
// 更新实时库存占用数量
|
|
|
|
System.out.println("石墨模子件[编码:" + preOutStock.getGoodsCode() + "]库存充足,已构建预出库信息,库存ID:" + maxStock.getId()); |
|
|
|
maxStock.setOccupyQuantity(occupyQty + actualTake); |
|
|
|
|
|
|
|
stRealtimeStockService.updateById(maxStock); |
|
|
|
// 更新实时库存占用数量
|
|
|
|
|
|
|
|
double oldOccupy = Optional.ofNullable(maxStock.getOccupyQuantity()).orElse(0D); |
|
|
|
StRealtimeStockLock lock = new StRealtimeStockLock(); |
|
|
|
maxStock.setOccupyQuantity(oldOccupy + takeQty); |
|
|
|
lock.setId(IdUtil.getSnowflake().nextId()); |
|
|
|
stRealtimeStockService.updateById(maxStock); |
|
|
|
lock.setRlsId(maxStock.getId()); |
|
|
|
|
|
|
|
lock.setWoNo(preOutStock.getCardNo()); |
|
|
|
StRealtimeStockLock lock = new StRealtimeStockLock(); |
|
|
|
lock.setOccupyQuantity(actualTake); |
|
|
|
lock.setId(IdUtil.getSnowflake().nextId()); |
|
|
|
lock.setStatus(0); |
|
|
|
lock.setRlsId(maxStock.getId()); |
|
|
|
stRealtimeStockMapper.insertStockLock(lock); |
|
|
|
lock.setWoNo(preOutStock.getCardNo()); |
|
|
|
|
|
|
|
lock.setOccupyQuantity(takeQty); |
|
|
|
remainNeed -= actualTake; |
|
|
|
lock.setStatus(0); |
|
|
|
} |
|
|
|
stRealtimeStockMapper.insertStockLock(lock); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
System.out.println("石墨模子件预出库全部完成!"); |
|
|
|
System.out.println("石墨模子件预出库全部完成!"); |
|
|
|
|
|
|
|
|
|
|
|
|