add:增加出库分配支持同单分配到同一个托盘逻辑
fix:出库库存变动时如果库存数0则变成出库状态,不为0的为组盘状态等待后续走回库逻辑
This commit is contained in:
@@ -113,6 +113,8 @@ public interface IStructattrService extends IService<Structattr> {
|
||||
|
||||
/**
|
||||
* 生成库存变动记录表,更新载具冻结数量
|
||||
* 如果是拣选出库,则库存数为0的变成出库状态
|
||||
* 拣选的,扣减冻结数之后变成组盘状态,如果需要回库则通过余料回库回去
|
||||
* @param changeDto
|
||||
*/
|
||||
void changeStruct(StructattrChangeDto changeDto);
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
and ivt.lock_type = '0'
|
||||
and gro.frozen_qty = 0
|
||||
</if>
|
||||
<if test="inv_code != null and inv_code != ''">
|
||||
and gro.frozen_qty = 0 and ( ivt.lock_type = '0' or ivt.inv_code = #{inv_code})
|
||||
</if>
|
||||
<if test="order_by != null and order_by != ''">
|
||||
order by ${order_by}
|
||||
</if>
|
||||
|
||||
@@ -24,6 +24,10 @@ public class StrategyStructParam {
|
||||
* 同步单号
|
||||
*/
|
||||
private String ext_code;
|
||||
/**
|
||||
* 分配的单号
|
||||
*/
|
||||
private String inv_code;
|
||||
/**
|
||||
* 来源单据类型
|
||||
*/
|
||||
|
||||
@@ -313,6 +313,7 @@ public class StructattrServiceImpl extends ServiceImpl<StructattrMapper, Structa
|
||||
* @param param:根据库区,需要物料及数量,单据,批次分配具体货位
|
||||
* @return 返回结果为仓位--对应--货物组盘物料信息及出库冻结数量
|
||||
* 当前分配不会自动锁定货位及冻结出库数量,分配完成后需要手动锁定货位并冻结出库数量
|
||||
* 混料模式下,同一个出库单允许分配到同一个托盘上
|
||||
*/
|
||||
@Override
|
||||
public List<StrategyStructMaterialVO> outBoundSectDiv(StrategyStructParam param) {
|
||||
@@ -403,8 +404,11 @@ public class StructattrServiceImpl extends ServiceImpl<StructattrMapper, Structa
|
||||
.set("frozen_qty", 0)
|
||||
.set("qty", subtract)
|
||||
.set("update_time", now)
|
||||
.set("status", GROUP_PLATE_STATUS.code("组盘"))
|
||||
.set("status", GROUP_PLATE_STATUS.code("出库"))
|
||||
.eq("group_id", vehicleMater.getGroup_id());
|
||||
if (subtract.intValue()<=0){
|
||||
update.set("status", GROUP_PLATE_STATUS.code("出库"));
|
||||
}
|
||||
iMdPbGroupplateService.update(update);
|
||||
}
|
||||
StIvtStructivtflow record = new StIvtStructivtflow();
|
||||
|
||||
@@ -71,29 +71,29 @@ public class BigScreenServiceImpl implements BigScreenService {
|
||||
item.put("pointUse", pointUse(storCode));
|
||||
// //2.【实时库存分析】数据
|
||||
item.put("ivtAnalyse", ivtAnalyse(storCode));
|
||||
//3.【出入库趋势】数据
|
||||
//3.【出入库趋势】数据
|
||||
item.put("inAndOutTrend", inAndOutTrend(storCode));
|
||||
// //4.【今日出入库】数据
|
||||
item.put("toDayInAndOut", toDayInAndOut(storCode));
|
||||
// //5.【今日出入库】数据
|
||||
item.put("realTask", realTask(storCode));
|
||||
//6.【未完成单据】数据
|
||||
//6.【未完成单据】数据
|
||||
item.put("unIos", unIos(storCode));
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
//
|
||||
// * 货位使用
|
||||
// *
|
||||
// * @return JSONObject {
|
||||
// * total_qty: 总货位数
|
||||
// * use_qty: 已用货位
|
||||
// * emp_qty: 空余货位
|
||||
// * use_percentage: 百分比(使用货位百分比)
|
||||
// * }
|
||||
// */
|
||||
//
|
||||
// * 货位使用
|
||||
// *
|
||||
// * @return JSONObject {
|
||||
// * total_qty: 总货位数
|
||||
// * use_qty: 已用货位
|
||||
// * emp_qty: 空余货位
|
||||
// * use_percentage: 百分比(使用货位百分比)
|
||||
// * }
|
||||
// */
|
||||
private JSONObject pointUse(String storCode) {
|
||||
// 返回数据
|
||||
JSONObject result = new JSONObject();
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.nl.wms.decision_manage.service.strategyConfig.decisioner.impl.diy;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.nl.common.exception.BadRequestException;
|
||||
import org.nl.common.utils.MapOf;
|
||||
import org.nl.wms.basedata_manage.service.IStructattrService;
|
||||
import org.nl.wms.basedata_manage.service.dao.StructattrVechielDto;
|
||||
import org.nl.wms.basedata_manage.service.dto.StrategyMater;
|
||||
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
|
||||
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
|
||||
import org.nl.wms.decision_manage.service.strategyConfig.decisioner.Decisioner;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* @author ZZQ
|
||||
* @Date 2024/4/6 16:18
|
||||
* 先进先出策略(支持同单分配)
|
||||
*/
|
||||
@Service("fifo2")
|
||||
@Slf4j
|
||||
public class FIFO2RuleHandler extends Decisioner<StrategyStructMaterialVO, StrategyStructParam> {
|
||||
|
||||
/**
|
||||
* 出入库明细服务
|
||||
*/
|
||||
@Autowired
|
||||
private IStructattrService iStructattrService;
|
||||
|
||||
@Override
|
||||
public List<StrategyStructMaterialVO> handler(List<StrategyStructMaterialVO> list, StrategyStructParam param) {
|
||||
//分配数量
|
||||
//当前条件只有id,批次
|
||||
log.info("---------执行fifo出库分配规则相同单据允许分配在同一个货位---------");
|
||||
List<StrategyMater> maters = param.getStrategyMaters();
|
||||
StrategyMater strategyMater = maters.get(0);
|
||||
BigDecimal planQty = strategyMater.getQty();
|
||||
List<StructattrVechielDto> vechielDtos =
|
||||
iStructattrService.collectVechicle(MapOf.of("material_id", strategyMater.getMaterial_id()
|
||||
, "pcsn", strategyMater.getPcsn()
|
||||
, "inv_code", param.getInv_code()
|
||||
, "stor_code", param.getStor_code()
|
||||
, "sect_code", param.getSect_code()
|
||||
, "plan_qty", planQty
|
||||
, "order_by", "gro.update_time asc")
|
||||
);
|
||||
if (ObjectUtils.isEmpty(vechielDtos)) {
|
||||
throw new BadRequestException("当前出库策略:先进先出,库存分配失败,失败原因:库存不足!");
|
||||
}
|
||||
List<StrategyStructMaterialVO> divStruct = new ArrayList<>();
|
||||
for (StructattrVechielDto vechielDto : vechielDtos) {
|
||||
if (planQty.intValue()<=0){
|
||||
break;
|
||||
}
|
||||
BigDecimal qty = vechielDto.getQty();
|
||||
BigDecimal subQty = planQty.subtract(qty);
|
||||
if (subQty.doubleValue()>=0){
|
||||
vechielDto.setFrozen_qty(vechielDto.getQty());
|
||||
}else {
|
||||
vechielDto.setFrozen_qty(planQty);
|
||||
}
|
||||
planQty=subQty;
|
||||
StrategyStructMaterialVO materialVO = new StrategyStructMaterialVO();
|
||||
BeanUtils.copyProperties(vechielDto,materialVO);
|
||||
divStruct.add(materialVO);
|
||||
}
|
||||
return divStruct;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import java.util.stream.Collectors;
|
||||
* @Date 2025/2/1 16:18
|
||||
* 相同巷道,自下而上分配,左右相邻
|
||||
*/
|
||||
@Service("sameBlockNum")
|
||||
//@Service("sameBlockNum")
|
||||
@Slf4j
|
||||
public class SameBlockNumRuleHandler extends Decisioner<Structattr, JSONObject> {
|
||||
|
||||
|
||||
@@ -563,6 +563,7 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
||||
StrategyStructParam.builder()
|
||||
.stor_code(ioStorInv.getStor_code())
|
||||
.sect_code(sectCode)
|
||||
.inv_code(ioStorInv.getBill_code())
|
||||
.strategyMaters(list)
|
||||
.build()
|
||||
);
|
||||
@@ -921,21 +922,18 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void allSetPoint(JSONObject whereJson) {
|
||||
//出库点
|
||||
String point_code = whereJson.getString("point_code");
|
||||
|
||||
if (StrUtil.isBlank(point_code)){
|
||||
if (StrUtil.isBlank(whereJson.getString("point_code"))){
|
||||
throw new BadRequestException("未选择出库点");
|
||||
}
|
||||
String iostorinv_id = whereJson.getString("iostorinv_id");
|
||||
|
||||
//查询主表信息
|
||||
IOStorInv ioStorInv = ioStorInvMapper.selectById(iostorinv_id);
|
||||
if (ObjectUtil.isEmpty(ioStorInv)) {
|
||||
throw new BadRequestException("未查到相关出库单");
|
||||
}
|
||||
|
||||
List<IOStorInvDis> ioStorInvDisList = ioStorInvDisMapper.selectList(new LambdaQueryWrapper<>(IOStorInvDis.class)
|
||||
.eq(IOStorInvDis::getIostorinv_id,iostorinv_id)
|
||||
.eq(IOStorInvDis::getIs_issued,BaseDataEnum.IS_YES_NOT.code("否"))
|
||||
@@ -944,28 +942,30 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
||||
if (ObjectUtil.isEmpty(ioStorInvDisList)){
|
||||
throw new BadRequestException("当前没有可设置的分配明细");
|
||||
}
|
||||
|
||||
for (IOStorInvDis ioStorInvDis:ioStorInvDisList){
|
||||
//分配明细中同分配到同载具的进行合并
|
||||
Map<String, List<IOStorInvDis>> groupDis = ioStorInvDisList.stream().collect(Collectors.groupingBy(dis -> dis.getStoragevehicle_code()));
|
||||
for (String storageVehicleCode : groupDis.keySet()) {
|
||||
List<IOStorInvDis> disList = groupDis.get(storageVehicleCode);
|
||||
IOStorInvDis item = disList.get(0);
|
||||
//创建任务
|
||||
JSONObject task_form = new JSONObject();
|
||||
task_form.put("task_type", "STOutTask");
|
||||
task_form.put("TaskCode",CodeUtil.getNewCode("TASK_CODE"));
|
||||
task_form.put("PickingLocation", ioStorInvDis.getStruct_code());
|
||||
task_form.put("PlacedLocation", point_code);
|
||||
task_form.put("vehicle_code", ioStorInvDis.getStoragevehicle_code());
|
||||
|
||||
task_form.put("PickingLocation", item.getStruct_code());
|
||||
task_form.put("PlacedLocation", whereJson.getString("point_code"));
|
||||
task_form.put("vehicle_code", item.getStoragevehicle_code());
|
||||
StOutTask stOutTask = SpringContextHolder.getBean("STOutTask");
|
||||
|
||||
String task_id = stOutTask.create(task_form);
|
||||
|
||||
//分配明细表更新任务相关数据
|
||||
IOStorInvDis dis = new IOStorInvDis();
|
||||
dis.setIostorinvdis_id(ioStorInvDis.getIostorinvdis_id());
|
||||
dis.setWork_status(IOSEnum.INBILL_DIS_STATUS.code("生成"));
|
||||
dis.setTask_id(task_id);
|
||||
dis.setIs_issued(BaseDataEnum.IS_YES_NOT.code("是"));
|
||||
dis.setPoint_code(point_code);
|
||||
ioStorInvDisMapper.updateById(dis);
|
||||
for (IOStorInvDis itemDis : disList) {
|
||||
//分配明细表更新任务相关数据
|
||||
IOStorInvDis dis = new IOStorInvDis();
|
||||
dis.setIostorinvdis_id(itemDis.getIostorinvdis_id());
|
||||
dis.setWork_status(IOSEnum.INBILL_DIS_STATUS.code("生成"));
|
||||
dis.setTask_id(task_id);
|
||||
dis.setIs_issued(BaseDataEnum.IS_YES_NOT.code("是"));
|
||||
dis.setPoint_code(whereJson.getString("point_code"));
|
||||
ioStorInvDisMapper.updateById(dis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,20 +1103,22 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
||||
String currentUserId = SecurityUtils.getCurrentUserId();
|
||||
String nickName = SecurityUtils.getCurrentNickName();
|
||||
String now = DateUtil.now();
|
||||
IOStorInvDis ioStorInvDis = ioStorInvDisMapper.selectOne(new LambdaQueryWrapper<>(IOStorInvDis.class)
|
||||
List<IOStorInvDis> disList = ioStorInvDisMapper.selectList(new LambdaQueryWrapper<>(IOStorInvDis.class)
|
||||
.eq(IOStorInvDis::getTask_id, task.getTask_id())
|
||||
);
|
||||
if (ObjectUtil.isEmpty(ioStorInvDis)) {
|
||||
if (ObjectUtil.isEmpty(disList)) {
|
||||
throw new BadRequestException("未找到任务对应的分配明细");
|
||||
}
|
||||
// 完成当前分配明细
|
||||
ioStorInvDisMapper.update(ioStorInvDis,new LambdaUpdateWrapper<>(IOStorInvDis.class)
|
||||
.set(IOStorInvDis::getWork_status,IOSEnum.INBILL_DIS_STATUS.code("完成"))
|
||||
.eq(IOStorInvDis::getIostorinvdis_id,ioStorInvDis.getIostorinvdis_id())
|
||||
);
|
||||
// 完成当前任务对应的所有分配明细
|
||||
for (IOStorInvDis ioStorInvDis : disList) {
|
||||
ioStorInvDisMapper.update(ioStorInvDis,new LambdaUpdateWrapper<>(IOStorInvDis.class)
|
||||
.set(IOStorInvDis::getWork_status,IOSEnum.INBILL_DIS_STATUS.code("完成"))
|
||||
.eq(IOStorInvDis::getIostorinvdis_id,ioStorInvDis.getIostorinvdis_id()));
|
||||
}
|
||||
IOStorInvDis item = disList.get(0);
|
||||
//解锁库位
|
||||
JSONObject finish_map = new JSONObject();
|
||||
finish_map.put("struct_code",ioStorInvDis.getStruct_code());
|
||||
finish_map.put("struct_code", item.getStruct_code());
|
||||
finish_map.put("storagevehicle_code",null);
|
||||
finish_map.put("inv_type", null);
|
||||
finish_map.put("inv_id", null);
|
||||
@@ -1124,17 +1126,17 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
||||
iStructattrService.updateStatusByCode("1",finish_map);
|
||||
//库存变动:根据冻结数更新物料库存
|
||||
StructattrChangeDto changeDto = StructattrChangeDto.builder()
|
||||
.inv(ioStorInvDis.getIostorinv_id())
|
||||
.storagevehicleCode(ioStorInvDis.getStoragevehicle_code())
|
||||
.structCode(ioStorInvDis.getStruct_code()).taskType(task.getConfig_code()).inBound(false).build();
|
||||
.inv(item.getIostorinv_id())
|
||||
.storagevehicleCode(item.getStoragevehicle_code())
|
||||
.structCode(item.getStruct_code()).taskType(task.getConfig_code()).inBound(false).build();
|
||||
iStructattrService.changeStruct(changeDto);
|
||||
// 查询该明细下是否还有未完成的分配明细
|
||||
int countDis = ioStorInvDisMapper.selectCount(new LambdaQueryWrapper<>(IOStorInvDis.class)
|
||||
.eq(IOStorInvDis::getIostorinvdtl_id,ioStorInvDis.getIostorinvdtl_id())
|
||||
.eq(IOStorInvDis::getIostorinvdtl_id,item.getIostorinvdtl_id())
|
||||
.ne(IOStorInvDis::getWork_status,IOSEnum.INBILL_DIS_STATUS.code("完成"))
|
||||
);
|
||||
// 明细
|
||||
IOStorInvDtl ioStorInvDtl = ioStorInvDtlMapper.selectById(ioStorInvDis.getIostorinvdtl_id());
|
||||
IOStorInvDtl ioStorInvDtl = ioStorInvDtlMapper.selectById(item.getIostorinvdtl_id());
|
||||
if (ObjectUtil.isEmpty(ioStorInvDtl)){
|
||||
throw new BadRequestException("未找到明细");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user