From 377e8aa2e9d6691176b24a2b0e93e4a1dd0aa6be Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Sat, 14 Sep 2024 17:20:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E6=AD=A5=E5=BC=B9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MesFunctionCutOrderDialogPrintService.java | 25 +- .../step/MesCustomDialogStepService.java | 7 + .../MesProdCraftRouteCheckNosortStepService.java | 344 +++++++++++++++++ .../MesProdCraftRouteCheckSortStepService.java | 344 +++++++++++++++++ .../step/MesReportGenerateStepService.java | 77 ---- .../step/MesReportNoSortStepService.java | 259 ------------- .../serviceimpl/step/MesReportSortStepService.java | 417 --------------------- 7 files changed, 702 insertions(+), 771 deletions(-) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckNosortStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckSortStepService.java delete mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java delete mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java delete mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionCutOrderDialogPrintService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionCutOrderDialogPrintService.java index 27debec..25960a9 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionCutOrderDialogPrintService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionCutOrderDialogPrintService.java @@ -33,7 +33,7 @@ import java.util.List; import java.util.Map; /** - * @Description : 工位参数按钮事件接口实现【选择工单】 + * @Description : 工位参数按钮事件接口实现【裁片工单打印弹框】 **/ @Service @Slf4j @@ -54,27 +54,24 @@ public class MesFunctionCutOrderDialogPrintService extends BaseSwsService implem @Override public Boolean doFunction(StationRequestBean reqBean, StationResultBean resultBean, ButtonDynamicModel buttonDynamicModel) { - //获取生产过程上下文对象 - MesProductionProcessContext productionProcessContext = productionProcessContextStepService.getProductionProcessContext(reqBean); - - if (!productionProcessContext.getSuccess()) return false; - if (StringUtils.isEmpty(buttonDynamicModel.getFunctionValue())) { this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()).scanInfo(buttonDynamicModel.getFunctionValue()), - String.format("生产线[%s]工位[%s]%s失败,裁片方案成品[%s]列表缺失!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), buttonDynamicModel.getButtonName(), buttonDynamicModel.getFunctionValue()), + String.format("生产线[%s]工位[%s]裁片工单打印弹框提交信息有误!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT); return false; } - this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()).scanInfo(buttonDynamicModel.getFunctionValue()), - String.format("生产线[%s]工位[%s]%s成功,请等待保存加工记录!提交信息[%s]", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), buttonDynamicModel.getButtonName(), buttonDynamicModel.getFunctionValue()), - MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + this.sendMessage(reqBean, resultBean, String.format("生产线[%s]工位[%s]裁片工单打印弹框提交信息成功!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + this.sendMessage(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()).scanInfo(buttonDynamicModel.getFunctionValue()), + String.format("生产线[%s]工位[%s]裁片工单打印弹框提交信息成功!提交信息[%s]", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), buttonDynamicModel.getFunctionValue()), + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); productionDispatchContextStepService.dispatchMesWorkOrderCutFgDataContext(reqBean, JSONObject.parseArray(buttonDynamicModel.getFunctionValue(), MesWorkOrderCutDetailModel.class)); reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean)); reqBean.setInterfaceType(MesPcnConstWords.SHIPPING); reqBean.setBusiType(MesPcnEnumUtil.ACTOR_RECEIVE_STRATEGY.WS_CMD_DO_SCAN.getCode()); + reqBean.setButtonCode(buttonDynamicModel.getButtonCode()); reqBean.setStepDialogStatus(true); shippingDispatchService.sendScanQueueNextExec(reqBean); @@ -85,8 +82,6 @@ public class MesFunctionCutOrderDialogPrintService extends BaseSwsService implem @Override public Object stepDialogDispatch(StationRequestBean reqBean) { - log.info("MesFunctionCutOrderDialogPrintService --- stepDialogDispatch --- start"); - List mesWorkOrderCutFgDataContextList = productionDispatchContextStepService.getMesWorkOrderCutFgDataContext(reqBean); // 如果当前存在成品列表则直接返回 @@ -100,8 +95,6 @@ public class MesFunctionCutOrderDialogPrintService extends BaseSwsService implem // 查成品列表 List mesCutSchemeFgs = workOrderCutService.queryCutSchemeFgList(cutWorkOrderNo, reqBean.getOrganizeCode()); - //Map partDataExtContext = productionDispatchContextStepService.getPartDataExtContext(reqBean); - mesWorkOrderCutFgDataContextList = new ArrayList<>(); for (MesCutSchemeFg mesCutSchemeFg : mesCutSchemeFgs) { @@ -112,13 +105,9 @@ public class MesFunctionCutOrderDialogPrintService extends BaseSwsService implem productionDispatchContextStepService.dispatchMesWorkOrderCutFgDataContext(reqBean, mesWorkOrderCutFgDataContextList); - log.info("MesFunctionCutOrderDialogPrintService --- stepDialogDispatch --- end --- value:{}", mesWorkOrderCutFgDataContextList); - return mesWorkOrderCutFgDataContextList; } - log.info("MesFunctionCutOrderDialogPrintService --- stepDialogDispatch --- end --- value:{}", mesWorkOrderCutFgDataContextList); - return mesWorkOrderCutFgDataContextList; } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesCustomDialogStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesCustomDialogStepService.java index b38e41a..c462323 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesCustomDialogStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesCustomDialogStepService.java @@ -4,11 +4,13 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IShippingDispatchService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService; +import cn.estsh.i3plus.mes.pcn.util.StringUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.bean.MesProdRouteOptParam; 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 com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -45,6 +47,7 @@ public class MesCustomDialogStepService extends BaseStepService { //弹框已经关闭 if (reqBean.getStepDialogStatus()) { + reqBean.setButtonCode(null); reqBean.setStepDialogStatus(false); return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean, stepResult, "弹框会话关闭!"); } @@ -62,6 +65,10 @@ public class MesCustomDialogStepService extends BaseStepService { //没有数据返回NULL则默认不需要弹框, 无须渲染动态数据时无须重写stepDialogDispatch方法且接口方法已默认返回true可以直接弹框 if (null == stepDialogContext) return stepResult; + if (!(stepDialogContext instanceof Boolean)) + log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- stepDialogContext:{}", + reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), JSONObject.toJSONString(stepDialogContext)); + //发送弹框数据 this.sendMessage(reqBean, resultBean.busiType(MesPcnEnumUtil.STATION_BUSI_TYPE.CUSTOM_COMPONENT.getValue()).dataType(MesPcnEnumUtil.STATION_DATA_TYPE.CUSTOM_DIALOG.getValue()).customPageName(customPageName).resultObj(stepDialogContext)); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckNosortStepService.java new file mode 100644 index 0000000..2ea32c0 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckNosortStepService.java @@ -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 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 productSnList2Jump = doHandleCraftJumpCode(reqBean, productionPsInContextList); + if (!CollectionUtils.isEmpty(productSnList2Jump)) + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList2Jump.toString()), stepResult, String.format("主条码%s跳过前道工艺防错验证成功!", productSnList2Jump.toString())); + + List 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> 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 productionPsInContextList) { + Optional optional = productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()))).findFirst(); + return (null == optional || !optional.isPresent()) ? false : true; + } + + //验证工位是否设置需要前道防错 + private Boolean isNeedCheckCraft(List productionPsInContextList) { + Optional 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> craftRouteDataMap) { + List craftRouteDetailList = fsmRouteDataService.handleProdCraftData(reqBean, workCenter.getCenterType(), partNo); + if (!CollectionUtils.isEmpty(craftRouteDetailList)) craftRouteDataMap.put(partNo, craftRouteDetailList); + } + + //验证是否存在工艺强过码, 存在则保存 并返回强过的主条码 + private List doHandleCraftJumpCode(StationRequestBean reqBean, List productionPsInContextList) { + + List 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 productionPsInContextList, Map> craftRouteDataMap) { + + List 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 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 craftRouteDetailList) { + + String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON; + + //判断主条码的当前工艺是否包含在产品工艺路线中 + Optional 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 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 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 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 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 unCompleteCraftList; + if (StringUtils.isEmpty(productionPsInContext.getCraftCode())) unCompleteCraftList = beforeCellCraftList; + else { + Optional 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 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 craftRouteDetailList) { + + String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON; + + //判断主条码的当前工艺是否包含在产品工艺路线中 + Optional 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 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 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 optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst(); + //根据当前工位对应的工艺 获取 所有前道工艺, 如果当前工位的工序对应工艺不在工艺路线明细内, 则默认所有明细均为所有前道工艺, 否则搜集当前工位工序对应工艺前面的所有前道工艺 + List 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> 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> prMapByCraft, String craftCode) { + return (CollectionUtils.isEmpty(prMapByCraft) || !prMapByCraft.containsKey(craftCode)) ? false : true; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckSortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckSortStepService.java new file mode 100644 index 0000000..2ea32c0 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProdCraftRouteCheckSortStepService.java @@ -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 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 productSnList2Jump = doHandleCraftJumpCode(reqBean, productionPsInContextList); + if (!CollectionUtils.isEmpty(productSnList2Jump)) + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList2Jump.toString()), stepResult, String.format("主条码%s跳过前道工艺防错验证成功!", productSnList2Jump.toString())); + + List 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> 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 productionPsInContextList) { + Optional optional = productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()))).findFirst(); + return (null == optional || !optional.isPresent()) ? false : true; + } + + //验证工位是否设置需要前道防错 + private Boolean isNeedCheckCraft(List productionPsInContextList) { + Optional 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> craftRouteDataMap) { + List craftRouteDetailList = fsmRouteDataService.handleProdCraftData(reqBean, workCenter.getCenterType(), partNo); + if (!CollectionUtils.isEmpty(craftRouteDetailList)) craftRouteDataMap.put(partNo, craftRouteDetailList); + } + + //验证是否存在工艺强过码, 存在则保存 并返回强过的主条码 + private List doHandleCraftJumpCode(StationRequestBean reqBean, List productionPsInContextList) { + + List 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 productionPsInContextList, Map> craftRouteDataMap) { + + List 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 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 craftRouteDetailList) { + + String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON; + + //判断主条码的当前工艺是否包含在产品工艺路线中 + Optional 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 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 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 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 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 unCompleteCraftList; + if (StringUtils.isEmpty(productionPsInContext.getCraftCode())) unCompleteCraftList = beforeCellCraftList; + else { + Optional 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 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 craftRouteDetailList) { + + String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON; + + //判断主条码的当前工艺是否包含在产品工艺路线中 + Optional 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 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 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 optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst(); + //根据当前工位对应的工艺 获取 所有前道工艺, 如果当前工位的工序对应工艺不在工艺路线明细内, 则默认所有明细均为所有前道工艺, 否则搜集当前工位工序对应工艺前面的所有前道工艺 + List 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> 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> prMapByCraft, String craftCode) { + return (CollectionUtils.isEmpty(prMapByCraft) || !prMapByCraft.containsKey(craftCode)) ? false : true; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java deleted file mode 100644 index 5f25a5f..0000000 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java +++ /dev/null @@ -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 prodRuleDataContext = productionDispatchContextStepService.getProdRuleDataContext(reqBean); - //获取产成零件信息 -// List productionPartContext = productionDispatchContextStepService.getProductionPartContext(reqBean); - //1. 校验当前有没有工单---只有有工单才能报工 - //如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号 -// List 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); - } - - } -} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java deleted file mode 100644 index edaa28a..0000000 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java +++ /dev/null @@ -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 prodRuleDataContext = productionDispatchContextStepService.getProdRuleDataContext(reqBean); - //如果产品加工规则中的foreignKey 和 mesProduceSns 一一对应的, - List mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); - //需要报工的条码 - List needReportSn = new ArrayList<>(); - for (MesProductionPsOutContext sn : mesProduceSns) { - Integer foreignKey = sn.getForeignKey(); - List 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 mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) { - //新增初始化 - Map> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo)); - Map mesPartMap = new HashMap<>(); - MesPart mesPart; - //查询工单状态 - Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()}; - for (Map.Entry> mesProduceSn : mesWorkOrderMap.entrySet()) { - List 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 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 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); - } - } - } -} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java deleted file mode 100644 index 14b9fe9..0000000 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java +++ /dev/null @@ -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 mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); - this.doProductReport(mesProduceSns, reqBean.getOrganizeCode(), reqBean.getUserInfo(),reqBean,resultBean); - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "报工成功"); - } - - public void doProductReport(List mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) { - //新增初始化 - Map> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo)); - Map mesPartMap = new HashMap<>(); - MesPart mesPart; - //查询工单状态 - Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()}; - for (Map.Entry> mesProduceSn : mesWorkOrderMap.entrySet()) { - List 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 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 mesProductOffLineList = new ArrayList<>(); - List mesMoveList = new ArrayList<>(); - //条码 - List snList = mesProduceSnList.stream().map(MesProduceSn::getProductSn).collect(Collectors.toList()); - //物料信息 - Map> 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 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> customerSupplyMove(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, List mesBoms, List resultList, List mesProductOffLineList, List mesMoveList, String workCenterCode) { - boolean isItemMove; - boolean isItemReport; - MesMoveRule moveRule; - //查询零件生产组的移库规则 - List moveRules = this.findMesMoveRuleByPartProdGroupCode(mesWorkOrder.getPartProdGroupCode(), mesWorkOrder.getOrganizeCode()); - Map> mesMoveRuleMap = moveRules.stream().filter(t -> Objects.nonNull(t.getSrcType())).collect(Collectors.groupingBy(MesMoveRule::getSrcType)); - List itemPartNoList = mesBoms.stream().map(MesBom::getItemPartNo).collect(Collectors.toList()); - //子物料SAP下发信息 - Map> mesPartSapMap = getPartSapMap(mesWorkOrder, itemPartNoList); - //获取物料信息 - Map> 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 findMesMoveRuleByPartProdGroupCode(String partProdGroupCode, String organizeCode) { - DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); - DdlPreparedPack.getStringEqualPack(partProdGroupCode, "partProdGroupCode", ddlPackBean); - List moveRules = moveRuleRao.findByHqlWhere(ddlPackBean); - return moveRules; - } - - private Map> getPartSapMap(MesWorkOrder mesWorkOrder, List itemPartNoList) { - DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); - DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean); - List mesPartSapList = mesPartSapRao.findByHqlWhere(ddlPackBean); - Map> mesPartSapMap = mesPartSapList.stream().filter(t -> Objects.nonNull(t.getPartNo())).collect(Collectors.groupingBy(MesPartSap::getPartNo)); - return mesPartSapMap; - } - - private Map> getItemPartMap(MesWorkOrder mesWorkOrder, List itemPartNoList) { - DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); - DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean); - List mesPartList = partRao.findByHqlWhere(ddlPackBean); - Map> 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; - } -}