容器扣减匹配装配件站点工步

mes-uat-changshu0609-temp-wj-250616-xisu
王杰 4 weeks ago
parent a6a28ab4fb
commit 619a3d72b5

@ -179,4 +179,10 @@ public interface IMesProductionProcessContextStepService {
@ApiOperation(value = "处理切换发运RFID生产模式的标志")
Boolean disPatchChooseShippingRfidRouteMode(StationRequestBean reqBean);
@ApiOperation(value = "处理设备站点")
List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode);
@ApiOperation(value = "处理设备站点")
List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List<Integer> stationTypeList);
}

@ -1,14 +1,45 @@
package cn.estsh.i3plus.ext.mes.pcn.api.busi;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Map;
public interface IMesStationContainSnExtService {
public interface IMesStationContainerSnExtService {
@ApiOperation(value = "根据设备代码查询站点信息")
List<MesStation> getStationList(String organizeCode, String equipmentCode);
@ApiOperation(value = "获取站点关联的容器条码")
Map<String, List<MesContainerSnStation>> getContainerSnStationMap(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
List<MesContainerSnStation> getContainerSnStationList(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】")
List<MesContainerPackageDetailContext> getContainerSnStationContext(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageList(String organizeCode, List<MesContainerSnStation> containerSnStationList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】")
List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】")
List<MesContainerPackageDetail> getContainerPackageDetailListById(String organizeCode, List<Long> idList);
@ApiOperation(value = "获取容器条码的一条上料明细表信息【可扣减】")
Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id);
}

@ -1,5 +1,6 @@
package cn.estsh.i3plus.ext.mes.pcn.api.busi;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import io.swagger.annotations.ApiOperation;
import java.util.Map;
@ -21,4 +22,7 @@ public interface IMesTimeEfficientCfgMatchService {
@ApiOperation(value = "时效性匹配")
Map<String, Object> checkSnTimeliness(String organizeCode, String productSn, Long sourceId, Integer dataSource);
@ApiOperation(value = "时效性匹配[容器条码]")
Map<String, Object> checkSnTimelinessContainerMatch(String organizeCode, MesContainerPackageDetailContext containerPackageDetailContext, Long sourceId);
}

@ -4,6 +4,7 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesTimeEfficientCfgMatchService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesTimeEfficientCfgService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
@ -209,4 +210,36 @@ public class MesTimeEfficientCfgMatchService implements IMesTimeEfficientCfgMatc
}
}
@Override
public Map<String, Object> checkSnTimelinessContainerMatch(String organizeCode, MesContainerPackageDetailContext containerPackageDetailContext, Long sourceId) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(MesPcnExtConstWords.RESULT, true);//校验成功
try {
//1.根据prodRuleNoSortId 获取 非排序加工规则的 时效性数据 --- 当前的条码需要完全匹配查询的规则
List<MesTimeEfficientCfg> timelinessList = timeEfficientCfgService.getTimeEfficientCfgList(organizeCode, sourceId);
//2.如果timelinessList为空 且 非装配件校验 直接返回true
if (CollectionUtils.isEmpty(timelinessList)) return resultMap;
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT);
for (MesTimeEfficientCfg timeliness : timelinessList) {
if (null == timeliness || StringUtils.isEmpty(timeliness.getPartNo()) || !timeliness.getPartNo().equals(containerPackageDetailContext.getPartNo())) continue;
Date productDateTime = sdf.parse(containerPackageDetailContext.getCreateDatetime());
//时差
int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000));
if (!checkTimeliness(timeliness, minDiff)) return backResultMap(resultMap, String.format("原材料条码[%s]时效性零件号[%s]验证失败!", containerPackageDetailContext.getBarCode(), timeliness.getPartNo()));
}
return resultMap;
} catch (Exception e) {
return backResultMap(resultMap, String.format("原材料条码[%s]时效性验证异常:%s!", containerPackageDetailContext.getBarCode(), e.toString()));
}
}
}

