前道防错工步

tags/yfai-pcn-ext-v1.0
王杰 11 months ago
parent 69603b0aee
commit a6cac78e8d

@ -29,6 +29,9 @@ public interface IMesProductionRecordService {
*/
Map<String, Object> checkSnTimeliness(String organizeCode, String serialNo, Long sourceId, Integer dataSource, Boolean isAssembly);
@ApiOperation(value = "根据零件条码查询加工记录信息")
List<MesProductionRecord> findProductionRecordList(String organizeCode, String productSn);
@ApiOperation(value = "根据零件条码,物料编码,工序代码,工艺代码查询加工记录信息")
List<MesProductionRecord> findProductionRecordList(String organizeCode, String productSn, String partNo, String processCode, String craftCode);

@ -12,9 +12,9 @@ import cn.estsh.i3plus.pojo.mes.repository.MesProductionAssemblyRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesProductionRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesTimeEfficientCfgRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@ -134,11 +134,11 @@ public class MesProductionRecordService implements IMesProductionRecordService {
for (MesTimeEfficientCfg timeliness : timelinessList) {
List<MesProductionRecord> records = new ArrayList<>();
//时效性规则 零件号不为空
if (StringUtils.isNoneBlank(timeliness.getPartNo())){
if (!StringUtils.isEmpty(timeliness.getPartNo())){
records = recordList.stream().filter(item -> item.getPartNo().equals(timeliness.getPartNo())).sorted(Comparator.comparing(MesProductionRecord::getCompleteDateTime)).collect(Collectors.toList());
}
//时效性规则 工艺不为空时
if (StringUtils.isNoneBlank(timeliness.getCraftCode())){
if (!StringUtils.isEmpty(timeliness.getCraftCode())){
records = recordList.stream().filter(item -> item.getCraftCode().equals(timeliness.getCraftCode())).sorted(Comparator.comparing(MesProductionRecord::getCompleteDateTime)).collect(Collectors.toList());
}
@ -192,7 +192,16 @@ public class MesProductionRecordService implements IMesProductionRecordService {
}
@Override
public List<MesProductionRecord> findProductionRecordList(String organizeCode, String productSn) {
if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(productSn)) return null;
return productionRecordRepository.findByProperty(
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.PRODUCT_SN},
new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), productSn});
}
@Override
public List<MesProductionRecord> findProductionRecordList(String organizeCode, String productSn, String partNo, String processCode, String craftCode) {
if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(productSn) || StringUtils.isEmpty(partNo) || StringUtils.isEmpty(processCode) || StringUtils.isEmpty(craftCode)) return null;
return productionRecordRepository.findByProperty(
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.PRODUCT_SN, MesPcnExtConstWords.PART_NO, MesPcnExtConstWords.PROCESS_CODE, MesPcnExtConstWords.CRAFT_CODE},
new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), productSn, partNo, processCode, craftCode});

@ -12,9 +12,11 @@ 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;
@ -79,24 +81,27 @@ public class MesProdCraftRouteCheckStepService extends BaseStepService {
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 execSuccessCompleteAndSendMsgReturn(reqBean, resultBean, stepResult, "主条码均已通过前道工艺防错验证!");
//从上下文中取出生产线对象
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//查询工艺路线数据
Map<String, List<MesCraftRouteDetail>> craftRouteDataMap = new HashMap<>();
partNoList.forEach(o -> doHandleProdCraftData(reqBean, o, craftRouteDataMap));
partNoList.forEach(o -> doHandleProdCraftData(reqBean, workCenter, o, craftRouteDataMap));
if (CollectionUtils.isEmpty(craftRouteDataMap) || craftRouteDataMap.size() != partNoList.size())
return execNonCompleteAndSendMsgReturn(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, productionPsInContextList, craftRouteDataMap);
doHandleProdCraftRouteCheck(reqBean, resultBean, stepResult, productionProcessContext, workCenter, productionPsInContextList, craftRouteDataMap);
return stepResult;
}
//查询工艺路线数据
private void doHandleProdCraftData(StationRequestBean reqBean, String o, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
List<MesCraftRouteDetail> craftRouteDetailList = fsmRouteDataService.doHandleProdCraftData(reqBean, o);
private void doHandleProdCraftData(StationRequestBean reqBean, MesWorkCenter workCenter, String o, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
List<MesCraftRouteDetail> craftRouteDetailList = fsmRouteDataService.doHandleProdCraftData(reqBean, workCenter.getCenterType(), o);
if (!CollectionUtils.isEmpty(craftRouteDetailList)) craftRouteDataMap.put(o, craftRouteDetailList);
}
@ -126,14 +131,14 @@ public class MesProdCraftRouteCheckStepService extends BaseStepService {
//前道工艺防错验证处理
private void doHandleProdCraftRouteCheck(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesProductionPsInContext> productionPsInContextList, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
MesWorkCenter workCenter, List<MesProductionPsInContext> productionPsInContextList, Map<String, List<MesCraftRouteDetail>> craftRouteDataMap) {
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
if (null == productionPsInContext || StringUtils.isEmpty(productionPsInContext.getPartNo()) || productionPsInContext.getIsCheckCraft().compareTo(MesPcnExtConstWords.ZERO) != 0) continue;
//前道工艺防错验证
Boolean result = doProdCraftRouteCheck(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDataMap.get(productionPsInContext.getPartNo()));
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());
@ -149,7 +154,18 @@ public class MesProdCraftRouteCheckStepService extends BaseStepService {
}
//前道工艺防错验证
private Boolean doProdCraftRouteCheck(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
private Boolean doProdCraftRouteCheck(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesWorkCenter workCenter, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
//排序
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.SORT.getValue()) == 0) return doProdCraftRouteCheckSort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
//非排序
return doProdCraftRouteCheckNosort(reqBean, stepResult, productionProcessContext, productionPsInContext, craftRouteDetailList);
}
//前道工艺防错验证【排序】
private Boolean doProdCraftRouteCheckSort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
@ -193,10 +209,10 @@ public class MesProdCraftRouteCheckStepService extends BaseStepService {
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)
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过首道工艺[%s]", message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftCode())).isCompleted();
@ -213,15 +229,83 @@ public class MesProdCraftRouteCheckStepService extends BaseStepService {
//如果没有未完成的工艺, 则代表当前工位可操作
if (CollectionUtils.isEmpty(unCompleteCraftList)) return true;
//未完成工艺重新正
unCompleteCraftList = unCompleteCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq)).collect(Collectors.toList());
//未完成工艺
unCompleteCraftList = unCompleteCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq).reversed()).collect(Collectors.toList());
Optional<MesCraftRouteDetail> optional = unCompleteCraftList.stream().filter(o -> (null != o && o.getIsChoose() == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue())).findFirst();
if (null != optional && optional.isPresent())
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), optional.get().getCraftCode())).isCompleted();
if (unCompleteCraftList.get(0).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), unCompleteCraftList.get(0).getCraftCode())).isCompleted();
return true;
}
//前道工艺防错验证 【非排序】
private Boolean doProdCraftRouteCheckNosort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesProductionPsInContext productionPsInContext, List<MesCraftRouteDetail> craftRouteDetailList) {
String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON;
//判断主条码的当前工艺是否包含在产品工艺路线中
Optional<MesCraftRouteDetail> optionalPs = StringUtils.isEmpty(productionPsInContext.getCraftCode()) ? null : craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionPsInContext.getCraftCode()))).findFirst();
if (!StringUtils.isEmpty(productionPsInContext.getCraftCode()) && (null == optionalPs || !optionalPs.isPresent()))
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]对应的工艺代码[%s]不匹配零件[%s]对应的产品工艺路线[%s]",
message, productionPsInContext.getProductSn(), productionPsInContext.getCraftCode(), productionPsInContext.getPartNo(), craftRouteDetailList.get(0).getCraftRouteCode())).isCompleted();
//验证工艺对应工序最多经过1个: 当前主条码的工艺字段有值, 对应的工艺路线明细信息设置了【true】, 当前工位的工艺与主条码的当前工艺相同, 当前工位的工序与主条码的当前工序不相同
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getAtMostProcess().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionProcessContext.getCraftCode().equals(productionPsInContext.getCraftCode()) && !reqBean.getProcessCode().equals(productionPsInContext.getProcessCode()))
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]相同工艺对应工序最多经过1个,上道工艺[%s]当前工位工艺[%s]",
message, productionPsInContext.getProductSn(), craftRouteDetailList.get(0).getCraftRouteCode(), productionPsInContext.getCraftCode(), productionProcessContext.getCraftCode())).isCompleted();
List<MesProductionRecord> productionRecordList = null;
//验证已完成工序最大重复次数: 如果当前工位的工序与主条码的当前工序一致的情况下, 根据条码+物料+工序+工艺查询加工记录, 判断加工记录条数
if (null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())) {
//根据零件条码查询加工记录信息
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
//条码+物料+工序+工艺搜集加工记录
List<MesProductionRecord> filterList = CollectionUtils.isEmpty(productionRecordList) ? null :
productionRecordList.stream().filter(o -> (null != o && o.getPartNo().equals(productionPsInContext.getPartNo()) && o.getProcessCode().equals(reqBean.getProcessCode()) && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(filterList) && filterList.size() >= optionalPs.get().getRepeatTimes())
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]当前工序[%s]产品工艺路线[%s]已完成工序最大重复次数[%s]",
message, productionPsInContext.getProductSn(), reqBean.getProcessCode(), craftRouteDetailList.get(0).getCraftRouteCode(), optionalPs.get().getRepeatTimes())).isCompleted();
}
//判断当前工位的工序对应的工艺是否包含在产品工艺路线中
Optional<MesCraftRouteDetail> optionalCell = craftRouteDetailList.stream().filter(o -> (null != o && o.getCraftCode().equals(productionProcessContext.getCraftCode()))).findFirst();
//根据当前工位对应的工艺 获取 所有前道工艺, 如果当前工位的工序对应工艺不在工艺路线明细内, 则默认所有明细均为所有前道工艺, 否则搜集当前工位工序对应工艺前面的所有前道工艺
List<MesCraftRouteDetail> beforeCellCraftList;
if (null == optionalCell || !optionalCell.isPresent()) beforeCellCraftList = craftRouteDetailList;
else beforeCellCraftList = craftRouteDetailList.stream().filter(o -> (null != o && o.getSeq().compareTo(optionalCell.get().getSeq()) < 0)).collect(Collectors.toList());
//前道工艺不存在即当前为首道工艺
if (CollectionUtils.isEmpty(beforeCellCraftList)) return true;
//前道工艺正序
beforeCellCraftList = beforeCellCraftList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesCraftRouteDetail::getSeq)).collect(Collectors.toList());
//判断上面是否已经查询过数据
if (!(null != optionalPs && optionalPs.isPresent() && optionalPs.get().getRepeatTimes().compareTo(MesPcnExtConstWords.ONE) > 0 && reqBean.getProcessCode().equals(productionPsInContext.getProcessCode())))
productionRecordList = productionRecordService.findProductionRecordList(reqBean.getOrganizeCode(), productionPsInContext.getProductSn());
Map<String, List<MesProductionRecord>> prMapByCraft = CollectionUtils.isEmpty(productionRecordList) ? null : productionRecordList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProductionRecord::getCraftCode));
//遍历前道工艺, 根据工艺查询加工记录是否存在, 并验证是否存在捆绑工艺
for (int i = 0; i < beforeCellCraftList.size(); i ++) {
if (null == beforeCellCraftList.get(i)) continue;
Boolean isExist = isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i).getCraftCode());
if (beforeCellCraftList.get(i).getIsChoose().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && !isExist)
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]未经过必过工艺[%s]", message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftCode())).isCompleted();
if (i != 0 && beforeCellCraftList.get(i - 1).getIsBindNextCraft().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && isExistProductionRecord(prMapByCraft, beforeCellCraftList.get(i - 1).getCraftCode()) && !isExist)
return stepResult.isCompleted(false).msg(String.format("%s主条码[%s]产品工艺路线[%s]工艺[%s]捆绑后道工艺",
message, productionPsInContext.getProductSn(), beforeCellCraftList.get(i).getCraftRouteCode(), beforeCellCraftList.get(i - 1).getCraftCode())).isCompleted();
}
return true;
}
private Boolean isExistProductionRecord(Map<String, List<MesProductionRecord>> prMapByCraft, String craftCode) {
return (CollectionUtils.isEmpty(prMapByCraft) || !prMapByCraft.containsKey(craftCode)) ? false : true;
}
}

Loading…
Cancel
Save