|
|
|
@ -0,0 +1,190 @@
|
|
|
|
|
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi;
|
|
|
|
|
|
|
|
|
|
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
|
|
|
|
|
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
|
|
|
|
|
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
|
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesProductionAssembly;
|
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
|
|
|
|
|
import cn.estsh.i3plus.pojo.mes.bean.MesTimeEfficientCfg;
|
|
|
|
|
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 java.text.ParseException;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Description :
|
|
|
|
|
* @Reference :
|
|
|
|
|
* @Author : Castle
|
|
|
|
|
* @CreateDate : 2024/6/20 21:20
|
|
|
|
|
* @Modify:
|
|
|
|
|
**/
|
|
|
|
|
@Service
|
|
|
|
|
public class MesProductionRecordServiceImpl implements IMesProductionRecordService {
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesTimeEfficientCfgRepository mesTimeEfficientCfgRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesProductionRecordRepository mesProductionRecordRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesProductionAssemblyRepository mesProductionAssemblyRao;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 逻辑:
|
|
|
|
|
* 0.根据加工规则可以查询 主条码时效性规则
|
|
|
|
|
* 1.校验主条码时效性
|
|
|
|
|
* 1.1 查询条码的所有加工记录,条件 条码相等且工序不相等; 没有不需要校验,直接返回true
|
|
|
|
|
* 1.2 如果有前道工序,遍历时效性规则
|
|
|
|
|
* 1.2.1 如果维护了零件号,则需要首先匹配零件号 相等,然后校验时间 和 时效性规则
|
|
|
|
|
* 1.2.2 如果维护了工序,则需要校验生产记录中当前工序的主条码生成时间 与 时效性校验
|
|
|
|
|
* 2.主条码装配件校验
|
|
|
|
|
* 2.1 首先校验主条码规则--同上
|
|
|
|
|
* 2.2 查找主条码的装配件条码(在装配件记录表中)
|
|
|
|
|
* 2.3 遍历获取道的装配件条码, 去校验装配件 的时效性,有零件 和 工序 两种情况
|
|
|
|
|
*
|
|
|
|
|
* 可以根据如下timeDataSource + sourceId 可以查询 MES_TIME_EFFICIENT_CFG 需要校验的 时效性规则
|
|
|
|
|
* DATA_SOURCE10(10, "排序加工规则"),
|
|
|
|
|
* DATA_SOURCE20(20, "非排序加工规则"),
|
|
|
|
|
* DATA_SOURCE30(30, "非排序装配件");
|
|
|
|
|
* 排除未知的零件号生产记录
|
|
|
|
|
* @param sn 条码 用于查询生产加工记录
|
|
|
|
|
* @param sourceId 用于获取时效性记录
|
|
|
|
|
* @param organizeCode
|
|
|
|
|
* @param isAssembly 如果是装配件需要查询装配记录
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, Object> checkSnTimeliness(String sn, Long sourceId ,String organizeCode ,Integer timeDataSource , Boolean isAssembly) {
|
|
|
|
|
Map<String, Object> resultMap = new HashMap<>();
|
|
|
|
|
//校验成功
|
|
|
|
|
resultMap.put("result", true);
|
|
|
|
|
//1.根据prodRuleNoSortId 获取 非排序加工规则的 时效性数据 --- 当前的条码需要完全匹配查询的规则
|
|
|
|
|
DdlPackBean timelinessPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(sourceId,"sourceId",timelinessPackBean);
|
|
|
|
|
List<MesTimeEfficientCfg> timelinessList = mesTimeEfficientCfgRao.findByHqlWhere(timelinessPackBean);
|
|
|
|
|
|
|
|
|
|
//2.如果timelinessList为空 且 非装配件校验 直接返回true
|
|
|
|
|
if (timelinessList.isEmpty() && !isAssembly){
|
|
|
|
|
return resultMap;
|
|
|
|
|
}
|
|
|
|
|
//查询主条码的逻辑
|
|
|
|
|
if (!isAssembly){
|
|
|
|
|
//3.根据条码获取生产加工记录结果
|
|
|
|
|
DdlPackBean recordPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(sn,"productSn",recordPackBean);
|
|
|
|
|
List<MesProductionRecord> recordList = mesProductionRecordRao.findByHqlWhere(recordPackBean);
|
|
|
|
|
boolean checkedResult = checkProductSn(recordList, timelinessList);
|
|
|
|
|
if (!checkedResult){
|
|
|
|
|
resultMap.put("result", false);
|
|
|
|
|
return resultMap;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
if (isAssembly){
|
|
|
|
|
Date now = new Date();
|
|
|
|
|
for (MesTimeEfficientCfg timeliness : timelinessList) {
|
|
|
|
|
//需要查询装配件记录表 production_assembly mesProductionAssemblyRao
|
|
|
|
|
DdlPackBean assemblyPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(sn,"assemblySn",assemblyPackBean);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(timeliness.getCraftCode(),"craftCode",assemblyPackBean);
|
|
|
|
|
List<MesProductionAssembly> productionAssemblyList = mesProductionAssemblyRao.findByHqlWhere(assemblyPackBean);
|
|
|
|
|
|
|
|
|
|
MesProductionAssembly mesProductionAssembly = productionAssemblyList.get(0);
|
|
|
|
|
String productDateTimeStr = mesProductionAssembly.getCreateDatetime();
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
Date productDateTime = sdf.parse(productDateTimeStr);
|
|
|
|
|
//时差
|
|
|
|
|
int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
return resultMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* MATCH_RULE_10("10", "生产时间小于装配件有效期"),
|
|
|
|
|
* MATCH_RULE_20("20", "小于最小时差有效"),
|
|
|
|
|
* MATCH_RULE_30("30", "大于最小时差有效"),
|
|
|
|
|
* MATCH_RULE_40("40", "最大最小时差有效"),
|
|
|
|
|
* MATCH_RULE_50("50", "最大外或最小内有效");
|
|
|
|
|
* 用于校验主条码时效性
|
|
|
|
|
* 加工记录 和 时效性校验
|
|
|
|
|
*
|
|
|
|
|
* 时效性规则 零件号可以为空 、工艺一定不为空
|
|
|
|
|
* @param
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private boolean checkProductSn(List<MesProductionRecord> recordList,List<MesTimeEfficientCfg> timelinessList) {
|
|
|
|
|
try {
|
|
|
|
|
Date now = new Date();
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
for (MesTimeEfficientCfg timeliness : timelinessList) {
|
|
|
|
|
List<MesProductionRecord> records = new ArrayList<>();
|
|
|
|
|
//时效性规则 零件号不为空
|
|
|
|
|
if (StringUtils.isNoneBlank(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())){
|
|
|
|
|
records = recordList.stream().filter(item -> item.getCraftCode().equals(timeliness.getCraftCode())).sorted(Comparator.comparing(MesProductionRecord::getCompleteDateTime)).collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (records.isEmpty()){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//不为空 则 需要校验时效性
|
|
|
|
|
MesProductionRecord record = records.get(0);
|
|
|
|
|
String completeDateTime = record.getCompleteDateTime();
|
|
|
|
|
Date productDateTime = sdf.parse(completeDateTime);
|
|
|
|
|
//时差
|
|
|
|
|
int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000));
|
|
|
|
|
if (!checkTimeliness(timeliness, minDiff)){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean checkTimeliness(MesTimeEfficientCfg timeliness, int minDiff) {
|
|
|
|
|
String matchRule = timeliness.getMatchRule();
|
|
|
|
|
Double minValue = timeliness.getMinValue();
|
|
|
|
|
Double maxValue = timeliness.getMaxValue();
|
|
|
|
|
if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_20.getValue().equals(matchRule)) {
|
|
|
|
|
//差值 大于等于最小值
|
|
|
|
|
if (minDiff >= minValue){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_30.getValue().equals(matchRule)) {
|
|
|
|
|
// 差值 小于等于最大值
|
|
|
|
|
if (minDiff <= minValue){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_40.getValue().equals(matchRule)) {
|
|
|
|
|
// 差值 在 最大值 最小值之间
|
|
|
|
|
if (minDiff <= minValue || minDiff >= maxValue){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_50.getValue().equals(matchRule)) {
|
|
|
|
|
// 差值 在 最小值之间
|
|
|
|
|
if (minDiff >= minValue && maxValue <= minDiff){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|