@ -288,7 +288,7 @@ public class MesAssemblyMatchSortStepService extends BaseStepService {
//时效性验证
if (!StringUtils.isEmpty(filter.getProductSnId())) {
result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue(), filter.getSourceId(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE10.getValue());
result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue(), filter.getPid(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE10.getValue());
if (!(Boolean)result.get(MesPcnExtConstWords.RESULT)) {
stepResult.msg(String.format("%s%s", StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg(), result.get(MesPcnExtConstWords.MESSAGE)));

@ -1,26 +1,40 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
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.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
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.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
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 cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
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.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesContainerSnScanStepService")
public class MesContainerMatchStationAssemblyStepService extends BaseStepService {
@Service("mesStationMatchAssemblyStepService")
public class MesStationMatchAssemblyStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@ -31,14 +45,14 @@ public class MesContainerMatchStationAssemblyStepService extends BaseStepService
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Override
public StepResult guide(StationRequestBean reqBean) {
productionCustomContextStepService.sendStepContextMessage(reqBean);
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!");
@Autowired
private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService;
}
@Autowired
private MesAssemblyShowNosortStepService assemblyShowNosortStepService;
@Override
public StepResult execute(StationRequestBean reqBean) {
@ -47,15 +61,135 @@ public class MesContainerMatchStationAssemblyStepService extends BaseStepService
StepResult stepResult = StepResult.getSuccessComplete();
//发送工步内容
if (!StringUtils.isEmpty(reqBean.getScanInfo())) productionCustomContextStepService.sendStepContextMessage(reqBean, reqBean.getScanInfo(), MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN);
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
if (CollectionUtils.isEmpty(prodRuleContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在产品加工规则信息,请重置工序解决!");
//验证是否存在装配件容器匹配
Optional<MesProdRuleContext> optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst();
if (null == optional || !optional.isPresent()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过容器条码扣减装配件!");
}
//处理设备站点【装配件站点&&混料站点】
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(),
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持扣减的站点");
//保存站点用于缺料时进行上料绑定
productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList);
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
List<MesContainerPackageDetailContext> containerSnStationList = stationContainerSnExtService.getContainerSnStationContext(reqBean.getOrganizeCode(), stationList);
if (CollectionUtils.isEmpty(containerSnStationList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件时验证当前无可扣减的原材料信息!");
//将可扣减的条码进行原子性缓存, 并获取最新的实际库存
productionCustomContextStepService.dispatchContainerSnAtomicity(reqBean.getOrganizeCode(), containerSnStationList);
//获取弹框输入的工单数量, 未弹框默认 数量=1
Double orderQtyDialogContext = productionDispatchContextStepService.getOrderQtyDialogContext(reqBean);
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//匹配装配件的工序用量
dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerSnStationList, orderQtyDialogContext);
if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0)
((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
else
((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件验证成功!");
}
//匹配装配件的工序用量【遍历加工规则】
private void dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
List<MesProdRuleContext> prodRuleContextList, List<MesContainerPackageDetailContext> containerSnStationList, Double orderQtyDialogContext) {
for (MesProdRuleContext prodRuleContext : prodRuleContextList) {
if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue;
List<MesProductionAssemblyContext> productionAssemblyContextList = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, containerSnStationList, orderQtyDialogContext);
if (!stepResult.isCompleted()) break;
prodRuleContext.assemblyDataJson(productionAssemblyContextList);
}
}
//匹配装配件的工序用量【遍历装配件】
private List<MesProductionAssemblyContext> dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
MesProdRuleContext prodRuleContext, List<MesContainerPackageDetailContext> containerSnStationList, Double orderQtyDialogContext) {
List<MesProductionAssemblyContext> productionAssemblyContextList = prodRuleContext.getAssemblyDataContext(workCenter);
for (MesProductionAssemblyContext productionAssemblyContext : productionAssemblyContextList) {
if (null == productionAssemblyContext || productionAssemblyContext.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) != 0) continue;
if (StringUtils.isEmpty(productionAssemblyContext.getPartNo()) || StringUtils.isEmpty(productionAssemblyContext.getQty()))
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("当前产成对应的[%s]类型的装配件信息维护零件号或工序用量!", MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getDescription()));
//未匹配的工序用量
Double unMatchQty = MathOperation.mul(productionAssemblyContext.getQty(), orderQtyDialogContext);
List<String> containerSnDataList = null;
List<String> containerSnList = null;
for (MesContainerPackageDetailContext containerPackageDetailContext : containerSnStationList) {
if (null == containerPackageDetailContext || StringUtils.isEmpty(containerPackageDetailContext.getPartNo())) continue;
if (!containerPackageDetailContext.getPartNo().equals(productionAssemblyContext.getPartNo()) || MathOperation.compareTo(containerPackageDetailContext.getRemainQty(), new Double(0)) <= 0) continue;
//验证时效性
Map<String, Object> result = timeEfficientCfgMatchService.checkSnTimelinessContainerMatch(reqBean.getOrganizeCode(), containerPackageDetailContext,
workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0 ? productionAssemblyContext.getSourceId() : productionAssemblyContext.getPid());
if (!(Boolean)result.get(MesPcnExtConstWords.RESULT)) continue;
//如果存在未匹配的工序用量
if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) {
//剩余未匹配的工序用量
Double remainQty = MathOperation.sub(containerPackageDetailContext.getRemainQty(), unMatchQty);
//全部匹配完成
if (MathOperation.compareTo(remainQty, new Double(0)) >= 0) {
containerPackageDetailContext.remainQty(remainQty);
unMatchQty = new Double(0);
} else {
//未匹配完成, 0-负数=正数
containerPackageDetailContext.remainQty(new Double(0));
unMatchQty = MathOperation.sub(new Double(0), remainQty);
}
}
//将能够扣减的所有条码跟当前装配件关联
if (CollectionUtils.isEmpty(containerSnDataList)) {
containerSnDataList = new ArrayList<>();
containerSnList = new ArrayList<>();
}
containerSnDataList.add(productionCustomContextStepService.getContainerSnAtomicityKey(reqBean.getOrganizeCode(), containerPackageDetailContext));
containerSnList.add(containerPackageDetailContext.getContainerSn());
}
if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) {
if (!StringUtils.isEmpty(productionAssemblyContext.getAssemblySn())) {
productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue());
productionAssemblyContext.setAssemblySn(null);
productionAssemblyContext.setMatchDatetime(null);
}
stepResult.isCompleted(false).msg(String.format("容器条码扣减装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getPartNo()));
break;
}
productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_10.getValue());
productionAssemblyContext.setAssemblySn(containerSnList.get(0));
productionAssemblyContext.setMatchDatetime((new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()));
productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(containerSnDataList));
}
return productionAssemblyContextList;
}
}

@ -1,5 +1,6 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.context;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProdRuleNosortCfg;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
@ -14,6 +15,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -117,6 +119,9 @@ public class MesProdRuleContext implements Serializable {
@ApiParam(name = "平行 工位/工艺顺序号")
private String parallelInfo;
@ApiParam(name = "是否存在装配件容器匹配")
private String isMatchContainer;
public MesProdRuleContext() {}
public MesProdRuleContext(String organizeCode) {
@ -226,7 +231,18 @@ public class MesProdRuleContext implements Serializable {
}
public MesProdRuleContext assemblyDataJson(List<? extends MesProductionAssemblyContext> productionAssemblyContextList) {
this.assemblyDataJson = !CollectionUtils.isEmpty(productionAssemblyContextList) ? JSONObject.toJSONString(productionAssemblyContextList) : null;
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return this;
this.assemblyDataJson = JSONObject.toJSONString(productionAssemblyContextList);
isMatchContainer(productionAssemblyContextList);
return this;
}
//标记装配件是否需要进行匹配容器条码进行扣减
public MesProdRuleContext isMatchContainer(List<? extends MesProductionAssemblyContext> productionAssemblyContextList) {
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return this;
Optional<MesProductionAssemblyContext> optional = (Optional<MesProductionAssemblyContext>) productionAssemblyContextList.stream()
.filter(o -> (null != o && !StringUtils.isEmpty(o.getMatchType()) && o.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) == 0)).findFirst();
if (null != optional && optional.isPresent()) this.isMatchContainer = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
return this;
}

Loading…
Cancel
Save