forked from I3-YF/i3plus-mes-pcn-yfai
工步弹框
parent
641c881f94
commit
377e8aa2e9
@ -0,0 +1,344 @@
|
||||
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
|
||||
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesAssemblyExtService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
|
||||
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService;
|
||||
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
|
||||
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
|
||||
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesCraftRouteDetail;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
||||
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description : 前道工艺防错工步
|
||||
* @Author : wangjie
|
||||
**/
|
||||
@Slf4j
|
||||
@Service("mesProdCraftRouteCheckStepService")
|
||||
public class MesProdCraftRouteCheckStepService extends BaseStepService {
|
||||
|
||||
@Autowired
|
||||
private IMesProductionProcessContextStepService productionProcessContextStepService;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionRecordService productionRecordService;
|
||||
|
||||
@Autowired
|
||||
private IFsmRouteDataService fsmRouteDataService;
|
||||
|
||||
@Autowired
|
||||
private IMesAssemblyExtService assemblyExtService;
|
||||
|
||||
@Override
|
||||
public StepResult execute(StationRequestBean reqBean) {
|
||||
|
||||
StationResultBean resultBean = new StationResultBean();
|
||||
|
||||
StepResult stepResult = StepResult.getSuccessComplete();
|
||||
|
||||
//获取上下文信息
|
||||
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
|
||||
|
||||
//获取生产过程上下文对象有异常信息 抛出异常
|
||||
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
|
||||
|
||||
//存储生产过程上下文对象
|
||||
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
|
||||
|
||||
//获取进料主条码数据信息
|
||||
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
|
||||
|
||||
if (CollectionUtils.isEmpty(productionPsInContextList)) return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前无主条码信息,无需进行前道工艺防错验证!");
|
||||
|
||||
//验证是否存在自制件
|
||||
if (!isExistProductSn(productionPsInContextList))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前主条码信息均为外协件,无需进行前道工艺防错验证!");
|
||||
|
||||
//验证工位是否设置需要前道防错
|
||||
if (!isNeedCheckCraft(productionPsInContextList))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("生产线[%s]工位[%s]未设置前道工艺防错,无需进行前道工艺防错验证!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()));
|
||||
|
||||
//验证是否存在工艺强过码, 存在则保存 并返回强过的主条码
|
||||
List<String> productSnList2Jump = doHandleCraftJumpCode(reqBean, productionPsInContextList);
|
||||
if (!CollectionUtils.isEmpty(productSnList2Jump))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList2Jump.toString()), stepResult, String.format("主条码%s跳过前道工艺防错验证成功!", productSnList2Jump.toString()));
|
||||
|
||||
List<String> partNoList = (productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()) &&
|
||||
o.getCheckCraftResult().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) != 0)).map(MesProductionPsInContext::getPartNo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(partNoList)) return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean, stepResult, "主条码均已通过前道工艺防错验证!");
|
||||
|
||||
//从上下文中取出生产线对象
|
||||
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
|
||||
|
||||
//查询工艺路线数据
|
||||
Map<String, List<MesCraftRouteDetail>> craftRouteDataMap = new HashMap<>();
|
||||
partNoList.forEach(o -> handleProdCraftData(reqBean, workCenter, o, craftRouteDataMap));
|
||||
|
||||
if (CollectionUtils.isEmpty(craftRouteDataMap) || craftRouteDataMap.size() != partNoList.size()) {
|
||||
//剔除未验证的进料主条码后保存数据
|
||||
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.toList()));
|
||||
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("零件编码%s未匹配到产品工艺路线!",
|
||||
CollectionUtils.isEmpty(craftRouteDataMap) ? partNoList.toString() : partNoList.stream().filter(o -> (!StringUtils.isEmpty(o) && !craftRouteDataMap.containsKey(o))).collect(Collectors.toList()).toString()));
|
||||
}
|
||||
|
||||
//前道工艺防错验证处理
|
||||
doHandleProdCraftRouteCheck(reqBean, resultBean, stepResult, productionProcessContext, workCenter, productionPsInContextList, craftRouteDataMap);
|
||||
|
||||
return stepResult;
|
||||
|
||||
}
|
||||
|
||||
//验证是否存在自制件
|
||||
private Boolean isExistProductSn(List<MesProductionPsInContext> productionPsInContextList) {
|
||||
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()))).findFirst();
|
||||
return (null == optional || !optional.isPresent()) ? false : true;
|
||||
}
|
||||
|
||||
//验证工位是否设置需要前道防错
|
||||
private Boolean isNeedCheckCraft(List<MesProductionPsInContext> productionPsInContextList) {
|
||||
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o &&
|
||||
o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && o.getIsCheckCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0)).findFirst();
|
||||
return (null == optional || !optional.isPresent()) ? false : true;
|
||||
}
|
||||
|
||||
//查询工艺路线数据
|
||||
private void handleProdCraftData(StationRequestBean reqBean, MesWorkCenter workCenter, String partNo, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
|
||||
List<MesCraftRouteDetail> craftRouteDetailList = fsmRouteDataService.handleProdCraftData(reqBean, workCenter.getCenterType(), partNo);
|
||||
if (!CollectionUtils.isEmpty(craftRouteDetailList)) craftRouteDataMap.put(partNo, craftRouteDetailList);
|
||||
}
|
||||
|
||||
//验证是否存在工艺强过码, 存在则保存 并返回强过的主条码
|
||||
private List<String> doHandleCraftJumpCode(StationRequestBean reqBean, List<MesProductionPsInContext> productionPsInContextList) {
|
||||
|
||||
List<String> productSnList2Jump = null;
|
||||
|
||||
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
|
||||
|
||||
if (null == productionPsInContext || productionPsInContext.getCheckCraftResult().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) != 0 || StringUtils.isEmpty(productionPsInContext.getCraftJumpCode())) continue;
|
||||
|
||||
if (CollectionUtils.isEmpty(productSnList2Jump)) productSnList2Jump = new ArrayList<>();
|
||||
|
||||
productSnList2Jump.add(productionPsInContext.getProductSn());
|
||||
|
||||
productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
|
||||
|
||||
}
|
||||
|
||||
//保存进料主条码数据
|
||||
if (!CollectionUtils.isEmpty(productSnList2Jump)) productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
|
||||
|
||||
return productSnList2Jump;
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证处理
|
||||
private void doHandleProdCraftRouteCheck(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext,
|
||||
MesWorkCenter workCenter, List<MesProductionPsInContext> productionPsInContextList, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
|
||||
|
||||
List<String> productSnList = new ArrayList<>();
|
||||
|
||||
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
|
||||
|
||||
if (null == productionPsInContext || StringUtils.isEmpty(productionPsInContext.getPartNo()) || productionPsInContext.getCheckCraftResult().compareTo(MesPcnExtConstWords.ZERO) != 0) continue;
|
||||
|
||||
//前道工艺防错验证
|
||||
Boolean result = doProdCraftRouteCheck(reqBean, stepResult, productionProcessContext, workCenter, productionPsInContext, craftRouteDataMap.get(productionPsInContext.getPartNo()));
|
||||
|
||||
if (!result) productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
|
||||
else productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
|
||||
|
||||
productSnList.add(productionPsInContext.getProductSn());
|
||||
|
||||
}
|
||||
|
||||
//保存进料主条码数据
|
||||
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
|
||||
|
||||
if (stepResult.isCompleted()) this.sendMessage(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), String.format("主条码%s前道工艺防错验证成功!", productSnList), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
|
||||
else this.sendMessage(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult.getMsg(), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证
|
||||
private Boolean doProdCraftRouteCheck(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesWorkCenter workCenter, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
//排序
|
||||
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.SORT.getValue()) == 0) return doProdCraftRouteCheckSort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
|
||||
|
||||
//非排序
|
||||
return doProdCraftRouteCheckNosort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证【排序】
|
||||
private Boolean doProdCraftRouteCheckSort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
|
||||
|
||||
//判断主条码的当前工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalPs = StringUtils.isEmpty(productionPsInContext.getCraftCode()) ? null : craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (!StringUtils.isEmpty(productionPsInContext.getCraftCode()) && (null == optionalPs || !optionalPs.isPresent()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]对应的工艺代码[%s]不匹配零件[%s]对应的产品工艺路线[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getCraftCode(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode())).isCompleted();
|
||||
|
||||
//判断当前工位的工序对应的工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst();
|
||||
if (null == optionalCell || !optionalCell.isPresent())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]零件[%s]对应的产品工艺路线[%s]不包含当前工位[%s]对应的工艺[%s]工序[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//验证工艺对应工序最多经过1个: 当前主条码的工艺字段有值, 对应的工艺路线明细信息设置了【true】, 当前工位的工艺与主条码的当前工艺相同, 当前工位的工序与主条码的当前工序不相同
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getAtMostProcess().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()) && !reqBean.getProcessCode().equals(productionPsInContext.getProcessCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]相同工艺对应工序最多经过1个,上道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//验证是否捆绑后道工艺: 如果当前工位的工艺与主条码的当前工艺不一致的情况下, 根据主条码的当前工艺获取在工艺路线明细的下一个工艺, 判断当前工位的工艺与下个工艺是否一致
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getIsBindNextCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && !productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode())) {
|
||||
Optional<MesCraftRouteDetail> optional = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalPs.get().getSeq()) > 0)).findFirst();
|
||||
if (null != optionalCell && optionalCell.isPresent() && !productionProcessContext.getCraftCode().equals(optional.get().getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]捆绑后道工艺,上道工艺[%s]下道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), optional.get().getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
}
|
||||
|
||||
//验证已完成工序最大重复次数: 如果当前工位的工序与主条码的当前工序一致的情况下, 根据条码+物料+工序+工艺查询加工记录, 判断加工记录条数
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())) {
|
||||
List<MesProductionRecord> productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), reqBean.getProcessCode(), productionProcessContext.getCraftCode());
|
||||
if (!CollectionUtils.isEmpty(productionRecordList) && productionRecordList.size() >= optionalPs.get().getRepeatTimes())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]当前工序[%s]产品工艺路线[%s]已完成工序最大重复次数[%s]",
|
||||
message, productionPsInContext.getProductSn(), reqBean.getProcessCode(), craftRouteDetailList.get(0).getCraftRouteCode(), optionalPs.get().getRepeatTimes())).isCompleted();
|
||||
}
|
||||
|
||||
//根据当前工位对应的工艺 获取 所有前道工艺
|
||||
List<MesCraftRouteDetail> beforeCellCraftList = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalCell.get().getSeq()) < 0)).collect(Collectors.toList());
|
||||
|
||||
//验证首工艺: 当前主条码的工艺字段有值,并且当前工位的工艺不等于主条码的当前工艺。 如果等于已经在【验证工艺对应工序最多经过1个】与【 验证已完成工序最大重复次数】 中验证通过,所以这边只考虑不相等
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList) && !StringUtils.isEmpty(productionPsInContext.getCraftCode()) && !productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]已经过首道工艺[%s]", message, productionPsInContext.getProductSn(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//执行首道工艺 当前主条码验证通过
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList)) return true;
|
||||
|
||||
//当前主条码的工艺字段为空 验证首工艺是否存在工单装配件信息
|
||||
if (StringUtils.isEmpty(productionPsInContext.getCraftCode()) && craftRouteDetailList.get(0).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && checkIsExistWorkOrderAssembly(productionPsInContext, craftRouteDetailList.get(0).getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过首道工艺[%s]", message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftCode())).isCompleted();
|
||||
|
||||
//搜集主条码当前工艺于当前工位对应工艺之间的未完成的工艺集合
|
||||
List<MesCraftRouteDetail> unCompleteCraftList;
|
||||
if (StringUtils.isEmpty(productionPsInContext.getCraftCode())) unCompleteCraftList = beforeCellCraftList;
|
||||
else {
|
||||
Optional<MesCraftRouteDetail> optional = beforeCellCraftList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (null == optional || !optional.isPresent()) //在工位对应的工艺之前的所有前道工艺中未找到主条码的当前工艺则表示主条码已经过当前工艺
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]已经过当前工艺[%s]", message, productionPsInContext.getProductSn(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
unCompleteCraftList = beforeCellCraftList.stream().filter(o -> (null != o && o.getSeq().compareTo(optional.get().getSeq()) > 0)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
//如果没有未完成的工艺, 则代表当前工位可操作
|
||||
if (CollectionUtils.isEmpty(unCompleteCraftList)) return true;
|
||||
|
||||
//未完成工艺倒序
|
||||
unCompleteCraftList = unCompleteCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq).reversed()).collect(Collectors.toList());
|
||||
|
||||
//验证未完成工艺是否存在工单装配件信息
|
||||
Optional<MesCraftRouteDetail> optional = unCompleteCraftList.stream().filter(o -> (null != o && o.getIsChoose() == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue())).findFirst();
|
||||
if (unCompleteCraftList.get(0).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && checkIsExistWorkOrderAssembly(productionPsInContext, unCompleteCraftList.get(0).getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), unCompleteCraftList.get(0).getCraftCode())).isCompleted();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//验证工艺是否存在工单装配件信息
|
||||
private Boolean checkIsExistWorkOrderAssembly(MesProductionPsInContext productionPsInContext, String craftCode) {
|
||||
return !CollectionUtils.isEmpty(assemblyExtService.getWorkOrderAssemblyList(productionPsInContext.getOrganizeCode(), productionPsInContext.getWorkOrderNo(), productionPsInContext.getProductSn(), craftCode)) ? true : false;
|
||||
}
|
||||
|
||||
//前道工艺防错验证 【非排序】
|
||||
private Boolean doProdCraftRouteCheckNosort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
|
||||
|
||||
//判断主条码的当前工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalPs = StringUtils.isEmpty(productionPsInContext.getCraftCode()) ? null : craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (!StringUtils.isEmpty(productionPsInContext.getCraftCode()) && (null == optionalPs || !optionalPs.isPresent()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]对应的工艺代码[%s]不匹配零件[%s]对应的产品工艺路线[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getCraftCode(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode())).isCompleted();
|
||||
|
||||
//验证工艺对应工序最多经过1个: 当前主条码的工艺字段有值, 对应的工艺路线明细信息设置了【true】, 当前工位的工艺与主条码的当前工艺相同, 当前工位的工序与主条码的当前工序不相同
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getAtMostProcess().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()) && !reqBean.getProcessCode().equals(productionPsInContext.getProcessCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]相同工艺对应工序最多经过1个,上道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
List<MesProductionRecord> productionRecordList = null;
|
||||
//验证已完成工序最大重复次数: 如果当前工位的工序与主条码的当前工序一致的情况下, 根据条码+物料+工序+工艺查询加工记录, 判断加工记录条数
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())) {
|
||||
//根据零件条码查询加工记录信息
|
||||
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
|
||||
//条码+物料+工序+工艺搜集加工记录
|
||||
List<MesProductionRecord> filterList = CollectionUtils.isEmpty(productionRecordList) ? null :
|
||||
productionRecordList.stream().filter(o -> (null != o && o.getPartNo().equals(productionPsInContext.getPartNo()) && o.getProcessCode().equals(reqBean.getProcessCode()) && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).collect(Collectors.toList());
|
||||
if (!CollectionUtils.isEmpty(filterList) && filterList.size() >= optionalPs.get().getRepeatTimes())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]当前工序[%s]产品工艺路线[%s]已完成工序最大重复次数[%s]",
|
||||
message, productionPsInContext.getProductSn(), reqBean.getProcessCode(), craftRouteDetailList.get(0).getCraftRouteCode(), optionalPs.get().getRepeatTimes())).isCompleted();
|
||||
}
|
||||
|
||||
//判断当前工位的工序对应的工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst();
|
||||
//根据当前工位对应的工艺 获取 所有前道工艺, 如果当前工位的工序对应工艺不在工艺路线明细内, 则默认所有明细均为所有前道工艺, 否则搜集当前工位工序对应工艺前面的所有前道工艺
|
||||
List<MesCraftRouteDetail> beforeCellCraftList;
|
||||
if (null == optionalCell || !optionalCell.isPresent()) beforeCellCraftList = craftRouteDetailList;
|
||||
else beforeCellCraftList = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalCell.get().getSeq()) < 0)).collect(Collectors.toList());
|
||||
|
||||
//前道工艺不存在即当前为首道工艺
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList)) return true;
|
||||
|
||||
//前道工艺正序
|
||||
beforeCellCraftList = beforeCellCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq)).collect(Collectors.toList());
|
||||
|
||||
//判断上面是否已经查询过数据
|
||||
if (!(null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())))
|
||||
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
|
||||
|
||||
Map<String, List<MesProductionRecord>> prMapByCraft = CollectionUtils.isEmpty(productionRecordList) ? null : productionRecordList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProductionRecord::getCraftCode));
|
||||
|
||||
//遍历前道工艺, 根据工艺查询加工记录是否存在, 并验证是否存在捆绑工艺
|
||||
for (int i = 0; i < beforeCellCraftList.size(); i ++) {
|
||||
if (null == beforeCellCraftList.get(i)) continue;
|
||||
Boolean isExist = isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i).getCraftCode());
|
||||
if (beforeCellCraftList.get(i).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && !isExist)
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftCode())).isCompleted();
|
||||
|
||||
if (i != 0 && beforeCellCraftList.get(i - 1).getIsBindNextCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i - 1).getCraftCode()) && !isExist)
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]工艺[%s]捆绑后道工艺",
|
||||
message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftRouteCode(), beforeCellCraftList.get(i - 1).getCraftCode())).isCompleted();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private Boolean isExistProductionRecord(Map<String, List<MesProductionRecord>> prMapByCraft, String craftCode) {
|
||||
return (CollectionUtils.isEmpty(prMapByCraft) || !prMapByCraft.containsKey(craftCode)) ? false : true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
|
||||
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesAssemblyExtService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
|
||||
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService;
|
||||
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
|
||||
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
|
||||
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesCraftRouteDetail;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
||||
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description : 前道工艺防错工步
|
||||
* @Author : wangjie
|
||||
**/
|
||||
@Slf4j
|
||||
@Service("mesProdCraftRouteCheckStepService")
|
||||
public class MesProdCraftRouteCheckStepService extends BaseStepService {
|
||||
|
||||
@Autowired
|
||||
private IMesProductionProcessContextStepService productionProcessContextStepService;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionRecordService productionRecordService;
|
||||
|
||||
@Autowired
|
||||
private IFsmRouteDataService fsmRouteDataService;
|
||||
|
||||
@Autowired
|
||||
private IMesAssemblyExtService assemblyExtService;
|
||||
|
||||
@Override
|
||||
public StepResult execute(StationRequestBean reqBean) {
|
||||
|
||||
StationResultBean resultBean = new StationResultBean();
|
||||
|
||||
StepResult stepResult = StepResult.getSuccessComplete();
|
||||
|
||||
//获取上下文信息
|
||||
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
|
||||
|
||||
//获取生产过程上下文对象有异常信息 抛出异常
|
||||
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
|
||||
|
||||
//存储生产过程上下文对象
|
||||
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
|
||||
|
||||
//获取进料主条码数据信息
|
||||
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
|
||||
|
||||
if (CollectionUtils.isEmpty(productionPsInContextList)) return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前无主条码信息,无需进行前道工艺防错验证!");
|
||||
|
||||
//验证是否存在自制件
|
||||
if (!isExistProductSn(productionPsInContextList))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前主条码信息均为外协件,无需进行前道工艺防错验证!");
|
||||
|
||||
//验证工位是否设置需要前道防错
|
||||
if (!isNeedCheckCraft(productionPsInContextList))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("生产线[%s]工位[%s]未设置前道工艺防错,无需进行前道工艺防错验证!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()));
|
||||
|
||||
//验证是否存在工艺强过码, 存在则保存 并返回强过的主条码
|
||||
List<String> productSnList2Jump = doHandleCraftJumpCode(reqBean, productionPsInContextList);
|
||||
if (!CollectionUtils.isEmpty(productSnList2Jump))
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList2Jump.toString()), stepResult, String.format("主条码%s跳过前道工艺防错验证成功!", productSnList2Jump.toString()));
|
||||
|
||||
List<String> partNoList = (productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()) &&
|
||||
o.getCheckCraftResult().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) != 0)).map(MesProductionPsInContext::getPartNo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(partNoList)) return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean, stepResult, "主条码均已通过前道工艺防错验证!");
|
||||
|
||||
//从上下文中取出生产线对象
|
||||
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
|
||||
|
||||
//查询工艺路线数据
|
||||
Map<String, List<MesCraftRouteDetail>> craftRouteDataMap = new HashMap<>();
|
||||
partNoList.forEach(o -> handleProdCraftData(reqBean, workCenter, o, craftRouteDataMap));
|
||||
|
||||
if (CollectionUtils.isEmpty(craftRouteDataMap) || craftRouteDataMap.size() != partNoList.size()) {
|
||||
//剔除未验证的进料主条码后保存数据
|
||||
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.toList()));
|
||||
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("零件编码%s未匹配到产品工艺路线!",
|
||||
CollectionUtils.isEmpty(craftRouteDataMap) ? partNoList.toString() : partNoList.stream().filter(o -> (!StringUtils.isEmpty(o) && !craftRouteDataMap.containsKey(o))).collect(Collectors.toList()).toString()));
|
||||
}
|
||||
|
||||
//前道工艺防错验证处理
|
||||
doHandleProdCraftRouteCheck(reqBean, resultBean, stepResult, productionProcessContext, workCenter, productionPsInContextList, craftRouteDataMap);
|
||||
|
||||
return stepResult;
|
||||
|
||||
}
|
||||
|
||||
//验证是否存在自制件
|
||||
private Boolean isExistProductSn(List<MesProductionPsInContext> productionPsInContextList) {
|
||||
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()))).findFirst();
|
||||
return (null == optional || !optional.isPresent()) ? false : true;
|
||||
}
|
||||
|
||||
//验证工位是否设置需要前道防错
|
||||
private Boolean isNeedCheckCraft(List<MesProductionPsInContext> productionPsInContextList) {
|
||||
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o &&
|
||||
o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && o.getIsCheckCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0)).findFirst();
|
||||
return (null == optional || !optional.isPresent()) ? false : true;
|
||||
}
|
||||
|
||||
//查询工艺路线数据
|
||||
private void handleProdCraftData(StationRequestBean reqBean, MesWorkCenter workCenter, String partNo, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
|
||||
List<MesCraftRouteDetail> craftRouteDetailList = fsmRouteDataService.handleProdCraftData(reqBean, workCenter.getCenterType(), partNo);
|
||||
if (!CollectionUtils.isEmpty(craftRouteDetailList)) craftRouteDataMap.put(partNo, craftRouteDetailList);
|
||||
}
|
||||
|
||||
//验证是否存在工艺强过码, 存在则保存 并返回强过的主条码
|
||||
private List<String> doHandleCraftJumpCode(StationRequestBean reqBean, List<MesProductionPsInContext> productionPsInContextList) {
|
||||
|
||||
List<String> productSnList2Jump = null;
|
||||
|
||||
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
|
||||
|
||||
if (null == productionPsInContext || productionPsInContext.getCheckCraftResult().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) != 0 || StringUtils.isEmpty(productionPsInContext.getCraftJumpCode())) continue;
|
||||
|
||||
if (CollectionUtils.isEmpty(productSnList2Jump)) productSnList2Jump = new ArrayList<>();
|
||||
|
||||
productSnList2Jump.add(productionPsInContext.getProductSn());
|
||||
|
||||
productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
|
||||
|
||||
}
|
||||
|
||||
//保存进料主条码数据
|
||||
if (!CollectionUtils.isEmpty(productSnList2Jump)) productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
|
||||
|
||||
return productSnList2Jump;
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证处理
|
||||
private void doHandleProdCraftRouteCheck(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext,
|
||||
MesWorkCenter workCenter, List<MesProductionPsInContext> productionPsInContextList, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
|
||||
|
||||
List<String> productSnList = new ArrayList<>();
|
||||
|
||||
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
|
||||
|
||||
if (null == productionPsInContext || StringUtils.isEmpty(productionPsInContext.getPartNo()) || productionPsInContext.getCheckCraftResult().compareTo(MesPcnExtConstWords.ZERO) != 0) continue;
|
||||
|
||||
//前道工艺防错验证
|
||||
Boolean result = doProdCraftRouteCheck(reqBean, stepResult, productionProcessContext, workCenter, productionPsInContext, craftRouteDataMap.get(productionPsInContext.getPartNo()));
|
||||
|
||||
if (!result) productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
|
||||
else productionPsInContext.checkCraftResult(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
|
||||
|
||||
productSnList.add(productionPsInContext.getProductSn());
|
||||
|
||||
}
|
||||
|
||||
//保存进料主条码数据
|
||||
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList);
|
||||
|
||||
if (stepResult.isCompleted()) this.sendMessage(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), String.format("主条码%s前道工艺防错验证成功!", productSnList), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
|
||||
else this.sendMessage(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult.getMsg(), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证
|
||||
private Boolean doProdCraftRouteCheck(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesWorkCenter workCenter, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
//排序
|
||||
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.SORT.getValue()) == 0) return doProdCraftRouteCheckSort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
|
||||
|
||||
//非排序
|
||||
return doProdCraftRouteCheckNosort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
|
||||
|
||||
}
|
||||
|
||||
//前道工艺防错验证【排序】
|
||||
private Boolean doProdCraftRouteCheckSort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
|
||||
|
||||
//判断主条码的当前工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalPs = StringUtils.isEmpty(productionPsInContext.getCraftCode()) ? null : craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (!StringUtils.isEmpty(productionPsInContext.getCraftCode()) && (null == optionalPs || !optionalPs.isPresent()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]对应的工艺代码[%s]不匹配零件[%s]对应的产品工艺路线[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getCraftCode(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode())).isCompleted();
|
||||
|
||||
//判断当前工位的工序对应的工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst();
|
||||
if (null == optionalCell || !optionalCell.isPresent())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]零件[%s]对应的产品工艺路线[%s]不包含当前工位[%s]对应的工艺[%s]工序[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//验证工艺对应工序最多经过1个: 当前主条码的工艺字段有值, 对应的工艺路线明细信息设置了【true】, 当前工位的工艺与主条码的当前工艺相同, 当前工位的工序与主条码的当前工序不相同
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getAtMostProcess().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()) && !reqBean.getProcessCode().equals(productionPsInContext.getProcessCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]相同工艺对应工序最多经过1个,上道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//验证是否捆绑后道工艺: 如果当前工位的工艺与主条码的当前工艺不一致的情况下, 根据主条码的当前工艺获取在工艺路线明细的下一个工艺, 判断当前工位的工艺与下个工艺是否一致
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getIsBindNextCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && !productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode())) {
|
||||
Optional<MesCraftRouteDetail> optional = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalPs.get().getSeq()) > 0)).findFirst();
|
||||
if (null != optionalCell && optionalCell.isPresent() && !productionProcessContext.getCraftCode().equals(optional.get().getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]捆绑后道工艺,上道工艺[%s]下道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), optional.get().getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
}
|
||||
|
||||
//验证已完成工序最大重复次数: 如果当前工位的工序与主条码的当前工序一致的情况下, 根据条码+物料+工序+工艺查询加工记录, 判断加工记录条数
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())) {
|
||||
List<MesProductionRecord> productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), reqBean.getProcessCode(), productionProcessContext.getCraftCode());
|
||||
if (!CollectionUtils.isEmpty(productionRecordList) && productionRecordList.size() >= optionalPs.get().getRepeatTimes())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]当前工序[%s]产品工艺路线[%s]已完成工序最大重复次数[%s]",
|
||||
message, productionPsInContext.getProductSn(), reqBean.getProcessCode(), craftRouteDetailList.get(0).getCraftRouteCode(), optionalPs.get().getRepeatTimes())).isCompleted();
|
||||
}
|
||||
|
||||
//根据当前工位对应的工艺 获取 所有前道工艺
|
||||
List<MesCraftRouteDetail> beforeCellCraftList = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalCell.get().getSeq()) < 0)).collect(Collectors.toList());
|
||||
|
||||
//验证首工艺: 当前主条码的工艺字段有值,并且当前工位的工艺不等于主条码的当前工艺。 如果等于已经在【验证工艺对应工序最多经过1个】与【 验证已完成工序最大重复次数】 中验证通过,所以这边只考虑不相等
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList) && !StringUtils.isEmpty(productionPsInContext.getCraftCode()) && !productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]已经过首道工艺[%s]", message, productionPsInContext.getProductSn(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
//执行首道工艺 当前主条码验证通过
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList)) return true;
|
||||
|
||||
//当前主条码的工艺字段为空 验证首工艺是否存在工单装配件信息
|
||||
if (StringUtils.isEmpty(productionPsInContext.getCraftCode()) && craftRouteDetailList.get(0).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && checkIsExistWorkOrderAssembly(productionPsInContext, craftRouteDetailList.get(0).getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过首道工艺[%s]", message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftCode())).isCompleted();
|
||||
|
||||
//搜集主条码当前工艺于当前工位对应工艺之间的未完成的工艺集合
|
||||
List<MesCraftRouteDetail> unCompleteCraftList;
|
||||
if (StringUtils.isEmpty(productionPsInContext.getCraftCode())) unCompleteCraftList = beforeCellCraftList;
|
||||
else {
|
||||
Optional<MesCraftRouteDetail> optional = beforeCellCraftList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (null == optional || !optional.isPresent()) //在工位对应的工艺之前的所有前道工艺中未找到主条码的当前工艺则表示主条码已经过当前工艺
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]已经过当前工艺[%s]", message, productionPsInContext.getProductSn(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
unCompleteCraftList = beforeCellCraftList.stream().filter(o -> (null != o && o.getSeq().compareTo(optional.get().getSeq()) > 0)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
//如果没有未完成的工艺, 则代表当前工位可操作
|
||||
if (CollectionUtils.isEmpty(unCompleteCraftList)) return true;
|
||||
|
||||
//未完成工艺倒序
|
||||
unCompleteCraftList = unCompleteCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq).reversed()).collect(Collectors.toList());
|
||||
|
||||
//验证未完成工艺是否存在工单装配件信息
|
||||
Optional<MesCraftRouteDetail> optional = unCompleteCraftList.stream().filter(o -> (null != o && o.getIsChoose() == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue())).findFirst();
|
||||
if (unCompleteCraftList.get(0).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && checkIsExistWorkOrderAssembly(productionPsInContext, unCompleteCraftList.get(0).getCraftCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), unCompleteCraftList.get(0).getCraftCode())).isCompleted();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//验证工艺是否存在工单装配件信息
|
||||
private Boolean checkIsExistWorkOrderAssembly(MesProductionPsInContext productionPsInContext, String craftCode) {
|
||||
return !CollectionUtils.isEmpty(assemblyExtService.getWorkOrderAssemblyList(productionPsInContext.getOrganizeCode(), productionPsInContext.getWorkOrderNo(), productionPsInContext.getProductSn(), craftCode)) ? true : false;
|
||||
}
|
||||
|
||||
//前道工艺防错验证 【非排序】
|
||||
private Boolean doProdCraftRouteCheckNosort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
|
||||
|
||||
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
|
||||
|
||||
//判断主条码的当前工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalPs = StringUtils.isEmpty(productionPsInContext.getCraftCode()) ? null : craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
|
||||
if (!StringUtils.isEmpty(productionPsInContext.getCraftCode()) && (null == optionalPs || !optionalPs.isPresent()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]对应的工艺代码[%s]不匹配零件[%s]对应的产品工艺路线[%s]",
|
||||
message, productionPsInContext.getProductSn(), productionPsInContext.getCraftCode(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode())).isCompleted();
|
||||
|
||||
//验证工艺对应工序最多经过1个: 当前主条码的工艺字段有值, 对应的工艺路线明细信息设置了【true】, 当前工位的工艺与主条码的当前工艺相同, 当前工位的工序与主条码的当前工序不相同
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getAtMostProcess().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()) && !reqBean.getProcessCode().equals(productionPsInContext.getProcessCode()))
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]相同工艺对应工序最多经过1个,上道工艺[%s]当前工位工艺[%s]",
|
||||
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
|
||||
|
||||
List<MesProductionRecord> productionRecordList = null;
|
||||
//验证已完成工序最大重复次数: 如果当前工位的工序与主条码的当前工序一致的情况下, 根据条码+物料+工序+工艺查询加工记录, 判断加工记录条数
|
||||
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())) {
|
||||
//根据零件条码查询加工记录信息
|
||||
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
|
||||
//条码+物料+工序+工艺搜集加工记录
|
||||
List<MesProductionRecord> filterList = CollectionUtils.isEmpty(productionRecordList) ? null :
|
||||
productionRecordList.stream().filter(o -> (null != o && o.getPartNo().equals(productionPsInContext.getPartNo()) && o.getProcessCode().equals(reqBean.getProcessCode()) && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).collect(Collectors.toList());
|
||||
if (!CollectionUtils.isEmpty(filterList) && filterList.size() >= optionalPs.get().getRepeatTimes())
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]当前工序[%s]产品工艺路线[%s]已完成工序最大重复次数[%s]",
|
||||
message, productionPsInContext.getProductSn(), reqBean.getProcessCode(), craftRouteDetailList.get(0).getCraftRouteCode(), optionalPs.get().getRepeatTimes())).isCompleted();
|
||||
}
|
||||
|
||||
//判断当前工位的工序对应的工艺是否包含在产品工艺路线中
|
||||
Optional<MesCraftRouteDetail> optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst();
|
||||
//根据当前工位对应的工艺 获取 所有前道工艺, 如果当前工位的工序对应工艺不在工艺路线明细内, 则默认所有明细均为所有前道工艺, 否则搜集当前工位工序对应工艺前面的所有前道工艺
|
||||
List<MesCraftRouteDetail> beforeCellCraftList;
|
||||
if (null == optionalCell || !optionalCell.isPresent()) beforeCellCraftList = craftRouteDetailList;
|
||||
else beforeCellCraftList = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalCell.get().getSeq()) < 0)).collect(Collectors.toList());
|
||||
|
||||
//前道工艺不存在即当前为首道工艺
|
||||
if (CollectionUtils.isEmpty(beforeCellCraftList)) return true;
|
||||
|
||||
//前道工艺正序
|
||||
beforeCellCraftList = beforeCellCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq)).collect(Collectors.toList());
|
||||
|
||||
//判断上面是否已经查询过数据
|
||||
if (!(null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())))
|
||||
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
|
||||
|
||||
Map<String, List<MesProductionRecord>> prMapByCraft = CollectionUtils.isEmpty(productionRecordList) ? null : productionRecordList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProductionRecord::getCraftCode));
|
||||
|
||||
//遍历前道工艺, 根据工艺查询加工记录是否存在, 并验证是否存在捆绑工艺
|
||||
for (int i = 0; i < beforeCellCraftList.size(); i ++) {
|
||||
if (null == beforeCellCraftList.get(i)) continue;
|
||||
Boolean isExist = isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i).getCraftCode());
|
||||
if (beforeCellCraftList.get(i).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && !isExist)
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftCode())).isCompleted();
|
||||
|
||||
if (i != 0 && beforeCellCraftList.get(i - 1).getIsBindNextCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i - 1).getCraftCode()) && !isExist)
|
||||
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]工艺[%s]捆绑后道工艺",
|
||||
message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftRouteCode(), beforeCellCraftList.get(i - 1).getCraftCode())).isCompleted();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private Boolean isExistProductionRecord(Map<String, List<MesProductionRecord>> prMapByCraft, String craftCode) {
|
||||
return (CollectionUtils.isEmpty(prMapByCraft) || !prMapByCraft.containsKey(craftCode)) ? false : true;
|
||||
}
|
||||
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
|
||||
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
|
||||
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
||||
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description : 生产汇报工步
|
||||
* @Author : zxw --castle update
|
||||
* @Date: 2024/06/07
|
||||
**/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MesReportGenerateStepService extends BaseStepService {
|
||||
@Autowired
|
||||
private IMesProductionProcessContextStepService productionProcessContextStepService;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
|
||||
|
||||
@Autowired
|
||||
private MesReportNoSortStepService reportNoSortStepService;
|
||||
|
||||
@Autowired
|
||||
private MesReportSortStepService reportSortStepService;
|
||||
|
||||
@Override
|
||||
public StepResult execute(StationRequestBean reqBean) {
|
||||
StationResultBean resultBean = new StationResultBean();
|
||||
StepResult stepResult = StepResult.getSuccessComplete();
|
||||
// todo 根据产线判断是排序还是非排序,然后调用排序或者非排序的报工工步
|
||||
//产品加工规则
|
||||
// List<MesProdRuleContext> prodRuleDataContext = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
|
||||
//获取产成零件信息
|
||||
// List<MesProductionPartContext> productionPartContext = productionDispatchContextStepService.getProductionPartContext(reqBean);
|
||||
//1. 校验当前有没有工单---只有有工单才能报工
|
||||
//如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号
|
||||
// List<MesProductionPsOutContext> mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean);
|
||||
|
||||
|
||||
|
||||
//获取上下文信息
|
||||
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
|
||||
|
||||
//配置错误 抛出异常
|
||||
if (!productionProcessContext.getSuccess())
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
|
||||
|
||||
//存储生产过程上下文对象
|
||||
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
|
||||
|
||||
//从上下文中取出生产线对象
|
||||
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
|
||||
|
||||
//排序线报工
|
||||
if (MesExtEnumUtil.WORK_CENTER_TYPE.SORT.getValue() == workCenter.getCenterType()) {
|
||||
return reportSortStepService.execute(reqBean);
|
||||
} else {
|
||||
//非排序线报工
|
||||
return reportNoSortStepService.execute(reqBean);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,259 +0,0 @@
|
||||
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
|
||||
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
|
||||
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
|
||||
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
|
||||
import cn.estsh.i3plus.platform.common.tool.MathOperation;
|
||||
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
|
||||
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
|
||||
import cn.estsh.i3plus.pojo.base.util.StringUtil;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.*;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
||||
import cn.estsh.i3plus.pojo.mes.repository.*;
|
||||
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description : 生产汇报工步 非排序报工
|
||||
*
|
||||
* @Author : zxw --castle update
|
||||
* @Date: 2024/06/07
|
||||
**/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MesReportNoSortStepService extends BaseStepService {
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService;
|
||||
|
||||
@Autowired
|
||||
private MesPartRepository mesPartRDao;
|
||||
|
||||
@Autowired
|
||||
private MesWorkOrderRepository workOrderRepository;
|
||||
|
||||
@Autowired
|
||||
private MesWorkCenterRepository mesWorkCenterRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductVersionRepository mesProductVersionRDao;
|
||||
|
||||
@Autowired
|
||||
private MesBomRepository mesBomRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductOffLineRepository mesProductOffLineRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductPlanRepository mesProductPlanRDao;
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
|
||||
|
||||
@Override
|
||||
public StepResult execute(StationRequestBean reqBean) {
|
||||
StationResultBean resultBean = new StationResultBean();
|
||||
StepResult stepResult = StepResult.getSuccessComplete();
|
||||
|
||||
//产品加工规则
|
||||
List<MesProdRuleContext> prodRuleDataContext = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
|
||||
//如果产品加工规则中的foreignKey 和 mesProduceSns 一一对应的,
|
||||
List<MesProductionPsOutContext> mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean);
|
||||
//需要报工的条码
|
||||
List<MesProductionPsOutContext> needReportSn = new ArrayList<>();
|
||||
for (MesProductionPsOutContext sn : mesProduceSns) {
|
||||
Integer foreignKey = sn.getForeignKey();
|
||||
List<MesProdRuleContext> ruleContextList = prodRuleDataContext.stream().filter(rule -> Objects.equals(rule.getForeignKey(), foreignKey)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(ruleContextList)) {
|
||||
Integer reportType = ruleContextList.get(0).getReportType();
|
||||
if (MesExtEnumUtil.NOSORT_REPORT_TYPE.REPORT.getValue() == reportType){
|
||||
needReportSn.add(sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.doProductReport(needReportSn, reqBean.getOrganizeCode(), reqBean.getUserInfo(),reqBean,resultBean);
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "报工成功");
|
||||
}
|
||||
|
||||
public void doProductReport(List<MesProductionPsOutContext> mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) {
|
||||
//新增初始化
|
||||
Map<String, List<MesProduceSn>> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo));
|
||||
Map<String, MesPart> mesPartMap = new HashMap<>();
|
||||
MesPart mesPart;
|
||||
//查询工单状态
|
||||
Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()};
|
||||
for (Map.Entry<String, List<MesProduceSn>> mesProduceSn : mesWorkOrderMap.entrySet()) {
|
||||
List<MesProduceSn> mesWorkOrderList = mesProduceSn.getValue();
|
||||
//获取物料信息
|
||||
if(mesPartMap.containsKey(mesProduceSn.getKey())){
|
||||
mesPart = mesPartMap.get(mesProduceSn.getKey());
|
||||
}else{
|
||||
//查询物料信息
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesProduceSn.getKey(), "partNo", ddlPackBean);
|
||||
mesPart = mesPartRDao.getByProperty(ddlPackBean);
|
||||
if(Objects.isNull(mesPart)){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】信息不存在", mesProduceSn.getKey()));
|
||||
}
|
||||
mesPartMap.put(mesProduceSn.getKey(),mesPart);
|
||||
}
|
||||
//根据物料获取已发布的工单
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getInPackArray(orderStatus, "workOrderStatus", ddlPackBean);
|
||||
MesWorkOrder oldMesWorkOrder = workOrderRepository.getByProperty(ddlPackBean);
|
||||
if(Objects.isNull(oldMesWorkOrder)){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】状态未已发布的工单信息不存在", mesPart.getPartNo()));
|
||||
}
|
||||
//查询工作中心
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getWorkCenterCode(), "workCenterCode", ddlPackBean);
|
||||
MesWorkCenter mesWorkCenter = mesWorkCenterRDao.getByProperty(ddlPackBean);
|
||||
if (Objects.isNull(mesWorkCenter)) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】不存在", oldMesWorkOrder.getWorkCenterCode()));
|
||||
}
|
||||
//获取生产版本
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(mesWorkCenter.getErpWorkCenter(), "workCenterCode", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getProductVersion(), "productVersion", ddlPackBean);
|
||||
MesProductVersion mesProductVersion = mesProductVersionRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductVersion) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本信息不存在", mesPart.getPartNo()));
|
||||
}
|
||||
//物料+生产版本获取bom信息
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(mesProductVersion.getAlternativePartList(), "bomVersion", ddlPackBean);
|
||||
List<MesBom> mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean);
|
||||
if (CollectionUtils.isEmpty(mesBoms)) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本【%s】对应bom信息不存在", mesPart.getPartNo(), mesProductVersion.getProductVersion()));
|
||||
}
|
||||
oldMesWorkOrder.setNum(mesWorkOrderList.size());
|
||||
oldMesWorkOrder.setReportedQty(MathOperation.add(oldMesWorkOrder.getNum(), oldMesWorkOrder.getReportedQty()));
|
||||
//更新SAP计划完成数量
|
||||
saveMesProductPlan(oldMesWorkOrder, false, true, reqBean, resultBean);
|
||||
|
||||
//更新工单状态
|
||||
double unCompleteQty = MathOperation.sub(oldMesWorkOrder.getQty(), oldMesWorkOrder.getReportedQty());
|
||||
oldMesWorkOrder.setUnCompleteQty(unCompleteQty > 0 ? unCompleteQty : 0);
|
||||
if (oldMesWorkOrder.getReportedQty() > oldMesWorkOrder.getQty()) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("工单报工数量【%s】大于工单数量【%s】,不允许报工", oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty()));
|
||||
} else if (Objects.equals(oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())) {
|
||||
oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue());
|
||||
} else {
|
||||
oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue());
|
||||
}
|
||||
ConvertBean.serviceModelUpdate(oldMesWorkOrder,userName);
|
||||
oldMesWorkOrder.setModifyDatetime((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")).format(new Date()));
|
||||
workOrderRepository.update(oldMesWorkOrder);
|
||||
//保存数据
|
||||
List<MesProductOffLine> mesProductOffLineList = new ArrayList<>();
|
||||
MesProductOffLine newMesProductOffLine;
|
||||
for (MesProduceSn produceSn : mesWorkOrderList) {
|
||||
for (MesBom mesBom : mesBoms) {
|
||||
newMesProductOffLine = new MesProductOffLine();
|
||||
newMesProductOffLine.setReportPartNo(oldMesWorkOrder.getPartNo());
|
||||
newMesProductOffLine.setReportPartNameRdd(oldMesWorkOrder.getPartName());
|
||||
newMesProductOffLine.setItemPartNo(mesBom.getItemPartNo());
|
||||
newMesProductOffLine.setItemPartName(mesBom.getItemPartName());
|
||||
newMesProductOffLine.setItemQty(mesBom.getItemQty());
|
||||
newMesProductOffLine.setAlort(mesProductVersion.getReceiveInventoryPoint());
|
||||
newMesProductOffLine.setStgeLoc(mesProductVersion.getShipInventoryPoint());
|
||||
newMesProductOffLine.setQty(1d);
|
||||
newMesProductOffLine.setReportSn(produceSn.getProductSn());
|
||||
newMesProductOffLine.setBomVersion(oldMesWorkOrder.getProductVersion());
|
||||
newMesProductOffLine.setSerialNumber(produceSn.getSerialNumber());
|
||||
newMesProductOffLine.setUnit(mesBom.getUnit());
|
||||
newMesProductOffLine.setItemUnit(mesBom.getItemUnit());
|
||||
newMesProductOffLine.setWorkOrderNo(oldMesWorkOrder.getWorkOrderNo());
|
||||
newMesProductOffLine.setWorkOrderType(oldMesWorkOrder.getWorkOrderType());
|
||||
newMesProductOffLine.setWorkCenterCode(oldMesWorkOrder.getWorkCenterCode());
|
||||
newMesProductOffLine.setWorkCellCode(oldMesWorkOrder.getWorkCellCode());
|
||||
newMesProductOffLine.setReportType(oldMesWorkOrder.getReportType());
|
||||
newMesProductOffLine.setSapWorkCenter(oldMesWorkOrder.getErpWorkCenter());
|
||||
newMesProductOffLine.setOrganizeCode(oldMesWorkOrder.getOrganizeCode());
|
||||
|
||||
ConvertBean.serviceModelInitialize(newMesProductOffLine, userName);
|
||||
mesProductOffLineList.add(newMesProductOffLine);
|
||||
}
|
||||
}
|
||||
mesProductOffLineRDao.saveAll(mesProductOffLineList);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveMesProductPlan(MesWorkOrder bean, boolean isInsert, boolean isReport,StationRequestBean reqBean, StationResultBean resultBean) {
|
||||
if (StringUtil.isEmpty(bean.getPlanOrderNo())) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanStartTime(), "planStartDate", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanEndTime(), "planEndDate", ddlPackBean);
|
||||
MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductPlan) {
|
||||
MesProductPlan mesPlanOrder = new MesProductPlan();
|
||||
mesPlanOrder.setPlanOrderNo("");
|
||||
mesPlanOrder.setPlanQty(bean.getQty());
|
||||
mesPlanOrder.setPlanPartNo(bean.getPartNo());
|
||||
mesPlanOrder.setCompleteQty(0d);
|
||||
mesPlanOrder.setUncompleteQty(bean.getQty());
|
||||
mesPlanOrder.setUnit(bean.getUnit());
|
||||
mesPlanOrder.setPlanStartDate(bean.getPlanStartTime());
|
||||
mesPlanOrder.setPlanEndDate(bean.getPlanEndTime());
|
||||
mesPlanOrder.setPartMappingWorkCenterCode(bean.getErpWorkCenter());
|
||||
mesPlanOrder.setPlanOrganizeCode(bean.getOrganizeCode());
|
||||
mesPlanOrder.setOrganizeCode(bean.getOrganizeCode());
|
||||
ConvertBean.serviceModelInitialize(mesPlanOrder, bean.getCreateUser());
|
||||
mesProductPlanRDao.insert(mesPlanOrder);
|
||||
} else {
|
||||
if (isInsert) {
|
||||
mesProductPlan.setPlanQty(MathOperation.add(mesProductPlan.getPlanQty(), bean.getQty()));
|
||||
} else {
|
||||
//报工
|
||||
if (isReport) {
|
||||
mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
//报工调整
|
||||
} else {
|
||||
mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
}
|
||||
}
|
||||
mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty()));
|
||||
ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser());
|
||||
mesProductPlanRDao.update(mesProductPlan);
|
||||
}
|
||||
} else {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanOrderNo(), "planOrderNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean);
|
||||
MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductPlan) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("SAP计划单号【%s】物料【%s】,不存在", bean.getPlanOrderNo(), bean.getPartNo()));
|
||||
}
|
||||
if (!isInsert) {
|
||||
if (Objects.isNull(mesProductPlan.getCompleteQty())) {
|
||||
mesProductPlan.setCompleteQty(0d);
|
||||
}
|
||||
//报工
|
||||
if (isReport) {
|
||||
mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
//报工调整
|
||||
} else {
|
||||
mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
}
|
||||
mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty()));
|
||||
ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser());
|
||||
mesProductPlanRDao.update(mesProductPlan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,417 +0,0 @@
|
||||
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
|
||||
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
|
||||
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
|
||||
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
|
||||
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
|
||||
import cn.estsh.i3plus.platform.common.tool.MathOperation;
|
||||
import cn.estsh.i3plus.platform.common.tool.TimeTool;
|
||||
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
|
||||
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
|
||||
import cn.estsh.i3plus.pojo.base.util.StringUtil;
|
||||
import cn.estsh.i3plus.pojo.mes.bean.*;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
||||
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
||||
import cn.estsh.i3plus.pojo.mes.repository.*;
|
||||
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
||||
import cn.estsh.impp.framework.boot.auth.AuthUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description : 生产汇报工步 排序报工
|
||||
*
|
||||
* @Author : zxw --castle update
|
||||
* @Date: 2024/06/07
|
||||
**/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MesReportSortStepService extends BaseStepService {
|
||||
|
||||
@Autowired
|
||||
private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService;
|
||||
|
||||
@Autowired
|
||||
private MesPartRepository mesPartRDao;
|
||||
|
||||
@Autowired
|
||||
private MesWorkOrderRepository workOrderRepository;
|
||||
|
||||
@Autowired
|
||||
private MesWorkCenterRepository mesWorkCenterRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductVersionRepository mesProductVersionRDao;
|
||||
|
||||
@Autowired
|
||||
private MesBomRepository mesBomRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductOffLineRepository mesProductOffLineRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProductPlanRepository mesProductPlanRDao;
|
||||
|
||||
@Autowired
|
||||
private MesProdRuleSortCfgRepository mesProdRuleSortCfgRDao;
|
||||
|
||||
@Autowired
|
||||
private IMesMoveRuleRepository moveRuleRao;
|
||||
|
||||
@Autowired
|
||||
private MesPartSapRepository mesPartSapRao;
|
||||
|
||||
@Autowired
|
||||
private MesPartRepository partRao;
|
||||
|
||||
@Autowired
|
||||
private MesMoveRepository mesMoveRDao;
|
||||
|
||||
@Autowired
|
||||
private IMesProdOrgExtService prodOrgExtService;
|
||||
|
||||
@Override
|
||||
public StepResult execute(StationRequestBean reqBean) {
|
||||
StationResultBean resultBean = new StationResultBean();
|
||||
StepResult stepResult = StepResult.getSuccessComplete();
|
||||
//如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号
|
||||
List<MesProductionPsOutContext> mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean);
|
||||
this.doProductReport(mesProduceSns, reqBean.getOrganizeCode(), reqBean.getUserInfo(),reqBean,resultBean);
|
||||
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "报工成功");
|
||||
}
|
||||
|
||||
public void doProductReport(List<MesProductionPsOutContext> mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) {
|
||||
//新增初始化
|
||||
Map<String, List<MesProduceSn>> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo));
|
||||
Map<String, MesPart> mesPartMap = new HashMap<>();
|
||||
MesPart mesPart;
|
||||
//查询工单状态
|
||||
Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()};
|
||||
for (Map.Entry<String, List<MesProduceSn>> mesProduceSn : mesWorkOrderMap.entrySet()) {
|
||||
List<MesProduceSn> mesWorkOrderList = mesProduceSn.getValue();
|
||||
//获取物料信息
|
||||
if(mesPartMap.containsKey(mesProduceSn.getKey())){
|
||||
mesPart = mesPartMap.get(mesProduceSn.getKey());
|
||||
}else{
|
||||
//查询物料信息
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesProduceSn.getKey(), "partNo", ddlPackBean);
|
||||
mesPart = mesPartRDao.getByProperty(ddlPackBean);
|
||||
if(Objects.isNull(mesPart)){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】信息不存在", mesProduceSn.getKey()));
|
||||
}
|
||||
mesPartMap.put(mesProduceSn.getKey(),mesPart);
|
||||
}
|
||||
//根据物料获取已发布的工单
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getInPackArray(orderStatus, "workOrderStatus", ddlPackBean);
|
||||
MesWorkOrder oldMesWorkOrder = workOrderRepository.getByProperty(ddlPackBean);
|
||||
if(Objects.isNull(oldMesWorkOrder)){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】状态未已发布的工单信息不存在", mesPart.getPartNo()));
|
||||
}
|
||||
//查询工作中心
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getWorkCenterCode(), "workCenterCode", ddlPackBean);
|
||||
MesWorkCenter mesWorkCenter = mesWorkCenterRDao.getByProperty(ddlPackBean);
|
||||
if (Objects.isNull(mesWorkCenter)) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】不存在", oldMesWorkOrder.getWorkCenterCode()));
|
||||
}
|
||||
//获取生产版本
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(mesWorkCenter.getErpWorkCenter(), "workCenterCode", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getProductVersion(), "productVersion", ddlPackBean);
|
||||
MesProductVersion mesProductVersion = mesProductVersionRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductVersion) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本信息不存在", mesPart.getPartNo()));
|
||||
}
|
||||
//物料+生产版本获取bom信息
|
||||
ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(mesProductVersion.getAlternativePartList(), "bomVersion", ddlPackBean);
|
||||
List<MesBom> mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean);
|
||||
if (CollectionUtils.isEmpty(mesBoms)) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本【%s】对应bom信息不存在", mesPart.getPartNo(), mesProductVersion.getProductVersion()));
|
||||
}
|
||||
oldMesWorkOrder.setNum(mesWorkOrderList.size());
|
||||
oldMesWorkOrder.setReportedQty(MathOperation.add(oldMesWorkOrder.getNum(), oldMesWorkOrder.getReportedQty()));
|
||||
//更新SAP计划完成数量
|
||||
saveMesProductPlan(oldMesWorkOrder, false, true, reqBean, resultBean);
|
||||
|
||||
//更新工单状态
|
||||
double unCompleteQty = MathOperation.sub(oldMesWorkOrder.getQty(), oldMesWorkOrder.getReportedQty());
|
||||
oldMesWorkOrder.setUnCompleteQty(unCompleteQty > 0 ? unCompleteQty : 0);
|
||||
if (oldMesWorkOrder.getReportedQty() > oldMesWorkOrder.getQty()) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("工单报工数量【%s】大于工单数量【%s】,不允许报工", oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty()));
|
||||
} else if (Objects.equals(oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())) {
|
||||
oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue());
|
||||
} else {
|
||||
oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue());
|
||||
}
|
||||
ConvertBean.serviceModelUpdate(oldMesWorkOrder,userName);
|
||||
workOrderRepository.update(oldMesWorkOrder);
|
||||
//保存数据
|
||||
List<MesProductOffLine> mesProductOffLineList = new ArrayList<>();
|
||||
List<MesMove> mesMoveList = new ArrayList<>();
|
||||
//条码
|
||||
List<String> snList = mesProduceSnList.stream().map(MesProduceSn::getProductSn).collect(Collectors.toList());
|
||||
//物料信息
|
||||
Map<String, List<MesPartSap>> partSapMap = new HashMap<>();
|
||||
boolean isReport = false;
|
||||
boolean isMove = false;
|
||||
//排序加工规则
|
||||
MesProdRuleSortCfg mesProdRuleSortCfg = getMesProdRuleSortCfg(oldMesWorkOrder);
|
||||
if (Objects.isNull(mesProdRuleSortCfg)){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】物料【%s】排序加工规则未维护", oldMesWorkOrder.getWorkCenterCode(), oldMesWorkOrder.getPartNo()));
|
||||
}
|
||||
|
||||
if(MesExtEnumUtil.MES_REPORT_TYPE.REPORT.getValue() == mesProdRuleSortCfg.getReportType()){
|
||||
isReport = true;
|
||||
} else if (MesExtEnumUtil.MES_REPORT_TYPE.MOVE.getValue() == mesProdRuleSortCfg.getReportType()) {
|
||||
isMove = true;
|
||||
}else if (MesExtEnumUtil.MES_REPORT_TYPE.REPORT_MOVE.getValue() == mesProdRuleSortCfg.getReportType()) {
|
||||
isReport = true;
|
||||
isMove = true;
|
||||
}else if (MesExtEnumUtil.MES_REPORT_TYPE.CUSTOMER_SUPPLY_MOVE.getValue() == mesProdRuleSortCfg.getReportType()) {
|
||||
partSapMap = customerSupplyMove(oldMesWorkOrder, mesProductVersion, mesBoms, snList, mesProductOffLineList, mesMoveList, reqBean.getWorkCenterCode());
|
||||
}else{
|
||||
log.info("工单{}排序加工规则报工类型未维护",oldMesWorkOrder.getWorkOrderNo());
|
||||
return;
|
||||
}
|
||||
|
||||
//查询SAP物料信息
|
||||
List<MesPartSap> mesPartSaps = partSapMap.get(oldMesWorkOrder.getPartNo());
|
||||
if (mesPartSaps.isEmpty()){
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】物料【%s】物料信息不存在", oldMesWorkOrder.getWorkCenterCode(), oldMesWorkOrder.getPartNo()));
|
||||
}
|
||||
MesPartSap mesPartSap = mesPartSaps.get(0);
|
||||
for (String sn : snList) {
|
||||
//成品汇报
|
||||
if(isReport){
|
||||
for (MesBom mesBom : mesBoms) {
|
||||
mesProductOffLineList.add(creatMesProductOffLine(oldMesWorkOrder, mesProductVersion, sn, mesBom,false));
|
||||
}
|
||||
}
|
||||
//成品移库
|
||||
if(isMove){
|
||||
MesMove move = createMove(mesPartSap, mesProdRuleSortCfg.getSrcErpLocation(), mesProdRuleSortCfg.getDestErpLocation(), oldMesWorkOrder.getOrganizeCode(), reqBean.getWorkCenterCode(), 1d,sn,MesExtEnumUtil.MOVE_TYPE.FINISH_PRODUCTS_MOVE.getValue());
|
||||
move.setMatnr(oldMesWorkOrder.getPartNo());
|
||||
mesMoveList.add(move);
|
||||
}
|
||||
}
|
||||
|
||||
//保存报工记录
|
||||
mesProductOffLineRDao.saveAll(mesProductOffLineList);
|
||||
//保存移库记录
|
||||
mesMoveRDao.saveAll(mesMoveList);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveMesProductPlan(MesWorkOrder bean, boolean isInsert, boolean isReport,StationRequestBean reqBean, StationResultBean resultBean) {
|
||||
if (StringUtil.isEmpty(bean.getPlanOrderNo())) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanStartTime(), "planStartDate", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanEndTime(), "planEndDate", ddlPackBean);
|
||||
MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductPlan) {
|
||||
MesProductPlan mesPlanOrder = new MesProductPlan();
|
||||
mesPlanOrder.setPlanOrderNo("");
|
||||
mesPlanOrder.setPlanQty(bean.getQty());
|
||||
mesPlanOrder.setPlanPartNo(bean.getPartNo());
|
||||
mesPlanOrder.setCompleteQty(0d);
|
||||
mesPlanOrder.setUncompleteQty(bean.getQty());
|
||||
mesPlanOrder.setUnit(bean.getUnit());
|
||||
mesPlanOrder.setPlanStartDate(bean.getPlanStartTime());
|
||||
mesPlanOrder.setPlanEndDate(bean.getPlanEndTime());
|
||||
mesPlanOrder.setPartMappingWorkCenterCode(bean.getErpWorkCenter());
|
||||
mesPlanOrder.setPlanOrganizeCode(bean.getOrganizeCode());
|
||||
mesPlanOrder.setOrganizeCode(bean.getOrganizeCode());
|
||||
ConvertBean.serviceModelInitialize(mesPlanOrder, bean.getCreateUser());
|
||||
mesProductPlanRDao.insert(mesPlanOrder);
|
||||
} else {
|
||||
if (isInsert) {
|
||||
mesProductPlan.setPlanQty(MathOperation.add(mesProductPlan.getPlanQty(), bean.getQty()));
|
||||
} else {
|
||||
//报工
|
||||
if (isReport) {
|
||||
mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
//报工调整
|
||||
} else {
|
||||
mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
}
|
||||
}
|
||||
mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty()));
|
||||
ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser());
|
||||
mesProductPlanRDao.update(mesProductPlan);
|
||||
}
|
||||
} else {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPlanOrderNo(), "planOrderNo", ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean);
|
||||
MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean);
|
||||
if (null == mesProductPlan) {
|
||||
stepExpSendMsgAndThrowEx(reqBean, resultBean, String.format("SAP计划单号【%s】物料【%s】,不存在", bean.getPlanOrderNo(), bean.getPartNo()));
|
||||
}
|
||||
if (!isInsert) {
|
||||
if (Objects.isNull(mesProductPlan.getCompleteQty())) {
|
||||
mesProductPlan.setCompleteQty(0d);
|
||||
}
|
||||
//报工
|
||||
if (isReport) {
|
||||
mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
//报工调整
|
||||
} else {
|
||||
mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum()));
|
||||
}
|
||||
mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty()));
|
||||
ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser());
|
||||
mesProductPlanRDao.update(mesProductPlan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private MesProdRuleSortCfg getMesProdRuleSortCfg(MesWorkOrder mesWorkOrder) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode());
|
||||
DdlPreparedPack.getStringEqualPack(mesWorkOrder.getPartNo(),"reportPartNo",ddlPackBean);
|
||||
DdlPreparedPack.getStringEqualPack(mesWorkOrder.getWorkCenterCode(),"workCenterCode",ddlPackBean);
|
||||
MesProdRuleSortCfg mesProdRuleSortCfg = mesProdRuleSortCfgRDao.getByProperty(ddlPackBean);
|
||||
return mesProdRuleSortCfg;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, List<MesPartSap>> customerSupplyMove(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, List<MesBom> mesBoms, List<String> resultList, List<MesProductOffLine> mesProductOffLineList, List<MesMove> mesMoveList, String workCenterCode) {
|
||||
boolean isItemMove;
|
||||
boolean isItemReport;
|
||||
MesMoveRule moveRule;
|
||||
//查询零件生产组的移库规则
|
||||
List<MesMoveRule> moveRules = this.findMesMoveRuleByPartProdGroupCode(mesWorkOrder.getPartProdGroupCode(), mesWorkOrder.getOrganizeCode());
|
||||
Map<String, List<MesMoveRule>> mesMoveRuleMap = moveRules.stream().filter(t -> Objects.nonNull(t.getSrcType())).collect(Collectors.groupingBy(MesMoveRule::getSrcType));
|
||||
List<String> itemPartNoList = mesBoms.stream().map(MesBom::getItemPartNo).collect(Collectors.toList());
|
||||
//子物料SAP下发信息
|
||||
Map<String, List<MesPartSap>> mesPartSapMap = getPartSapMap(mesWorkOrder, itemPartNoList);
|
||||
//获取物料信息
|
||||
Map<String, List<MesPart>> itemPartMap = getItemPartMap(mesWorkOrder, itemPartNoList);
|
||||
for (String sn : resultList) {
|
||||
for (MesBom mesBom : mesBoms) {
|
||||
isItemReport = false;
|
||||
isItemMove = false;
|
||||
moveRule = null;
|
||||
if(itemPartMap.containsKey(mesBom.getItemPartNo())){
|
||||
MesPart itemPart = itemPartMap.get(mesBom.getItemPartNo()).iterator().next();
|
||||
if(!StringUtil.isEmpty(itemPart.getEsd()) && mesMoveRuleMap.containsKey(itemPart.getEsd())){
|
||||
moveRule = mesMoveRuleMap.get(itemPart.getEsd()).iterator().next();
|
||||
if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.REPORT_MOVE.getValue() == moveRule.getReportType()) {
|
||||
isItemMove = true;
|
||||
isItemReport = true;
|
||||
} else if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.REPORT.getValue() == moveRule.getReportType()) {
|
||||
isItemReport = true;
|
||||
} else if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.MOVE.getValue() == moveRule.getReportType()) {
|
||||
isItemMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//汇报
|
||||
if(isItemReport){
|
||||
mesProductOffLineList.add(creatMesProductOffLine(mesWorkOrder, mesProductVersion, sn, mesBom,true));
|
||||
}
|
||||
//移库
|
||||
if(isItemMove){
|
||||
MesPartSap mesPartSap = null;
|
||||
if(mesPartSapMap.containsKey(mesBom.getItemPartNo())){
|
||||
mesPartSap = mesPartSapMap.get(mesBom.getItemPartNo()).iterator().next();
|
||||
}
|
||||
MesMove move = createMove(mesPartSap, moveRule.getErpSrcLocateNo(), moveRule.getErpDestLocateNo(), mesBom.getOrganizeCode(), workCenterCode, mesBom.getItemQty(),"",MesExtEnumUtil.MOVE_TYPE.RAW_MATERIAL_MOVE.getValue());
|
||||
move.setMatnr(mesBom.getItemPartNo());
|
||||
mesMoveList.add(move);
|
||||
}
|
||||
}
|
||||
}
|
||||
//子物料SAP下发信息
|
||||
return mesPartSapMap ;
|
||||
}
|
||||
|
||||
|
||||
private List<MesMoveRule> findMesMoveRuleByPartProdGroupCode(String partProdGroupCode, String organizeCode) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
||||
DdlPreparedPack.getStringEqualPack(partProdGroupCode, "partProdGroupCode", ddlPackBean);
|
||||
List<MesMoveRule> moveRules = moveRuleRao.findByHqlWhere(ddlPackBean);
|
||||
return moveRules;
|
||||
}
|
||||
|
||||
private Map<String, List<MesPartSap>> getPartSapMap(MesWorkOrder mesWorkOrder, List<String> itemPartNoList) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode());
|
||||
DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean);
|
||||
List<MesPartSap> mesPartSapList = mesPartSapRao.findByHqlWhere(ddlPackBean);
|
||||
Map<String, List<MesPartSap>> mesPartSapMap = mesPartSapList.stream().filter(t -> Objects.nonNull(t.getPartNo())).collect(Collectors.groupingBy(MesPartSap::getPartNo));
|
||||
return mesPartSapMap;
|
||||
}
|
||||
|
||||
private Map<String, List<MesPart>> getItemPartMap(MesWorkOrder mesWorkOrder, List<String> itemPartNoList) {
|
||||
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode());
|
||||
DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean);
|
||||
List<MesPart> mesPartList = partRao.findByHqlWhere(ddlPackBean);
|
||||
Map<String, List<MesPart>> itemPartMap = mesPartList.stream().filter(t -> Objects.nonNull(t.getPartNo())).collect(Collectors.groupingBy(MesPart::getPartNo));
|
||||
return itemPartMap;
|
||||
}
|
||||
|
||||
private MesProductOffLine creatMesProductOffLine(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion,
|
||||
String sn, MesBom mesBom,boolean isItemReport) {
|
||||
MesProductOffLine newMesProductOffLine;
|
||||
newMesProductOffLine = new MesProductOffLine();
|
||||
if(!isItemReport){
|
||||
newMesProductOffLine.setReportPartNo(mesWorkOrder.getPartNo());
|
||||
newMesProductOffLine.setReportPartNameRdd(mesWorkOrder.getPartName());
|
||||
}
|
||||
|
||||
newMesProductOffLine.setReportSn(sn);
|
||||
newMesProductOffLine.setItemPartNo(mesBom.getItemPartNo());
|
||||
newMesProductOffLine.setItemPartName(mesBom.getItemPartName());
|
||||
newMesProductOffLine.setItemQty(mesBom.getItemQty());
|
||||
newMesProductOffLine.setAlort(mesProductVersion.getReceiveInventoryPoint());
|
||||
newMesProductOffLine.setStgeLoc(mesProductVersion.getShipInventoryPoint());
|
||||
newMesProductOffLine.setQty(1d);
|
||||
newMesProductOffLine.setBomVersion(mesWorkOrder.getProductVersion());
|
||||
newMesProductOffLine.setSerialNumber(sn);
|
||||
newMesProductOffLine.setUnit(mesBom.getUnit());
|
||||
newMesProductOffLine.setItemUnit(mesBom.getItemUnit());
|
||||
newMesProductOffLine.setWorkOrderNo(mesWorkOrder.getWorkOrderNo());
|
||||
newMesProductOffLine.setWorkOrderType(mesWorkOrder.getWorkOrderType());
|
||||
newMesProductOffLine.setWorkCenterCode(mesWorkOrder.getWorkCenterCode());
|
||||
newMesProductOffLine.setWorkCellCode(mesWorkOrder.getWorkCellCode());
|
||||
newMesProductOffLine.setReportType(mesWorkOrder.getReportType());
|
||||
newMesProductOffLine.setSapWorkCenter(mesWorkOrder.getErpWorkCenter());
|
||||
newMesProductOffLine.setOrganizeCode(mesWorkOrder.getOrganizeCode());
|
||||
|
||||
ConvertBean.serviceModelInitialize(newMesProductOffLine, mesWorkOrder.getCreateUser());
|
||||
return newMesProductOffLine;
|
||||
}
|
||||
|
||||
private MesMove createMove(MesPartSap mesPart , String source, String target, String org, String workCenterCode, double qty,String sn,Integer moveType) {
|
||||
MesMove move = new MesMove();
|
||||
if(!Objects.isNull(mesPart)){
|
||||
move.setMeins(mesPart.getUnit());
|
||||
}
|
||||
move.setOrganizeCode(org);
|
||||
move.setFactoryCode(org);
|
||||
move.setLgort(source);
|
||||
move.setUmlgo(target);
|
||||
move.setMenge(qty);
|
||||
move.setPostDate(TimeTool.getToday());
|
||||
move.setProductSn(sn);
|
||||
move.setMoveType(moveType);
|
||||
move.setPostTime(TimeTool.getTimeShortWithColon());
|
||||
move.setWorkCenter(prodOrgExtService.getErpWorkCenterCode(org, workCenterCode));
|
||||
ConvertBean.serviceModelInitialize(move, AuthUtil.getSessionUser().getUserName());
|
||||
return move;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue