diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java index 57525ca..508d3f6 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java @@ -1,8 +1,6 @@ package cn.estsh.i3plus.ext.mes.pcn.api.busi; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdShiftContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; @@ -115,4 +113,7 @@ public interface IMesProductionCustomContextStepService { @ApiOperation(value = "删除排序线工单队列推送锁数据") void removeSortQueuePushLockContext(StationRequestBean reqBean, String queuePushId); + @ApiOperation(value = "处理工位维度的工单完成数上下文") + MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyCellContext(Integer flag, StationRequestBean reqBean, MesProductionPartContext productionPartContext, Double calcCompleteQty); + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java index 1eee104..f976490 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java @@ -204,6 +204,7 @@ public class MesQueueOrderPushService implements IMesQueueOrderPushService { DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.WORK_CENTER_CODE), MesPcnExtConstWords.WORK_CENTER_CODE, packBean); DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.PART_NO), MesPcnExtConstWords.PART_NO, packBean); DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.PART_PROD_GROUP_CODE), MesPcnExtConstWords.PART_PROD_GROUP_CODE, packBean); + DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.CUST_ORDER_NO), MesPcnExtConstWords.PART_PROD_GROUP_CODE, packBean); DdlPreparedPack.getStringLikerPack(paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO), MesPcnExtConstWords.WORK_ORDER_NO, packBean); DdlPreparedPack.getStringLikerPack(paramMap.get(MesPcnExtConstWords.CUST_SN), MesPcnExtConstWords.CUST_SN, packBean); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionQueueOrderPushService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionQueueOrderPushService.java index 91f2f8f..4c419da 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionQueueOrderPushService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionQueueOrderPushService.java @@ -193,7 +193,7 @@ public class MesFunctionQueueOrderPushService extends BaseSwsService implements Integer processSeq; if (!StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ))) processSeq = Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ)); else if (!StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP))) processSeq = queueOrderPushService.getQueueOrderPushCalcSeq(reqBean.getOrganizeCode(), optional.get(), Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP))); - else processSeq = Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP)) + 1; + else processSeq = Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_DOWN)) + 1; //根据条件修改生产队列工位推送信息 queueOrderPushService.saveQueueOrderPushByCondition( new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID}, diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java index 6aedb9b..d7d0352 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java @@ -1,6 +1,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; import cn.estsh.i3plus.ext.mes.pcn.api.busi.*; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService; @@ -60,6 +61,9 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { @Autowired private IFsmCommonService fsmCommonService; + @Autowired + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; + @Override public StepResult execute(StationRequestBean reqBean) { @@ -102,6 +106,9 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //封装非排序加工规则 doHandleProdRuleData(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList); + //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则 + workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList); + //匹配失败需要清除本次扫描/读取信息 if (!stepResult.isCompleted() && doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList)) return stepResult.nextTriggerEvent(CollectionUtils.isEmpty(productionPsInContextList) ? MesPcnExtConstWords.NEXT_TRIGGER_EVENT_PART_NO : (!StringUtils.isEmpty(stepResult.getObj()) ? MesPcnExtConstWords.NEXT_TRIGGER_EVENT_PART_NO : MesPcnExtConstWords.NEXT_TRIGGER_EVENT_PRODUCT_SN)); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java index 65f14b2..1e9b89c 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java @@ -5,6 +5,7 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService; 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.apiservice.serviceimpl.step.method.MesPartDataMapSaveStepService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService; @@ -74,6 +75,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { @Autowired private IMesProdShiftRecordService prodShiftRecordService; + @Autowired + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; + @Override public StepResult execute(StationRequestBean reqBean) { @@ -154,9 +158,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { MesPart part = partDataMap.get(prodRuleContext.getOutPartNo()); //验证进料零件与产出零件是否一致 - Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, prodRuleContext); + Boolean isSamePart = workOrderCheckCompleteQtyStepService.isSamePart(productionPsInContext, productionPartContext, prodRuleContext); //工位是否不累计工单完成数 - Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty()); + Boolean isCellNoCalcQty = workOrderCheckCompleteQtyStepService.isCellNoCalcQty(workCell.getNoCalcOrderQty()); MesProduceSn produceSn; //进出一致, 不累计工单完成数量 在显示装配件工步中已经验证了 进出一致 进出存在工单则必须一致 @@ -222,7 +226,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { produceSn = produceSnExtService.insert(produceSn); } else produceSnExtService.updateNoSync(produceSn); - MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().copy(produceSn, prodRuleContext.getForeignKey()).isCalcCompleteQty(isCalcCompleteQty(isCellNoCalcQty, isSamePart, productionPartContext)); + MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext() + .copy(produceSn, prodRuleContext.getForeignKey()) + .isCalcCompleteQty(isCalcCompleteQty(isCellNoCalcQty, isSamePart, productionPartContext)); log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- MesProduceSn:{} --- MesProductionPsOutContext:{}", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), @@ -256,24 +262,6 @@ public class MesProductSnGenerateStepService extends BaseStepService { return part.getProductMatchRule(); } - //验证进料零件与产出零件是否一致 - private Boolean isSamePart(MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext, MesProdRuleContext prodRuleContext) { - if (null == productionPsInContext) return false; - if (StringUtils.isEmpty(productionPsInContext.getPartNo())) return false; - if (null != productionPartContext) { - if (!productionPsInContext.getPartNo().equals(productionPartContext.getPartNo())) return false; - else return true; - } else { - if (!productionPsInContext.getPartNo().equals(prodRuleContext.getOutPartNo())) return false; - else return true; - } - } - - //工位是否不累计工单完成数 - private Boolean isCellNoCalcQty(Integer noCalcOrderQty) { - return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false; - } - //判断是否累计工单完成数 private Boolean isCalcCompleteQty(Boolean isCellNoCalcQty, Boolean isSamePart, MesProductionPartContext productionPartContext) { //工位不消耗工单完成数 diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java index 3836714..aacf96e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java @@ -1,12 +1,11 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.context; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdShiftContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; 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.util.StationKvBeanUtil; +import cn.estsh.i3plus.platform.common.tool.MathOperation; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; @@ -327,4 +326,28 @@ public class MesProductionCustomContextStepService extends BaseStepService imple removeFsmBusiData(reqBean.getOrganizeCode(), getSortQueuePushLockContextKey(reqBean), queuePushId); } + //工单完成数工位维度KEY + private String getWorkOrderCompleteQtyContextCellKey(StationRequestBean reqBean, String workOrderNo) { + return new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()).add(reqBean.getWorkCellCode()).add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).add(workOrderNo).toString(); + } + + //处理工位维度的工单完成数上下文 + @Override + public MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyCellContext(Integer flag, StationRequestBean reqBean, MesProductionPartContext productionPartContext, Double calcCompleteQty) { + String key = getWorkOrderCompleteQtyContextCellKey(reqBean, productionPartContext.getWorkOrderNo()); + String context = getFsmBusiData(reqBean.getOrganizeCode(), key); + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = !StringUtils.isEmpty(context) + ? JSONObject.parseObject(context, MesWorkOrderCompleteQtyContext.class) + : new MesWorkOrderCompleteQtyContext(productionPartContext.getWorkOrderNo(), productionPartContext.getQty(), productionPartContext.getCompleteQty()); + //假如缓存中的完成数小于当前传参工单的完成数,则覆盖 + if (!StringUtils.isEmpty(context) && MathOperation.compareTo(productionPartContext.getCompleteQty(), workOrderCompleteQtyContext.getCompleteQty()) > 0) workOrderCompleteQtyContext.overrideCompleteQty(productionPartContext.getCompleteQty()); + //判断标志当前是否是累计上下文的完成数 + if (flag == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) workOrderCompleteQtyContext.overrideCompleteQty(MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty)); + //判断是否需要存储 + if (StringUtils.isEmpty(context) || flag == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) dispatchFsmBusiData(reqBean.getOrganizeCode(), key, JSONObject.toJSONString(workOrderCompleteQtyContext)); + return workOrderCompleteQtyContext; + } + + + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java index 7164787..a179a5a 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java @@ -1,8 +1,25 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +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 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 : 加工单验证工单完成数量通用工步方法 @@ -12,4 +29,155 @@ import org.springframework.stereotype.Service; @Service("mesWorkOrderCheckCompleteQtyStepService") public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + //flag=1【验证+临时存储】; flag=2【累加完成数+删除临时存储】 + //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单; + public void dispatchWorkOrderCompleteQtyContext(Integer flag, StationRequestBean reqBean, StationResultBean resultBean, + StepResult stepResult, MesProductionProcessContext productionProcessContext, + List productionPartContextList, List productionPsInContextList) { + //是否存在产成零件信息 + if (!stepResult.isCompleted() || CollectionUtils.isEmpty(productionPartContextList)) return; + + //根据产出零件或者腔数拿到需要的加工规则数量, 优先使用产出零件数量 + Integer needQty = !CollectionUtils.isEmpty(productionPartContextList) ? productionPartContextList.size() : productionProcessContext.getCurCellEquip().getCavity(); + //验证是否满足腔数 + if (!CollectionUtils.isEmpty(productionPsInContextList) && productionPsInContextList.size() < needQty) return; + + //对MesProductionPartContext中的工单号经行分组,每个工单可能对应多条数据, 筛选掉foreignkey为空的数据 + Map> productionPartContextMap = productionPartContextList.stream().filter(o -> + (!StringUtils.isEmpty(o.getWorkOrderNo()) && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo)); + + if (CollectionUtils.isEmpty(productionPartContextMap)) return; + + //根据foreignkey分组进料零件条码 + Map productionPsInContextMap = CollectionUtils.isEmpty(productionPsInContextList) ? null : + productionPsInContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsInContext::getForeignKey, o -> o)); + + //生产线与工位信息 + MesWorkCenter workCenter = productionProcessContext.getWorkCenter(); + MesWorkCell workCell = productionProcessContext.getWorkCell(); + //工位是否不累计工单完成数 + Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty()); + + for (Map.Entry> entry : productionPartContextMap.entrySet()) { + if (null == entry) continue; + dispatchWorkOrderCompleteQty(flag, reqBean, resultBean, stepResult, workCenter, isCellNoCalcQty, entry.getValue(), productionPsInContextMap); + } + + } + + //验证加工单完成数量 + private void dispatchWorkOrderCompleteQty(Integer flag, StationRequestBean reqBean, StationResultBean resultBean, + StepResult stepResult, MesWorkCenter workCenter, Boolean isCellNoCalcQty, + List productionPartContextList, Map productionPsInContextMap) { + Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO); + for (MesProductionPartContext productionPartContext : productionPartContextList) { + //验证进料零件与产出零件是否一致 + Boolean isSamePart = isSamePart(getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey()), productionPartContext, null); + //如果进出不一致,则累加完成数 + if (!isSamePart) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE)); + } + //当前工单无须计算工单完成数 + if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return; + + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext; + + //工位维度=true ; 生产线维度=false,需要LOCK + if (isCellNoCalcQty) { + //处理工位维度的工单完成数上下文 + workOrderCompleteQtyContext = productionCustomContextStepService.dispatchWorkOrderCompleteQtyCellContext(flag, reqBean, productionPartContextList.get(0), calcCompleteQty); + //已经在上下文中累加当前工序的工单完成数 + if (flag == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) return; + //验证工单完成数 + checkWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, workOrderCompleteQtyContext, calcCompleteQty); + + + return; + } + + } + + //根据数据关联键获取进料零件信息 + private MesProductionPsInContext getProductionPsInContext(Map productionPsInContextMap, Integer foreignKey) { + if (CollectionUtils.isEmpty(productionPsInContextMap) || StringUtils.isEmpty(foreignKey)) return null; + return productionPsInContextMap.get(foreignKey); + } + + //验证进料零件与产出零件是否一致 + public Boolean isSamePart(MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext, MesProdRuleContext prodRuleContext) { + if (null == productionPsInContext) return false; + if (StringUtils.isEmpty(productionPsInContext.getPartNo())) return false; + if (null != productionPartContext) { + if (!productionPsInContext.getPartNo().equals(productionPartContext.getPartNo())) return false; + else return true; + } else { + if (!productionPsInContext.getPartNo().equals(prodRuleContext.getOutPartNo())) return false; + else return true; + } + } + + //工位是否不累计工单完成数 + public Boolean isCellNoCalcQty(Integer noCalcOrderQty) { + return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false; + } + + //验证工单完成数 + private void checkWorkOrderCompleteQty(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, + MesWorkCenter workCenter, MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext, Double calcCompleteQty) { + + //当前工序的预计达到的完成数 + Double complateQty = MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty); + // 如果预完成数量 小于等于工单数量,则直接过 + if (MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), complateQty) >= 0) return; + if (StringUtils.isEmpty(workCenter.getIsCheckOrderQty()) || workCenter.getIsCheckOrderQty().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0) { + productionPartContextList.forEach(o -> o.busiCheckToDelete()); + if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), + MathOperation.compareTo(mesWorkOrder.getQty(), mesWorkOrder.getCompleteQty()) == 0 + ? String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前已完成!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue()) + : String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前不支持超工单!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue())); + } + } + + private StepResult validSuperWorkOrder(StationRequestBean reqBean, List productionPartContextList, List productionPsInContextList, MesWorkCenter workCenter, StepResult stepResult, StationResultBean resultBean) { + + // 对工单经行分组 + Map> orderListMap = workOrderList.stream().collect(Collectors.groupingBy(MesWorkOrder::getWorkOrderNo)); + + for (Map.Entry> entry : productionPartContextMap.entrySet()) { + String workOrder = entry.getKey(); + List productionPartContexts = entry.getValue(); + MesWorkOrder mesWorkOrder = orderListMap.get(workOrder).get(0); + + Double complateQty = mesWorkOrder.getCompleteQty() + productionPartContexts.size(); + Double qty = mesWorkOrder.getQty(); + log.info("验证超工单,工单号【{}】,qty=【{}】,complateQty =【{}】begin ->", mesWorkOrder.getWorkOrderNo(), qty, complateQty); + // 如果预完成数量 小于等于工单数量,则直接过 + if (complateQty <= qty) continue; + + // 以下则是超工单逻辑 + // 如果产线中没有配置超工单,则直接阻断 + if (!Objects.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), workCenter.getIsCheckOrderQty())) { + productionPartContextList.forEach(o -> o.busiCheckToDelete()); + if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), + MathOperation.compareTo(mesWorkOrder.getQty(), mesWorkOrder.getCompleteQty()) == 0 + ? String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前已完成!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue()) + : String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前不支持超工单!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue())); + } + // 如果配置了超工单,且比例已经超过了配置的超工单比例,也需要阻断 + Double rate = (complateQty - qty)/qty; + if (rate > workCenter.getOrderRate()/100) { + productionPartContextList.forEach(o -> o.busiCheckToDelete()); + if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), + String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前超出超工单比例[%s]!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue(), workCenter.getOrderRate())); + } + log.info("验证超工单,工单号【{}】,qty=【{}】,complateQty =【{}】,isCheckOrderQty=【{}】, rate = 【{}】end ->", mesWorkOrder.getWorkOrderNo(), qty, complateQty,workCenter.getIsCheckOrderQty(),rate); + } + log.info("验证是否超工单end ->"); + return stepResult; + } } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java new file mode 100644 index 0000000..40047dd --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java @@ -0,0 +1,37 @@ +package cn.estsh.i3plus.ext.mes.pcn.pojo.context; + +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import io.swagger.annotations.ApiParam; +import lombok.Data; +import org.springframework.util.StringUtils; + +import java.io.Serializable; + +/** + * 生产过程上下文对象-加工单完成数 + */ +@Data +public class MesWorkOrderCompleteQtyContext implements Serializable { + + private static final long serialVersionUID = -1602007855074296100L; + + @ApiParam("生产工单号") + private String workOrderNo; + + @ApiParam("工单数量") + private Double qty; + + @ApiParam("完成数量") + private Double completeQty; + + public MesWorkOrderCompleteQtyContext(String workOrderNo, Double qty, Double completeQty) { + this.workOrderNo = workOrderNo; + this.qty = qty; + this.completeQty = StringUtils.isEmpty(completeQty) ? new Double(MesPcnExtConstWords.ZERO) : completeQty; + } + + public MesWorkOrderCompleteQtyContext overrideCompleteQty(Double completeQty) { + this.completeQty = completeQty; + return this; + } +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java index 12b354b..fe9f962 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java @@ -655,6 +655,8 @@ public class MesPcnExtConstWords { public static final String QUEUE_PUSH_LOCK_CONTEXT = "QUEUE_PUSH_LOCK_CONTEXT"; // 推送队列上下文 public static final String QUEUE_PUSH_CONTEXT = "QUEUE_PUSH_CONTEXT"; + // 工单完成数上下文 + public static final String WORK_ORDER_COMPLETE_CONTEXT = "WORK_ORDER_COMPLETE_CONTEXT"; // 上下文: 展示组件数据 public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";