|
|
@ -8,17 +8,18 @@ import cn.estsh.i3plus.platform.common.tool.MathOperation;
|
|
|
|
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
|
|
|
|
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
|
|
|
|
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.StationRequestBean;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
|
|
|
import cn.estsh.i3plus.pojo.mes.model.StepResult;
|
|
|
|
|
|
|
|
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -32,7 +33,7 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
private IMesProductionCustomContextStepService productionCustomContextStepService;
|
|
|
|
private IMesProductionCustomContextStepService productionCustomContextStepService;
|
|
|
|
|
|
|
|
|
|
|
|
//flag=1【验证+临时存储】; flag=2【累加完成数+删除临时存储】
|
|
|
|
//flag=1【验证】; flag=2【累加完成数】
|
|
|
|
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单;
|
|
|
|
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单;
|
|
|
|
public void dispatchWorkOrderCompleteQtyContext(Integer flag, StationRequestBean reqBean, StationResultBean resultBean,
|
|
|
|
public void dispatchWorkOrderCompleteQtyContext(Integer flag, StationRequestBean reqBean, StationResultBean resultBean,
|
|
|
|
StepResult stepResult, MesProductionProcessContext productionProcessContext,
|
|
|
|
StepResult stepResult, MesProductionProcessContext productionProcessContext,
|
|
|
@ -61,9 +62,19 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
|
|
|
|
//工位是否不累计工单完成数
|
|
|
|
//工位是否不累计工单完成数
|
|
|
|
Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty());
|
|
|
|
Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//遍历验证加工单完成数量
|
|
|
|
for (Map.Entry<String, List<MesProductionPartContext>> entry : productionPartContextMap.entrySet()) {
|
|
|
|
for (Map.Entry<String, List<MesProductionPartContext>> entry : productionPartContextMap.entrySet()) {
|
|
|
|
if (null == entry) continue;
|
|
|
|
if (null == entry) continue;
|
|
|
|
|
|
|
|
//验证加工单完成数量
|
|
|
|
dispatchWorkOrderCompleteQty(flag, reqBean, resultBean, stepResult, workCenter, isCellNoCalcQty, entry.getValue(), productionPsInContextMap);
|
|
|
|
dispatchWorkOrderCompleteQty(flag, reqBean, resultBean, stepResult, workCenter, isCellNoCalcQty, entry.getValue(), productionPsInContextMap);
|
|
|
|
|
|
|
|
//验证失败直接退出
|
|
|
|
|
|
|
|
if (!stepResult.isCompleted()) break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//验证失败标记删除标志
|
|
|
|
|
|
|
|
if (!stepResult.isCompleted()) {
|
|
|
|
|
|
|
|
productionPartContextList.forEach(o -> o.busiCheckToDelete());
|
|
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -74,25 +85,32 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
|
|
|
|
List<MesProductionPartContext> productionPartContextList, Map<Integer, MesProductionPsInContext> productionPsInContextMap) {
|
|
|
|
List<MesProductionPartContext> productionPartContextList, Map<Integer, MesProductionPsInContext> productionPsInContextMap) {
|
|
|
|
Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO);
|
|
|
|
Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO);
|
|
|
|
for (MesProductionPartContext productionPartContext : productionPartContextList) {
|
|
|
|
for (MesProductionPartContext productionPartContext : productionPartContextList) {
|
|
|
|
|
|
|
|
MesProductionPsInContext productionPsInContext = getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey());
|
|
|
|
//验证进料零件与产出零件是否一致
|
|
|
|
//验证进料零件与产出零件是否一致
|
|
|
|
Boolean isSamePart = isSamePart(getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey()), productionPartContext, null);
|
|
|
|
Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, null);
|
|
|
|
//如果进出不一致,则累加完成数
|
|
|
|
//验证是否计数
|
|
|
|
if (!isSamePart) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE));
|
|
|
|
Boolean isCalcCompleteQty = isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext);
|
|
|
|
|
|
|
|
if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//当前工单无须计算工单完成数
|
|
|
|
//当前工单无须计算工单完成数
|
|
|
|
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return;
|
|
|
|
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//处理工位维度的工单完成数上下文
|
|
|
|
//处理工位维度的工单完成数上下文
|
|
|
|
workOrderCompleteQtyContext = productionCustomContextStepService.dispatchWorkOrderCompleteQtyCellContext(flag, reqBean, productionPartContextList.get(0), calcCompleteQty);
|
|
|
|
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = productionCustomContextStepService.dispatchWorkOrderCompleteQtyCellContext(flag, isCellNoCalcQty, reqBean, productionPartContextList.get(0), calcCompleteQty);
|
|
|
|
//已经在上下文中累加当前工序的工单完成数
|
|
|
|
|
|
|
|
|
|
|
|
//flag=2【累加完成数】
|
|
|
|
if (flag == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) return;
|
|
|
|
if (flag == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) return;
|
|
|
|
|
|
|
|
|
|
|
|
//验证工单完成数
|
|
|
|
//验证工单完成数
|
|
|
|
checkWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, workOrderCompleteQtyContext, calcCompleteQty);
|
|
|
|
checkWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, workOrderCompleteQtyContext, calcCompleteQty);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//工位是否不累计工单完成数
|
|
|
|
|
|
|
|
public Boolean isCellNoCalcQty(Integer noCalcOrderQty) {
|
|
|
|
|
|
|
|
return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//根据数据关联键获取进料零件信息
|
|
|
|
//根据数据关联键获取进料零件信息
|
|
|
|
private MesProductionPsInContext getProductionPsInContext(Map<Integer, MesProductionPsInContext> productionPsInContextMap, Integer foreignKey) {
|
|
|
|
private MesProductionPsInContext getProductionPsInContext(Map<Integer, MesProductionPsInContext> productionPsInContextMap, Integer foreignKey) {
|
|
|
|
if (CollectionUtils.isEmpty(productionPsInContextMap) || StringUtils.isEmpty(foreignKey)) return null;
|
|
|
|
if (CollectionUtils.isEmpty(productionPsInContextMap) || StringUtils.isEmpty(foreignKey)) return null;
|
|
|
@ -112,9 +130,19 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//工位是否不累计工单完成数
|
|
|
|
//验证是否计数
|
|
|
|
public Boolean isCellNoCalcQty(Integer noCalcOrderQty) {
|
|
|
|
private Boolean isCalcCompleteQty(Boolean isSamePart, MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext) {
|
|
|
|
return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false;
|
|
|
|
//未选工单场景
|
|
|
|
|
|
|
|
if (null == productionPartContext || StringUtils.isEmpty(productionPartContext.getWorkOrderNo())) return false;
|
|
|
|
|
|
|
|
//进出不一致
|
|
|
|
|
|
|
|
if (!isSamePart) return true;
|
|
|
|
|
|
|
|
//进出一致的情况下: 【打印件已经是产成的情况下也需要计数】
|
|
|
|
|
|
|
|
if (!StringUtils.isEmpty(productionPsInContext.getId()) && StringUtils.isEmpty(productionPsInContext.getProcessCode()) &&
|
|
|
|
|
|
|
|
!StringUtils.isEmpty(productionPsInContext.getPrintStatus()) && productionPsInContext.getPrintStatus().compareTo(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue()) == 0) {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//进出一致
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//验证工单完成数
|
|
|
|
//验证工单完成数
|
|
|
@ -125,53 +153,22 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
|
|
|
|
Double complateQty = MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty);
|
|
|
|
Double complateQty = MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty);
|
|
|
|
// 如果预完成数量 小于等于工单数量,则直接过
|
|
|
|
// 如果预完成数量 小于等于工单数量,则直接过
|
|
|
|
if (MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), complateQty) >= 0) return;
|
|
|
|
if (MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), complateQty) >= 0) return;
|
|
|
|
|
|
|
|
//判断不支持超工单生产
|
|
|
|
if (StringUtils.isEmpty(workCenter.getIsCheckOrderQty()) || workCenter.getIsCheckOrderQty().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0) {
|
|
|
|
if (StringUtils.isEmpty(workCenter.getIsCheckOrderQty()) || workCenter.getIsCheckOrderQty().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0) {
|
|
|
|
productionPartContextList.forEach(o -> o.busiCheckToDelete());
|
|
|
|
//stepResult.obj(false)目的是在工步最后可以判断是否需要清除进料
|
|
|
|
if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete());
|
|
|
|
stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s]!",
|
|
|
|
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false),
|
|
|
|
workOrderCompleteQtyContext.getWorkOrderNo(), workOrderCompleteQtyContext.getQty().intValue(), workOrderCompleteQtyContext.getCompleteQty().intValue(),
|
|
|
|
MathOperation.compareTo(mesWorkOrder.getQty(), mesWorkOrder.getCompleteQty()) == 0
|
|
|
|
MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), workOrderCompleteQtyContext.getCompleteQty()) == 0 ? "当前已完成!" : "当前不支持超工单!"));
|
|
|
|
? String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前已完成!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue())
|
|
|
|
return;
|
|
|
|
: String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前不支持超工单!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue()));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//支持超工单生产情况下判断超出比例
|
|
|
|
|
|
|
|
Double rate = MathOperation.div((MathOperation.sub(complateQty, workOrderCompleteQtyContext.getQty())), workOrderCompleteQtyContext.getQty());
|
|
|
|
|
|
|
|
if (MathOperation.compareTo(rate, MathOperation.div(workCenter.getOrderRate(), new Double(MesPcnExtConstWords.ONE_HUNDRED))) > 0) {
|
|
|
|
|
|
|
|
stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false),
|
|
|
|
|
|
|
|
String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前超出超工单比例[%s]!",
|
|
|
|
|
|
|
|
workOrderCompleteQtyContext.getWorkOrderNo(), workOrderCompleteQtyContext.getQty().intValue(), workOrderCompleteQtyContext.getCompleteQty().intValue(), workCenter.getOrderRate()));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private StepResult validSuperWorkOrder(StationRequestBean reqBean, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList, MesWorkCenter workCenter, StepResult stepResult, StationResultBean resultBean) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 对工单经行分组
|
|
|
|
|
|
|
|
Map<String, List<MesWorkOrder>> orderListMap = workOrderList.stream().collect(Collectors.groupingBy(MesWorkOrder::getWorkOrderNo));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, List<MesProductionPartContext>> entry : productionPartContextMap.entrySet()) {
|
|
|
|
|
|
|
|
String workOrder = entry.getKey();
|
|
|
|
|
|
|
|
List<MesProductionPartContext> 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;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|