保存裁片加工记录

tags/yfai-pcn-ext-v2.3
yxw 8 months ago
parent 59fc125885
commit ae725102b7

@ -22,7 +22,10 @@ public interface IMesWorkOrderCutService {
@ApiOperation(value = "查询裁片工单明细")
List<MesWorkOrderCutDetail> queryMesWorkOrderCutDetailList(String cutWorkOrderNo, String organizeCode);
@ApiOperation(value = "查询裁片工单明细")
@ApiOperation(value = "查询裁片方案")
MesCutScheme getCutScheme(String cutCode, String organizeCode);
@ApiOperation(value = "查询裁片方案成品配置")
List<MesCutSchemeFg> queryCutSchemeFgList(String cutCode, String organizeCode);
}

@ -4,15 +4,17 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesWorkOrderCutService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesCutScheme;
import cn.estsh.i3plus.pojo.mes.bean.MesCutSchemeFg;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCut;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCutDetail;
import cn.estsh.i3plus.pojo.mes.repository.MesCutSchemeFgRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesCutSchemeRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCutDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCutRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.xml.ws.Action;
import java.util.List;
/**
@ -33,6 +35,9 @@ public class MesWorkOrderCutService implements IMesWorkOrderCutService {
@Autowired
private MesCutSchemeRepository cutSchemeRepository;
@Autowired
private MesCutSchemeFgRepository cutSchemeFgRepository;
@Override
public MesWorkOrderCut getMesWorkOrderCut(String cutWorkOrderNo, String organizeCode) {
return workOrderCutRepository.getByProperty(
@ -53,4 +58,14 @@ public class MesWorkOrderCutService implements IMesWorkOrderCutService {
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.CUT_CODE},
new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), cutCode});
}
@Override
public List<MesCutSchemeFg> queryCutSchemeFgList(String cutCode, String organizeCode) {
if (StringUtils.isEmpty(organizeCode)) return null;
return cutSchemeFgRepository.findByProperty(
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.CUT_CODE},
new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), cutCode});
}
}

@ -1,21 +1,15 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
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.IMesWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
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.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.mes.pcn.util.StationKvBeanUtil;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrder;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
@ -27,10 +21,9 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -50,6 +43,15 @@ public class MesWorkOrderCutCheckStepService extends BaseStepService {
@Autowired
private IMesWorkOrderExtService workOrderExtService;
@Autowired
private IMesWorkOrderCutService workOrderCutService;
@Autowired
private MesFirstMouldNoReadStepService firstMouldNoReadStepService;
@Autowired
private IMesProduceSnExtService produceSnExtService;
@Override
public StepResult execute(StationRequestBean reqBean) {
@ -66,12 +68,12 @@ public class MesWorkOrderCutCheckStepService extends BaseStepService {
//存储生产过程上下文对象
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
//清除本次已获取得到的加工单信息
productionDispatchContextStepService.removeScanWorkOrderNoContext(reqBean);
//获取上下文生产扫/读信息:加工单
List<MesEquipVariableCollectContext> equipVariableCollectContextList = productionDispatchContextStepService.getScanWorkOrderNoContext(reqBean);
if (CollectionUtils.isEmpty(equipVariableCollectContextList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前缺失待验证的加工单信息!");
if (CollectionUtils.isEmpty(equipVariableCollectContextList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "当前缺失待验证的裁片工单信息!");
//清除本次已获取得到的裁片工单信息
//productionDispatchContextStepService.removeScanWorkOrderNoContext(reqBean);
//从上下文中取出生产线对象
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
@ -90,7 +92,7 @@ public class MesWorkOrderCutCheckStepService extends BaseStepService {
//当前不允许跳过
if (isCraftJumpCode && !isAllowJump)
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.SCAN.getValue()).
scanInfo(equipVariableCollectContextList.get(0).getEquipVariableValue()), stepResult, String.format("当前扫描信息工艺强过码[%s],当前没有可以跳过的工单信息!", equipVariableCollectContextList.get(0).getEquipVariableValue()));
scanInfo(equipVariableCollectContextList.get(0).getEquipVariableValue()), stepResult, String.format("当前扫描信息工艺强过码[%s],当前没有可以跳过的裁片工单信息!", equipVariableCollectContextList.get(0).getEquipVariableValue()));
//允许跳过,先更新数据
if (isCraftJumpCode && isAllowJump) {
@ -102,65 +104,153 @@ public class MesWorkOrderCutCheckStepService extends BaseStepService {
//验证工单的有效性
List<MesProductionPartContext> productionPartContextList = new ArrayList<>();
List<MesProductionPsInContext> productionPsInContextList = new ArrayList<>();
if (!checkWorkOrderValid(reqBean, resultBean, stepResult, productionProcessContext, workCenter,
equipVariableCollectContextList, productionPartContextList, productionPsInContextList).isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
List<MesProductionPsOutContext> productionPsOutContextList = new ArrayList<>();
if (!checkWorkOrderValid(reqBean, stepResult, productionProcessContext, workCenter,
equipVariableCollectContextList, productionPartContextList, productionPsInContextList,
productionPsOutContextList).isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
//保存零件数据信息
if (!firstMouldNoReadStepService.savePartDataMap(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, true).isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
//保存上下文产出零件信息
productionDispatchContextStepService.dispatchProductionPartContext(reqBean, productionPartContextList);
//存储展示组件MODULE_CONTENT内容
productionDispatchContextStepService.dispatchModuleContentContext(reqBean, getModuleContextData(reqBean, productionPartContextList));
//保存扫描的工单信息上下文
if (MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue() == equipVariableCollectContextList.get(0).getMessageSource()) {
productionProcessContextStepService.dispatchFunctionChooseCavityOrderContext(reqBean, StationKvBeanUtil.addStationKvBeanList(new ArrayList<>(),
new StationKvBean(MesPcnExtConstWords.CAVITY, "腔数", String.valueOf(productionPartContextList.size())),
new StationKvBean(MesPcnExtConstWords.CELL_MESSAGE_SOURCE, "工位信息来源", MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ.getValueStr()),
new StationKvBean(MesPcnExtConstWords.CRAFT_JUMP_CODE, "是否已验证顺序防错", CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr()),
new StationKvBean(MesPcnExtConstWords.WORK_ORDER_NO, "裁片工单", productionPartContextList.stream().filter(o -> null != o).map(MesProductionPartContext::getWorkOrderNo).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON)))));
}
String workOrderStr = equipVariableCollectContextList.stream().filter(o -> null != o).map(MesEquipVariableCollectContext::getEquipVariableValue).collect(Collectors.toList()).toString();
//执行匹配加工规则工步
((IStepService) SpringContextsUtil.getBean("mesWorkOrderCutMatchingProdRuleStepService")).executeInState(reqBean);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(workOrderStr), stepResult, String.format("当前%s裁片工单%s验证工单状态成功%s!",
MesExtEnumUtil.CELL_MESSAGE_SOURCE.valueOfDescription(equipVariableCollectContextList.get(0).getMessageSource()), workOrderStr, MesPcnExtConstWords.EMPTY));
return null;
}
//封装展示组件MODULE_CONTENT内容
private List<List<StationKvBean>> getModuleContextData(StationRequestBean reqBean, List<MesProductionPartContext> productionPartContextList) {
List<List<StationKvBean>> dataList = new ArrayList<>();
List<MesProductionPartContext> orderList = filterProductionPartContext(productionPartContextList, true);
List<MesProductionPartContext> finishCodeList = filterProductionPartContext(productionPartContextList, false);
AtomicReference<Integer> index = new AtomicReference<>(0);
if (!CollectionUtils.isEmpty(orderList)) {
orderList.forEach(o -> StationKvBeanUtil.addStationKvBeanList(dataList, new ArrayList<>(),
new StationKvBean(MesPcnExtConstWords.WORK_ORDER_NO, "裁片工单号", o.getWorkOrderNo()),
new StationKvBean(MesPcnExtConstWords.PART_NO, "零件编码", new StringJoiner(MesPcnExtConstWords.SLANT_R).add(o.getPartNo()).toString()),
new StationKvBean(MesPcnExtConstWords.QTY, "完成数/工单数", new StringJoiner(MesPcnExtConstWords.SLANT_R).add(String.valueOf(o.getCompleteQty().intValue())).add(String.valueOf(o.getQty().intValue())).toString()),
new StationKvBean(MesPcnExtConstWords.CAVITY, "腔数", new StringJoiner(MesPcnExtConstWords.SLANT_R).add(String.valueOf(index.updateAndGet(v -> v + 1))).add(String.valueOf(productionPartContextList.size())).toString())));
}
if (!CollectionUtils.isEmpty(finishCodeList)) {
StationKvBeanUtil.addStationKvBeanList(dataList, new ArrayList<>(), new StationKvBean(MesPcnExtConstWords.CAVITY_FINISH_CODE, "空腔数", String.valueOf(finishCodeList.size())));
}
return dataList;
}
//验证工单的有效性
private StepResult checkWorkOrderValid(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesWorkCenter workCenter,
List<MesEquipVariableCollectContext> equipVariableCollectContextList, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList) {
private StepResult checkWorkOrderValid(StationRequestBean reqBean, StepResult stepResult,
MesProductionProcessContext productionProcessContext, MesWorkCenter workCenter,
List<MesEquipVariableCollectContext> equipVariableCollectContextList,
List<MesProductionPartContext> productionPartContextList,
List<MesProductionPsInContext> productionPsInContextList,
List<MesProductionPsOutContext> productionPsOutContextList) {
//搜集生产工单号
List<String> filterList = equipVariableCollectContextList.stream().filter(o -> (null != o)).map(MesEquipVariableCollectContext::getEquipVariableValue).collect(Collectors.toList());
List<String> workOrderNoList = filterList.stream().filter(o -> (!StringUtils.isEmpty(o) && !o.equals(productionProcessContext.getFinishCode()))).distinct().collect(Collectors.toList());
List<String> workOrderCutNoList = filterList.stream().filter(o -> (!StringUtils.isEmpty(o) && !o.equals(productionProcessContext.getFinishCode()))).distinct().collect(Collectors.toList());
//Map<String, Map<String, Object>> workOrderMap = workOrderExtService.getWorkOrderMapSort(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), workOrderNoList);
String cutWorkOrderNo = workOrderCutNoList.stream().findFirst().get();
MesWorkOrderCut workOrderCut = workOrderCutService.getMesWorkOrderCut(reqBean.getOrganizeCode(), cutWorkOrderNo);
Map<String, Map<String, Object>> workOrderMap = workOrderExtService.getWorkOrderMapSort(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), workOrderNoList);
if (workOrderCut == null)
return stepResult.isCompleted(false).msg(String.format("请检查裁片工单信息,裁片工单[%s]无效!", cutWorkOrderNo));
for (String workOrderNo : workOrderNoList) {
MesCutScheme cutScheme = workOrderCutService.getCutScheme(workOrderCut.getCutCode(), reqBean.getOrganizeCode());
if (StringUtils.isEmpty(workOrderNo)) continue;
if (cutScheme == null)
return stepResult.isCompleted(false).msg(String.format("请检查裁片工单信息,裁片工单[%s]所属裁片配置无效!", cutWorkOrderNo));
Map<String, Object> itemMap = CollectionUtils.isEmpty(workOrderMap) ? null : workOrderMap.get(workOrderNo);
if (CollectionUtils.isEmpty(itemMap))
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,加工单号[%s]无效!", workOrderNo));
if (itemMap.containsKey(MesPcnExtConstWords.MESSAGE))
return stepResult.isCompleted(false).msg((String) itemMap.get(MesPcnExtConstWords.MESSAGE));
if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == cutScheme.getIsCheckMaterial() && workOrderCut.getWorkOrderStatus() != MesExtEnumUtil.CUT_ORDER_STATUS.CHECKED_RAW.getValue())
return stepResult.isCompleted(false).msg(String.format("裁片工单[%s]未进行裁片原材料防错!", cutWorkOrderNo));
else if (workOrderCut.getWorkOrderStatus() != MesExtEnumUtil.CUT_ORDER_STATUS.RELEASED.getValue() || workOrderCut.getWorkOrderStatus() != MesExtEnumUtil.CUT_ORDER_STATUS.PROCESS.getValue())
return stepResult.isCompleted(false).msg(String.format("裁片工单[%s]当前状态[%s]无需加工或无法加工!", cutWorkOrderNo, MesExtEnumUtil.CUT_ORDER_STATUS.valueOfDescription(workOrderCut.getWorkOrderStatus())));
MesWorkOrder workOrder = (MesWorkOrder) itemMap.get(MesWorkOrder.class.getSimpleName());
List<MesWorkOrderCutDetail> mesWorkOrderCutDetailList = workOrderCutService.queryMesWorkOrderCutDetailList(reqBean.getOrganizeCode(), cutWorkOrderNo);
if (CollectionUtils.isEmpty(mesWorkOrderCutDetailList))
return stepResult.isCompleted(false).msg(String.format("请检查裁片工单信息,裁片工单[%s]明细不存在!", cutWorkOrderNo));
List<String> workOrderNoList = mesWorkOrderCutDetailList.stream().map(MesWorkOrderCutDetail::getWorkOrderNo).distinct().collect(Collectors.toList());
List<MesWorkOrder> workOrderList = workOrderExtService.getWorkOrderList(reqBean.getOrganizeCode(), workOrderNoList);
if (CollectionUtils.isEmpty(workOrderList))
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,裁片工单[%s]信息绑定工单信息无效!", cutWorkOrderNo));
for (MesWorkOrder workOrder : workOrderList) {
if (!MesExtEnumUtil.ORDER_STATUS.checkAllowStatus(workCenter.getCenterType(), workOrder.getWorkOrderStatus()))
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,加工单[%s]信息工单状态[%s]!", workOrderNo, MesExtEnumUtil.ORDER_STATUS.valueOfDescription(workOrder.getWorkOrderStatus())));
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,裁片工单[%s]信息绑定工单信息工单状态[%s]!", cutWorkOrderNo, MesExtEnumUtil.ORDER_STATUS.valueOfDescription(workOrder.getWorkOrderStatus())));
if (!workOrder.getWorkCenterCode().equals(reqBean.getWorkCenterCode()))
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,加工单[%s]信息所属生产线[%s]与当前生产线[%s]不一致!", workOrderNo, workOrder.getWorkCenterCode(), reqBean.getWorkCenterCode()));
if (StringUtils.isEmpty(workOrder.getPartProdGroupCode()))
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,加工单[%s]信息未关联零件生产组!", workOrderNo));
MesProduceSn produceSn = (MesProduceSn) itemMap.get(MesProduceSn.class.getSimpleName());
if (MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue() != produceSn.getQcStatus())
return stepResult.isCompleted(false).msg(String.format("请检查产品条码信息,产品条码[%s]质量状态[%s]", produceSn.getProductSn(), MesExtEnumUtil.PRODUCE_QC_STATUS.valueOfDescription(produceSn.getQcStatus())));
if (MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue() <= produceSn.getSnStatus() || MesExtEnumUtil.PRODUCE_SN_STATUS.UNKNOW.getValue() == produceSn.getSnStatus())
return stepResult.isCompleted(false).msg(String.format("请检查产品条码信息,产品条码[%s]条码状态[%s]", produceSn.getProductSn(), MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(produceSn.getSnStatus())));
MesQueueOrder queueOrder = (MesQueueOrder) itemMap.get(MesQueueOrder.class.getSimpleName());
if (MesExtEnumUtil.QUEUE_ORDER_STATUS.FINISH.getValue() == queueOrder.getStatus())
return stepResult.isCompleted(false).msg(String.format("请检查产品条码工位队列信息,产品条码[%s]工位队列状态[%s]", queueOrder.getProductSn(), MesExtEnumUtil.QUEUE_ORDER_STATUS.valueOfDescription(queueOrder.getStatus())));
//封装产成零件
MesProductionPartContext productionPartContext = new MesProductionPartContext().copyPartNo(workOrder, equipVariableCollectContextList.get(0).getMessageSource()).isCheck(productionProcessContext.getWorkCell());
productionPartContextList.add(productionPartContext);
return stepResult.isCompleted(false).msg(String.format("请检查工单信息,裁片工单[%s]信息绑定工单[%s]信息所属生产线[%s]与当前生产线[%s]不一致!", cutWorkOrderNo, workOrder.getWorkOrderNo(), workOrder.getWorkCenterCode(), reqBean.getWorkCenterCode()));
}
//封装产品条码
productionPsInContextList.add(new MesProductionPsInContext(productionProcessContext.getWorkCell(), produceSn).messageSource(equipVariableCollectContextList.get(0).getMessageSource()).relateId(queueOrder.getId()));
// 裁片方案成品配置
List<MesCutSchemeFg> mesCutSchemeFgList = workOrderCutService.queryCutSchemeFgList(cutScheme.getCutCode(), reqBean.getOrganizeCode());
}
if (CollectionUtils.isEmpty(mesCutSchemeFgList))
return stepResult.isCompleted(false).msg(String.format("请检查裁片方案成品信息,裁片工单[%s]关联裁片方案[%s]无成品配置!", cutWorkOrderNo, cutScheme.getCutCode()));
List<String> fgPartNoList = mesCutSchemeFgList.stream().map(MesCutSchemeFg::getPartNo).distinct().collect(Collectors.toList());
List<String> worKOrderPartNoList = workOrderList.stream().map(MesWorkOrder::getWorkOrderNo).distinct().collect(Collectors.toList());
worKOrderPartNoList.removeAll(fgPartNoList);
//封装空腔
equipVariableCollectContextList.stream().filter(o -> (null != o && o.getEquipVariableValue().equals(productionProcessContext.getFinishCode()))).forEach(o -> {
productionPartContextList.add(new MesProductionPartContext().isFinishCode());
productionPsInContextList.add(new MesProductionPsInContext().isFinishCode());
if (!CollectionUtils.isEmpty(worKOrderPartNoList))
return stepResult.isCompleted(false).msg(String.format("请检查裁片方案成品信息,零件号[%s]未在裁片方案[%]成品配置信息中维护!", worKOrderPartNoList, cutScheme.getCutCode()));
Map<String, MesWorkOrderCutDetail> workOrderCutDetailMap = mesWorkOrderCutDetailList.stream().collect(Collectors.toMap(MesWorkOrderCutDetail::getWorkOrderNo, Function.identity(), (x, y) -> y));
List<MesProduceSn> produceSnList = produceSnExtService.getProduceSnList(reqBean.getOrganizeCode(), cutWorkOrderNo);
//获取上下文的工位
MesWorkCell workCell = productionProcessContext.getWorkCell();
// 获取上道工艺生产的条码并封装到进料上下文中
if (!CollectionUtils.isEmpty(produceSnList))
produceSnList.stream().filter(o -> null != o).forEach(o -> {
productionPsInContextList.add(new MesProductionPsInContext(workCell, o).cutCode(cutScheme.getCutCode()));
productionPsOutContextList.add(new MesProductionPsOutContext().copy(o));
});
//封装产出零件信息
workOrderList.stream().filter(o -> null != o).forEach( o -> {
MesProductionPartContext productionPartContext = new MesProductionPartContext()
.copyPartNo(o, workOrderCutDetailMap.get(o.getWorkOrderNo()).getQty(), equipVariableCollectContextList.get(0).getMessageSource())
.isCheck(productionProcessContext.getWorkCell());
//if (equipVariableCollectContextList.get(0).getIsConsume().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) productionPartContext.checkSeqResult(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
productionPartContext.setCutCode(cutScheme.getCutCode());
productionPartContextList.add(productionPartContext);
});
return stepResult;

@ -0,0 +1,538 @@
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.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.PojoAttrUtil;
import cn.estsh.i3plus.mes.pcn.util.StringUtil;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProdRuleNosortCfg;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.model.AttrBean;
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 com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
* @Description :
* @Author : xinwang.yi
**/
@Slf4j
@Service("mesWorkOrderCutMatchingProdRuleStepService")
public class MesWorkOrderCutMatchingProdRuleStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProdRuleCfgExtService prodRuleCfgExtService;
@Autowired
private IMesNumberRuleMatchDispatchService numberRuleMatchDispatchService;
@Autowired
private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService;
@Autowired
private IMesWorkOrderExtService workOrderExtService;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取上下文信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//存储生产过程上下文对象
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
//从上下文中取出生产线对象
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//从上下文中取出生产线对象
MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();
//获取上下文加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
//获取上下文产出零件数据信息集合
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
//获取上下文进料零件条码信息集合
//List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
//根据现有数据【产出零件数据】【进料零件条码信息】比对上下文中已经存在的加工规则数据信息集合, 没有加工规则的数据进行查询
if (CollectionUtils.isEmpty(prodRuleContextList)) prodRuleContextList = new ArrayList<>();
Integer initSize = prodRuleContextList.size();
//封装非排序加工规则
doHandleProdRuleData(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext,
prodRuleContextList, productionPartContextList);
//匹配失败需要清除本次扫描/读取信息
//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));
if (prodRuleContextList.size() != initSize) {
//保存上下文产品加工规则信息集合
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
//保存上下文产出零件信息
//if (!CollectionUtils.isEmpty(productionPartContextList)) productionDispatchContextStepService.dispatchProductionPartContext(reqBean, productionPartContextList);
}
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "匹配完成!");
}
private StepResult doHandleProdRuleData(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult,
MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext,
MesCellEquipContext cellEquipContext, List<MesProdRuleContext> prodRuleContextList,
List<MesProductionPartContext> productionPartContextList) {
//根据是否存在【产出零件数据】获取剩余待匹配的加工规则数据 (只能查询到一条,否则报错)
return doHandleProdRuleDataByProductionPart(reqBean, resultBean, stepResult, workCenter, productionProcessContext,
cellEquipContext, prodRuleContextList, productionPartContextList);
}
//根据是否存在【产出零件数据】获取剩余待匹配的加工规则数据 (只能查询到一条,否则报错)
private StepResult doHandleProdRuleDataByProductionPart(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesWorkCenter workCenter,
MesProductionProcessContext productionProcessContext,
MesCellEquipContext cellEquipContext,
List<MesProdRuleContext> prodRuleContextList,
List<MesProductionPartContext> productionPartContextList) {
//加工规则的数据已与产出零件的数量一致
//if (!CollectionUtils.isEmpty(prodRuleContextList) && prodRuleContextList.size() == productionPartContextList.size()) return stepResult;
//拿到当前最大的foreignKey
Optional<MesProductionPartContext> maxForeignKeyOptional = productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).max(Comparator.comparing(MesProductionPartContext::getForeignKey));
Integer foreignKey = (null != maxForeignKeyOptional && maxForeignKeyOptional.isPresent()) ? maxForeignKeyOptional.get().getForeignKey() : MesPcnExtConstWords.ZERO;
//搜集未匹配规则的产出零件
List<String> outPartNoList = productionPartContextList.stream()
.filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && !StringUtils.isEmpty(o.getPartNo())))
.map(MesProductionPartContext::getPartNo).collect(Collectors.toList());
//没有【进料零件条码信息】信息, 根据进料[NULL]条件获取匹配当前产出零件的加工规则数据(只能查询到一条,否则报错)
return doHandleProdRuleDataByProductionPartAndEmptyProductSn(reqBean, resultBean, stepResult, productionProcessContext,
cellEquipContext, prodRuleContextList, productionPartContextList, outPartNoList, foreignKey);
//存在【产出零件数据】信息, 存在【进料零件条码信息】 获取匹配当前产出零件的加工规则数据 (只能查询到一条,否则报错)
//else return doHandleProdRuleDataByProductionPartAndProductSn(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList, outPartNoList, foreignKey);
}
//没有【进料零件条码信息】信息, 根据进料[NULL]条件获取匹配当前产出零件的加工规则数据(只能查询到一条,否则报错)
private StepResult doHandleProdRuleDataByProductionPartAndEmptyProductSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext,
MesCellEquipContext cellEquipContext, List<MesProdRuleContext> prodRuleContextList, List<MesProductionPartContext> productionPartContextList, List<String> outPartNoList, Integer foreignKey) {
//【非排序线】获取产品加工规则 ; 条件进料[NULL]
List<MesProdRuleNosortCfg> prodRuleNosortCfgList = prodRuleCfgExtService.getProdRuleNosortCfgList(new MesProdRuleContext(reqBean.getOrganizeCode()).equipmentCode(cellEquipContext.getEquipmentCode()).outPartNos(outPartNoList).inPartIsEmpty(true));
//根据产出零件分组数据
Map<String, List<MesProdRuleNosortCfg>> prodRuleNosortCfgMap = groupProdRuleNosortCfgList(prodRuleNosortCfgList);
for (MesProductionPartContext productionPartContext : productionPartContextList) {
//foreignKey有值代表已经匹配过产品加工规则
if (null == productionPartContext || productionPartContext.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 || !StringUtils.isEmpty(productionPartContext.getForeignKey())) continue;
List<MesProdRuleNosortCfg> filterList = !CollectionUtils.isEmpty(prodRuleNosortCfgMap) ? prodRuleNosortCfgMap.get(productionPartContext.getPartNo()) : null;
if (CollectionUtils.isEmpty(filterList) || filterList.size() > 1) {
productionPartContextList.forEach(o -> o.busiCheckToDelete());
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format(
"设备[%s]产出零件[%s]进料零件[空]%s加工规则配置信息!", cellEquipContext.getEquipmentName(), productionPartContext.getPartNo(), CollectionUtils.isEmpty(filterList) ? "未匹配到" : String.format("匹配到[%s]条", filterList.size())));
}
//【非排序线】获取产品加工规则对应的装配件信息
MesProdRuleContext prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(
new MesProdRuleContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())
.copy(filterList.get(0)).workOrderNo(productionPartContext.getWorkOrderNo()).foreignKey(productionPartContext.foreignKey(foreignKey += 1).getForeignKey()));
prodRuleContextList.add(prodRuleContext);
log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- 设备:{} 产出零件信息:{} 产品加工规则:{} ---", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(),
StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), cellEquipContext.getEquipmentCode(), JSONObject.toJSONString(productionPartContext), JSONObject.toJSONString(prodRuleContext));
}
// 默认头道才有超工单
//validSuperWorkOrder(reqBean, productionPartContextList, null, workCenter, stepResult, resultBean);
return stepResult;
}
/**
* 1 MesProductionPartContext
* 2
* 3 ,
* @param reqBean
* @param productionPartContextList
* @param workCenter
* @param stepResult
* @param resultBean
* @return
*/
private StepResult validSuperWorkOrder(StationRequestBean reqBean, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList, MesWorkCenter workCenter, StepResult stepResult, StationResultBean resultBean) {
// 验证超工单
log.info("验证是否超工单begin ->");
//判断是否还存在待匹配的主条码信息, 内部循环匹配成功会标记 foreignKey
Optional<MesProductionPartContext> optional = productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkOrderNo()))).findFirst();
if (null == optional || !optional.isPresent()) return stepResult;
// 对MesProductionPartContext中的工单号经行分组每个工单可能对应多条数据,筛选掉foreignkey为空的数据
Map<String, List<MesProductionPartContext>> productionPartContextMap = productionPartContextList.stream().filter(productionPartContext -> !StringUtils.isEmpty(productionPartContext.getForeignKey()))
.collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo));
// 获取涉及到的所有工单列表
List<MesWorkOrder> workOrderList = workOrderExtService.getWorkOrderList(reqBean.getOrganizeCode(), new ArrayList<>(productionPartContextMap.keySet()));
// 对工单经行分组
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), String.format("请检查工单数量,工单号[%s],工单数量[%s]预完成数量[%s],且未配置超工单!", workOrder, mesWorkOrder.getQty().intValue(), complateQty.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(), complateQty.intValue(), workCenter.getOrderRate()));
}
log.info("验证超工单,工单号【{}】,qty=【{}】,complateQty =【{}】,isCheckOrderQty=【{}】, rate = 【{}】end ->", mesWorkOrder.getWorkOrderNo(), qty, complateQty,workCenter.getIsCheckOrderQty(),rate);
}
log.info("验证是否超工单end ->");
return stepResult;
}
//没有【产出零件数据】信息 , 根据进料条件获取匹配加工规则数据(只能查询到一条,否则报错)
private StepResult doHandleProdRuleDataByProductSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext,
MesCellEquipContext cellEquipContext, List<MesProdRuleContext> prodRuleContextList, List<MesProductionPsInContext> productionPsInContextList) {
//【非排序线】获取产品加工规则 ; 分别根据 进料零件有值 与 进料规则不为空 查询 再合并数据返回
List<MesProdRuleNosortCfg> prodRuleNosortCfgList = getProdRuleNosortCfgList(reqBean, cellEquipContext, productionPsInContextList, null);
//拿到当前最大的foreignKey
Optional<MesProductionPsInContext> maxForeignKeyOptional = productionPsInContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).max(Comparator.comparing(MesProductionPsInContext::getForeignKey));
Integer foreignKey = (null != maxForeignKeyOptional && maxForeignKeyOptional.isPresent()) ? maxForeignKeyOptional.get().getForeignKey() : MesPcnExtConstWords.ZERO;
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
//foreignKey有值代表已经匹配过产品加工规则
if (null == productionPsInContext || productionPsInContext.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 || !StringUtils.isEmpty(productionPsInContext.getForeignKey())) continue;
List<MesProdRuleNosortCfg> filterList;
//搜集进料零件号匹配的产品加工规则
if (!StringUtils.isEmpty(productionPsInContext.getPartNo())) filterList = filterProdRuleNosortCfgList(prodRuleNosortCfgList, productionPsInContext.getPartNo());
//进料零件条码匹配进料零件规则
else filterList = (List<MesProdRuleNosortCfg>) numberRuleMatchDispatchService.matchNumberRule(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), filterProdRuleNosortCfgList(prodRuleNosortCfgList));
if (CollectionUtils.isEmpty(filterList) || filterList.size() > 1) {
if (productionPsInContext.getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) productionPsInContext.busiCheckToDelete();
else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("设备[%s]与进料零件条码%s加工规则配置信息! 进料零件条码[%s]%s",
cellEquipContext.getEquipmentName(), CollectionUtils.isEmpty(filterList) ? "未匹配到" : String.format("匹配到[%s]条", filterList.size()), productionPsInContext.getProductSn(),
StringUtils.isEmpty(productionPsInContext.getPartNo()) ? "为外协件" : String.format("当前零件号[%s]", productionPsInContext.getPartNo())));
}
//时效性验证
if (!StringUtils.isEmpty(productionPsInContext.getPartNo())) {
Map<String, Object> result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), filterList.get(0).getId(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE20.getValue());
if (!(Boolean) result.get(MesPcnExtConstWords.RESULT)) {
if (productionPsInContext.getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) productionPsInContext.busiCheckToDelete();
else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productionPsInContext.getProductSn()), stepResult, (String) result.get(MesPcnExtConstWords.MESSAGE));
}
}
//【非排序线】获取产品加工规则对应的装配件信息
MesProdRuleContext prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(
new MesProdRuleContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode())
.copy(filterList.get(0)).productSn(productionPsInContext.getProductSn()).foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey()));
prodRuleContextList.add(prodRuleContext);
log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- 设备:{} 进料零件条码:{} 产品加工规则:{} ---", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(),
StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), cellEquipContext.getEquipmentCode(), JSONObject.toJSONString(productionPsInContext), JSONObject.toJSONString(prodRuleContext));
}
return stepResult;
}
private List<MesProdRuleNosortCfg> getProdRuleNosortCfgList(StationRequestBean reqBean, MesCellEquipContext cellEquipContext, List<MesProductionPsInContext> productionPsInContextList, List<String> outPartNoList) {
//【非排序线】获取产品加工规则 ; 分别根据 进料零件有值 与 进料规则不为空 查询 再合并数据返回, 条件可能携带产出零件
List<String> inPartNoList = productionPsInContextList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && !StringUtils.isEmpty(o.getPartNo()))).map(MesProductionPsInContext::getPartNo).collect(Collectors.toList());
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0 && StringUtils.isEmpty(o.getPartNo()))).findFirst();
List<MesProdRuleNosortCfg> prodRuleNosortCfgList = prodRuleCfgExtService.getProdRuleNosortCfgList(
!CollectionUtils.isEmpty(inPartNoList) ? new MesProdRuleContext(reqBean.getOrganizeCode()).equipmentCode(cellEquipContext.getEquipmentCode()).inPartNos(inPartNoList).outPartNos(outPartNoList) : null,
(null != optional && optional.isPresent()) ? new MesProdRuleContext(reqBean.getOrganizeCode()).equipmentCode(cellEquipContext.getEquipmentCode()).inPartIsEmpty(true).inPartRuleIsEmpty(false).outPartNos(outPartNoList) : null);
return prodRuleNosortCfgList;
}
//存在【产出零件数据】信息, 存在【进料零件条码信息】 获取匹配当前产出零件的加工规则数据 (只能查询到一条,否则报错)
private StepResult doHandleProdRuleDataByProductionPartAndProductSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext,
List<MesProdRuleContext> prodRuleContextList, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList, List<String> outPartNoList, Integer foreignKey) {
//【非排序线】获取产品加工规则 ; 分别根据 进料零件有值 与 进料规则不为空 查询 再合并数据返回, 条件携带产出零件
List<MesProdRuleNosortCfg> prodRuleNosortCfgList = getProdRuleNosortCfgList(reqBean, cellEquipContext, productionPsInContextList, outPartNoList);
//TODO 提示优化 直接根除产出零件去查询,判断产出零件对应的加工规则是不是仅仅维护了一个
//List<MesProdRuleNosortCfg> prodRuleNosortCfgList = prodRuleCfgExtService.getProdRuleNosortCfgList(new MesProdRuleContext(reqBean.getOrganizeCode()).equipmentCode(cellEquipContext.getEquipmentCode()).outPartNos(outPartNoList));
//根据产出零件分组数据
Map<String, List<MesProdRuleNosortCfg>> prodRuleNosortCfgMap = groupProdRuleNosortCfgList(prodRuleNosortCfgList);
for (MesProductionPartContext productionPartContext : productionPartContextList) {
//foreignKey有值代表已经匹配过产品加工规则
if (null == productionPartContext || productionPartContext.getIsFinishCode()
.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 || !StringUtils.isEmpty(productionPartContext.getForeignKey())) continue;
//获取匹配产出零件的所有加工规则
List<MesProdRuleNosortCfg> outPartNoProdRuleList = !CollectionUtils.isEmpty(prodRuleNosortCfgMap) ? prodRuleNosortCfgMap.get(productionPartContext.getPartNo()) : null;
MesProductionPsInContext productSn = null;
//判断是否还存在待匹配的主条码信息, 内部循环匹配成功会标记 foreignKey
Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).findFirst();
if (null == optional || !optional.isPresent()) break;
List<MesProdRuleNosortCfg> innerfilterList = null;
for (MesProductionPsInContext productionPsInContext : productionPsInContextList) {
//foreignKey有值代表已经匹配过产品加工规则
if (null == productionPsInContext || productionPartContext.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 || !StringUtils.isEmpty(productionPsInContext.getForeignKey())) continue;
//搜集进料零件号匹配的产品加工规则
if (!StringUtils.isEmpty(productionPsInContext.getPartNo())) innerfilterList = filterProdRuleNosortCfgList(outPartNoProdRuleList, productionPsInContext.getPartNo());
//进料零件条码匹配进料零件规则
else innerfilterList = (List<MesProdRuleNosortCfg>) numberRuleMatchDispatchService.matchNumberRule(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), filterProdRuleNosortCfgList(outPartNoProdRuleList));
if (CollectionUtils.isEmpty(innerfilterList) || innerfilterList.size() > 1) continue;
//验证进出一致
if (!StringUtils.isEmpty(productionPsInContext.getPartNo()) && productionPsInContext.getPartNo().equals(productionPartContext.getPartNo())) {
//进料工单必须与产出工单一致
if (!StringUtils.isEmpty(productionPartContext.getWorkOrderNo()) && !StringUtils.isEmpty(productionPsInContext.getWorkOrderNo()) && !productionPsInContext.getWorkOrderNo().equals(productionPartContext.getWorkOrderNo())) {
if (productionPsInContext.getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) productionPsInContext.busiCheckToDelete();
else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productionPsInContext.getProductSn()), stepResult, String.format("主条码[%s]零件号[%s]关联的加工单[%s]与产出零件[%s]关联的加工单[%s]不一致!",
productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), productionPsInContext.getWorkOrderNo(), productionPartContext.getPartNo(), productionPartContext.getWorkOrderNo()));
}
//进料存在工单且已经过某工序生产, 不能匹配无工单的产出零件
if (StringUtils.isEmpty(productionPartContext.getWorkOrderNo()) && !StringUtils.isEmpty(productionPsInContext.getWorkOrderNo()) && !StringUtils.isEmpty(productionPsInContext.getProcessCode())) {
if (productionPsInContext.getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) productionPsInContext.busiCheckToDelete();
else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productionPsInContext.getProductSn()), stepResult, String.format("主条码[%s]零件号[%s]已关联加工单[%s]且已经过工序[%s]工艺[%s],不支持匹配当前未关联加工单的产出零件[%s]",
productionPsInContext.getProductSn(), productionPsInContext.getPartNo(), productionPsInContext.getWorkOrderNo(), productionPsInContext.getProcessCode(), productionPsInContext.getCraftCode(), productionPartContext.getPartNo()));
}
}
//时效性验证
//if (!StringUtils.isEmpty(productionPsInContext.getPartNo())) {
// Map<String, Object> result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), productionPsInContext.getProductSn(), innerfilterList.get(0).getId(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE20.getValue());
//
// if (!(Boolean)result.get(MesPcnExtConstWords.RESULT)) {
// if (productionPsInContext.getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) productionPsInContext.busiCheckToDelete();
// else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
// return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productionPsInContext.getProductSn()), stepResult, (String) result.get(MesPcnExtConstWords.MESSAGE));
// }
//}
productionPartContext.foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey());
productSn = productionPsInContext;
break;
}
//【非排序线】获取产品加工规则对应的装配件信息
if (!CollectionUtils.isEmpty(innerfilterList) && innerfilterList.size() == 1) {
MesProdRuleContext prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(new MesProdRuleContext(
reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(),
reqBean.getProcessCode(), productionProcessContext.getCraftCode()).
copy(innerfilterList.get(0)).workOrderNo(productionPartContext.getWorkOrderNo()).productSn(productSn.getProductSn()))
.foreignKey(productionPartContext.getForeignKey());
prodRuleContextList.add(prodRuleContext);
log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- 设备:{} 产出零件信息:{} 进料零件条码:{} 产品加工规则:{} ---", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(),
StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), cellEquipContext.getEquipmentCode(), JSONObject.toJSONString(productionPartContext), JSONObject.toJSONString(productSn), JSONObject.toJSONString(prodRuleContext));
}
}
////判断是否还存在待匹配的主条码信息
//Optional<MesProductionPsInContext> optional = productionPsInContextList.stream().filter(o ->
// (null != o && StringUtils.isEmpty(o.getForeignKey()) && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).findFirst();
//if (null != optional && optional.isPresent()) {
// if (optional.get().getMessageSource().compareTo(MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN.getValue()) == 0) optional.get().busiCheckToDelete();
// else productionPsInContextList.forEach(o -> o.busiCheckToDelete());
// String productSnStr = productionPsInContextList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0))
// .map(o -> String.format(" 进料零件条码[%s]%s", o.getProductSn(), StringUtils.isEmpty(o.getPartNo()) ? "为外协件" : String.format("当前零件号[%s]", o.getPartNo()))).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
// return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnStr), stepResult, String.format("设备[%s]产出零件%s与进料零件条码未匹配到唯一的加工规则配置信息!%s", cellEquipContext.getEquipmentName(),
// productionPartContextList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getForeignKey()) && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).map(MesProductionPartContext::getPartNo).collect(Collectors.toList()).toString(),
// productSnStr));
//}
// 默认头道才有超工单
//validSuperWorkOrder(reqBean, productionPartContextList,productionPsInContextList,workCenter, stepResult, resultBean);
return stepResult;
}
//搜集进料零件号匹配的产品加工规则
private List<MesProdRuleNosortCfg> filterProdRuleNosortCfgList(List<MesProdRuleNosortCfg> prodRuleNosortCfgList, String partNo) {
return CollectionUtils.isEmpty(prodRuleNosortCfgList) ? null : prodRuleNosortCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getInPartNo()) && o.getInPartNo().equals(partNo))).collect(Collectors.toList());
}
//搜集进料零件规则有值的产品加工规则
private List<MesProdRuleNosortCfg> filterProdRuleNosortCfgList(List<MesProdRuleNosortCfg> prodRuleNosortCfgList) {
return CollectionUtils.isEmpty(prodRuleNosortCfgList) ? null : prodRuleNosortCfgList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getInPartNo()) && !StringUtils.isEmpty(o.getInPartNoRule()))).collect(Collectors.toList());
}
//根据产出零件分组数据
private Map<String, List<MesProdRuleNosortCfg>> groupProdRuleNosortCfgList(List<MesProdRuleNosortCfg> prodRuleNosortCfgList) {
return CollectionUtils.isEmpty(prodRuleNosortCfgList) ? null :
prodRuleNosortCfgList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProdRuleNosortCfg::getOutPartNo));
}
//显示装配件信息
public Boolean showProductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, MesWorkCenter workCenter, MesCellEquipContext cellEquipContext, List<MesProdRuleContext> prodRuleContextList) {
for (MesProdRuleContext prodRuleContext : prodRuleContextList) {
if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getAssemblyDataJson())) continue;
//封装匹配当前设备的装配件信息
List<MesAssemblyShowContext> assemblyShowContextList = getAssemblyShowContextList(cellEquipContext, prodRuleContext.getAssemblyDataContext(workCenter));
if (CollectionUtils.isEmpty(assemblyShowContextList)) continue;
//装配件清单列表标题
List<AttrBean> attrBeanList = dataAttrList(prodRuleContext.getWorkOrderNo());
//封装多表格
resultBean.addStationResultBeans(new StationResultBean().dataType(MesPcnEnumUtil.STATION_DATA_TYPE.TABLE.getValue()).dataAttrList(attrBeanList).resultList(assemblyShowContextList));
}
if (CollectionUtils.isEmpty(resultBean.getStationResultBeans())) return false;
resultBean.busiType(MesPcnEnumUtil.STATION_BUSI_TYPE.STEP_CUSTOM_CONTENT.getValue()).dataType(MesPcnEnumUtil.STATION_DATA_TYPE.TABLES.getValue());
this.sendMessage(reqBean, resultBean);
return true;
}
private String getWorkOrderNo(Map<Integer, MesProductionPartContext> productionPartMap, Integer foreignKey) {
return (!CollectionUtils.isEmpty(productionPartMap) && productionPartMap.containsKey(foreignKey)) ? productionPartMap.get(foreignKey).getWorkOrderNo() : null;
}
//封装匹配当前设备的装配件信息
private List<MesAssemblyShowContext> getAssemblyShowContextList(MesCellEquipContext cellEquipContext, List<MesProductionAssemblyContext> productionAssemblyContextList) {
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return null;
List<MesAssemblyShowContext> assemblyShowContextList = new ArrayList<>();
for (MesProductionAssemblyContext item : productionAssemblyContextList) {
//不显示且不扫描/仅目视的不显示出来
if (null == item || MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.checkIsNoShow(item.getMatchType())) continue;
assemblyShowContextList.add(assemblyShowContext(item));
}
assemblyShowContextList = assemblyShowContextList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesAssemblyShowContext::getRouteSeq)).collect(Collectors.toList());
AtomicReference<Integer> index = new AtomicReference<>(0);
assemblyShowContextList.forEach(o -> o.index(index.updateAndGet(v -> v + 1)));
return assemblyShowContextList;
}
//封装装配件信息
private MesAssemblyShowContext assemblyShowContext(MesProductionAssemblyContext o) {
MesAssemblyShowContext assemblyShowContext = new MesAssemblyShowContext();
BeanUtils.copyProperties(o, assemblyShowContext);
assemblyShowContext.setMatchTypeName(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.valueOfDescription(assemblyShowContext.getMatchType()));
assemblyShowContext.setAssemblyStatusName(MesExtEnumUtil.ASSEMBLY_STATUS.valueOfDescription(assemblyShowContext.getAssemblyStatus()));
if (MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue() != assemblyShowContext.getAssemblyStatus())
assemblyShowContext.setColor(StringUtils.isEmpty(assemblyShowContext.getShowColor()) ? MesExtEnumUtil.COLOR.GREEN.getValue() : assemblyShowContext.getShowColor());
return assemblyShowContext;
}
//装配件清单列表标题
private List<AttrBean> dataAttrList(String workOrderNo) {
List<AttrBean> attrBeanList = new ArrayList<>();
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.INDEX, "序号");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.MATCH_TYPE_NAME, "装配方式");
if (!StringUtils.isEmpty(workOrderNo)) PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.WORK_ORDER_NO, "生产工单编号");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.PART_NO, "零件编码");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.ASSEMBLY_PART_NO, "原料编码");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.ASSEMBLY_PART_NAME, "原料名称");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.ASSEMBLY_SN, "原料条码");
PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.ASSEMBLY_STATUS_NAME, "装配状态");
return attrBeanList;
}
//清除本次扫描/读取信息 有进料【只】需要清除进料,否则存在产出零件需要清除产出零件 【只需要清除被标记的数据】
private Boolean doBusiCheckToDelete(StationRequestBean reqBean, StepResult stepResult, List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList) {
if (!CollectionUtils.isEmpty(productionPsInContextList) && StringUtils.isEmpty(stepResult.getObj())) {
productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList.stream().filter(o -> (null != o && o.getBusiCheckToDelete().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).collect(Collectors.toList()));
} else if (!CollectionUtils.isEmpty(productionPartContextList)) {
if (!StringUtils.isEmpty(stepResult.getObj())) productionDispatchContextStepService.removeProductionPsInContext(reqBean);
productionDispatchContextStepService.removeProductionPartContext(reqBean);
productionDispatchContextStepService.removeProdRuleDataContext(reqBean);
productionProcessContextStepService.removeFunctionChooseCavityOrderContext(reqBean);
if (productionDispatchContextStepService.checkFirstMouldNoIsExistContext(reqBean)) {
//存在头道模具号场景下 必须抛出异常 因为头道模具号的接口逻辑会配置非常变值,也就是每次返回回去都会拿到头道模具号 就会出现死循环线程
productionDispatchContextStepService.removeFirstMouldNoContext(reqBean);
foundExThrowNoShowMsg();
}
}
return true;
}
}

@ -0,0 +1,323 @@
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.pojo.context.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.mes.pcn.util.StringUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
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.repository.MesProductionAssemblyRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCutRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
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.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesWorkOrderCutSaveStepService")
public class MesWorkOrderCutSaveStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IMesWorkOrderCutService workOrderCutService;
@Autowired
private MesWorkOrderCutRepository workOrderCutRepository;
@Autowired
private IFsmCommonService fsmCommonService;
@Autowired
private MesFirstMouldNoReadStepService firstMouldNoReadStepService;
@Autowired
private IMesProduceSnExtService produceSnExtService;
@Autowired
private ISyncFuncService syncFuncService;
@Autowired
private IFsmRouteDataService fsmRouteDataService;
@Autowired
private MesProductionAssemblyRepository productionAssemblyRepository;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
//获取上下文信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//存储生产过程上下文对象
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
//获取上下文生产扫/读信息:加工单
List<MesEquipVariableCollectContext> equipVariableCollectContextList = productionDispatchContextStepService.getScanWorkOrderNoContext(reqBean);
String cutWorkOrderNo = equipVariableCollectContextList.get(0).getEquipVariableValue();
//从上下文中取出工位当前要使用的设备
MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();
// 看是否修改裁片工单状态
//获取工位参数
Map<String, String> wcpcMap = fsmCommonService.handleFsmWcpcMapDataForDoScan(reqBean);
//获取上下文进料零件条码信息集合
List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);
//获取上下文产成零件条码信息集合
List<MesProductionPsOutContext> productionPsOutContextList = productionDispatchContextStepService.getProductionPsOutContext(reqBean);
//获取上下文产出零件数据信息集合
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
if (CollectionUtils.isEmpty(prodRuleContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在加工规则信息,请重置工序解决!");
// 根据产出零件号分组加工规则
Map<String, MesProdRuleContext> prodRuleContextMapByOutPartNo = prodRuleContextList.stream().collect(Collectors.toMap(MesProdRuleContext::getOutPartNo, Function.identity(), (x, y) -> y));
// 获取产成零件信息
Map<String, MesPart> partDataContext = productionDispatchContextStepService.getPartDataContext(reqBean);
// 无进料条码则生成条码
if (CollectionUtils.isEmpty(productionPsInContextList)) {
productionPsOutContextList = new ArrayList<>();
//获取生产线的当前班组班次信息
MesProdShiftContext prodShiftContext = productionCustomContextStepService.getMesProdShiftKvBean(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
if (null == prodShiftContext) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在生产开班记录,请重新开班!");
//从上下文中取出工位对象
MesWorkCell workCell = productionProcessContext.getWorkCell();
for (MesProductionPartContext mesProductionPartContext : productionPartContextList) {
MesPart part = partDataContext.get(mesProductionPartContext.getPartNo());
MesProdRuleContext mesProdRuleContext = prodRuleContextMapByOutPartNo.get(part.getPartNo());
MesProduceSn produceSn = new MesProduceSn();
ConvertBean.serviceModelInitialize(produceSn, reqBean.getUserInfo());
produceSn.setOrganizeCode(reqBean.getOrganizeCode());
produceSn.setProductSn(cutWorkOrderNo);
//produceSn.set
produceSn.setCustSn(produceSn.getCustSn());
produceSn.setSerialNumber(doGenerateSerialNo(reqBean, resultBean, MesPcnExtConstWords.DEFAULT_SERIAL_NUMBER_RULE, part));
produceSn.setQty(mesProductionPartContext.getQty());
produceSn.setWorkOrderNo(mesProductionPartContext.getWorkOrderNo());
produceSn.setCustCode(mesProductionPartContext.getCustCode());
produceSn.setCustPartNo(mesProductionPartContext.getCustPartNo());
produceSn.setAreaCode(workCell.getAreaCode());
produceSn.setWorkCenterCode(workCell.getWorkCenterCode());
produceSn.setWorkCellCode(workCell.getWorkCellCode());
produceSn.setPartNo(mesProductionPartContext.getPartNo());
produceSn.setPartName(mesProductionPartContext.getPartName());
produceSn.setProcessLabelTemplate(part.getProcessLabelTemplate());
produceSn.setProdLabelTemplate(part.getProductLabelTemplate());
produceSn.setCustLabelTemplate(part.getCustLabelTemplate());
produceSn.setSnType(MesExtEnumUtil.PRODUCE_SN_TYPE.STANDARD.getValue());
produceSn.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue());
produceSn.setQcStatus(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue());
produceSn.setShiftCode(prodShiftContext.getShiftCode());
produceSn.setShiftGroup(prodShiftContext.getShiftGroup());
produceSn.setPrintCount(MesPcnExtConstWords.ZERO);
produceSn.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.UNPRINT.getValue());
if (StringUtils.isEmpty(produceSn.getInWorkCenterTime())) produceSn.setInWorkCenterTime(produceSn.getModifyDatetime());
produceSn.setLotNo(produceSn.getModifyDatetime().substring(0, 10));
produceSn.setFid(UUID.randomUUID().toString());
produceSn = produceSnExtService.insert(produceSn);
MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().copy(produceSn, mesProdRuleContext.getForeignKey());
log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- MesProduceSn:{} --- MesProductionPsOutContext:{}",
reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(),
StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), JSONObject.toJSONString(produceSn), JSONObject.toJSONString(productionPsOutContext));
productionPsOutContextList.add(productionPsOutContext);
saveProductionAssembly(reqBean, productionProcessContext, cellEquipContext, mesProdRuleContext, productionPsOutContext);
}
//保存上下文产出条码数据信息集合
productionDispatchContextStepService.dispatchProductionPsOutContext(reqBean, productionPsOutContextList);
} else {
if (CollectionUtils.isEmpty(prodRuleContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在加工规则信息,请重置工序解决!");
//保存零件条码信息工步
((IStepService) SpringContextsUtil.getBean("mesProductSnSaveStepService")).executeInState(reqBean);
for (MesProductionPartContext mesProductionPartContext : productionPartContextList) {
Map<String, MesProductionPsOutContext> productionPsOutContextMap = productionPsOutContextList.stream().collect(Collectors.toMap(MesProductionPsOutContext::getPartNo, Function.identity(), (x, y) -> y));
MesPart part = partDataContext.get(mesProductionPartContext.getPartNo());
if (part == null)
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("产出零件号[%s]不存在,请重置工序解决!", part.getPartNo()));
MesProductionPsOutContext productionPsOutContext = productionPsOutContextMap.get(part.getPartNo());
if (productionPsOutContext == null)
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("产出零件号[%s]不存在,请重置工序解决!", part.getPartNo()));
MesProdRuleContext mesProdRuleContext = prodRuleContextMapByOutPartNo.get(part.getPartNo());
saveProductionAssembly(reqBean, productionProcessContext, cellEquipContext, mesProdRuleContext, productionPsOutContext);
}
}
//生成加工记录工步
((IStepService) SpringContextsUtil.getBean("mesProductionRecordGenerateStepService")).executeInState(reqBean);
// 是否修改工单状态为完成
String cutOrderOrderIsComplete = wcpcMap.containsKey(MesPcnExtConstWords.CUT_ORDER_ORDER_IS_COMPLETE) ? wcpcMap.get(MesPcnExtConstWords.CUT_ORDER_ORDER_IS_COMPLETE) : null;
if (!StringUtils.isEmpty(cutOrderOrderIsComplete)) {
updateWorkOrderCutStatus(reqBean, cutWorkOrderNo, MesExtEnumUtil.CUT_ORDER_STATUS.COMPLETE.getValue());
} else {
updateWorkOrderCutStatus(reqBean, cutWorkOrderNo, MesExtEnumUtil.CUT_ORDER_STATUS.PROCESS.getValue());
}
//保存装配记录工步
//((IStepService) SpringContextsUtil.getBean("mesAssemblySaveStepService")).executeInState(reqBean);
//保存工单信息工步
((IStepService) SpringContextsUtil.getBean("mesWorkOrderSaveStepService")).executeInState(reqBean);
return stepSuccessCompleteAndSendMsgReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "保存加工结果成功!");
}
private void saveProductionAssembly(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext,
MesCellEquipContext cellEquipContext, MesProdRuleContext mesProdRuleContext,
MesProductionPsOutContext productionPsOutContext) {
MesProductionAssembly productionAssembly = new MesProductionAssembly();
productionAssembly.setAssemblySn("");
productionAssembly.setDataSource(MesExtEnumUtil.PRODUCTION_ASSEMBLY_DATA_SOURCE.NOSORT.getValue());
productionAssembly.setIsOrigSn(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
productionAssembly.setIsSkip(CommonEnumUtil.FALSE);
productionAssembly.setAreaCode(reqBean.getWorkCenterCode());
productionAssembly.setWorkCenterCode(reqBean.getWorkCenterCode());
productionAssembly.setWorkCellCode(reqBean.getWorkCellCode());
productionAssembly.setProcessCode(reqBean.getProcessCode());
productionAssembly.setProcessName(productionProcessContext.getProcessName());
productionAssembly.setCraftCode(productionProcessContext.getCraftCode());
productionAssembly.setCraftName(productionProcessContext.getCraftName());
productionAssembly.setEquipmentCode(cellEquipContext.getEquipmentCode());
productionAssembly.setProductionRecordId(mesProdRuleContext.getProductionRecordId());
productionAssembly.setMouldNo(mesProdRuleContext.getMouldNo());
if (null != productionPsOutContext) {
productionAssembly.setPartNo(productionPsOutContext.getPartNo());
productionAssembly.setPartName(productionPsOutContext.getPartName());
productionAssembly.setSerialNumber(productionPsOutContext.getSerialNumber());
productionAssembly.setProductSn(productionPsOutContext.getProductSn());
productionAssembly.setCustSn(productionPsOutContext.getCustSn());
}
MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true);
if (null != scanMonitorContext) productionAssembly.setMouldRecordId(scanMonitorContext.getMouldRecordId());
productionAssembly.setOrganizeCode(reqBean.getOrganizeCode());
ConvertBean.serviceModelInitialize(productionAssembly, reqBean.getUserInfo());
productionAssembly.setFid(UUID.randomUUID().toString());
productionAssemblyRepository.insert(productionAssembly);
}
private void updateWorkOrderCutStatus(StationRequestBean reqBean, String cutWorkOrderNo, Integer status) {
DdlPackBean packBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode());
DdlPreparedPack.getStringEqualPack(cutWorkOrderNo, MesPcnExtConstWords.CUT_WORK_ORDER_NO, packBean);
workOrderCutRepository.updateByProperties(new String[]{MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.WORK_ORDER_STATUS},
new Object[]{reqBean.getUserInfo(), TimeTool.getNowTime(true), status},
packBean);
}
private String doGenerateSerialNo(StationRequestBean reqBean, StationResultBean resultBean, String ruleCode, MesPart part) {
try {
return syncFuncService.syncSerialNo(
new GenSerialNoModel(ruleCode).prodLocation(reqBean.getWorkCenterCode()).partNo(part.getPartNo()).putDataMap(MesPart.class.getSimpleName(), part).organizeCode(reqBean.getOrganizeCode()),
reqBean.getUserInfo(), reqBean.getOrganizeCode(), 1).getResultList().get(0).toString();
} catch (ImppBusiException e) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), e.getErrorDetail());
} catch (Exception e) {
String webMsg = String.format("零件编码[%s]编码规则代码[%s]生成零件条码%s", part.getPartNo(), ruleCode, fsmRouteDataService.handleFsmCfgOrDefault(reqBean, MesPcnEnumUtil.FSM_CFG.FSM_EXCEPTION_MSG.getCode()));
this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.ERROR.getValue()), webMsg, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
this.cacheException(reqBean, reqBean.getStepName(), webMsg, e, true);
foundExThrowNoShowMsg();
}
return null;
}
}

@ -70,15 +70,10 @@ public class MesWorkOrderCutScanStepService extends BaseStepService {
//存储生产过程上下文对象
productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);
//从上下文中取出生产线对象
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//如果没有扫描信息, 取手选工单信息, 封装扫/读信息:裁片工单信息
List<MesEquipVariableCollectContext> equipVariableCollectContextList;
List<MesEquipVariableCollectContext> equipVariableCollectContextList = new ArrayList<>();
//优先验证扫描裁片工单
if (!StringUtils.isEmpty(scanInfo)) equipVariableCollectContextList = doHandleScanWorkOrderNoContext(reqBean, stepResult, scanInfo);
//选择裁片工单
else equipVariableCollectContextList = doHandleScanWorkOrderNoContext(reqBean, stepResult, workCenter);
//扫描信息为空
if (CollectionUtils.isEmpty(equipVariableCollectContextList)) stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描裁片工单!");

@ -111,6 +111,17 @@ public class MesProductionPartContext implements Serializable {
@ApiParam("业务验证之后需要清除的数据标志")
private Integer busiCheckToDelete = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue();
// 裁片功能
@ApiParam("裁片方案代码")
private String cutCode;
@ApiParam("标包数量")
private Double packageQty;
@ApiParam("包装条码规则")
private String packageSnRule;
// 裁片功能
//根据一模多腔赋值
public MesProductionPartContext copyMouldMultiCavity(MesMouldMultiCavity mouldMultiCavity) {
BeanUtils.copyProperties(mouldMultiCavity, this, MesPcnExtConstWords.ID);

@ -86,6 +86,9 @@ public class MesProductionPsInContext implements Serializable {
@ApiParam("业务验证之后需要清除的数据标志")
private Integer busiCheckToDelete = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue();
@ApiParam("裁片方案代码")
private String cutCode;
public MesProductionPsInContext() {}
public MesProductionPsInContext foreignKey(Integer foreignKey) {
@ -133,4 +136,9 @@ public class MesProductionPsInContext implements Serializable {
return this;
}
public MesProductionPsInContext cutCode(String cutCode) {
this.cutCode = cutCode;
return this;
}
}

@ -0,0 +1,38 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.model;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import lombok.Data;
/**
* @Description :
* @Reference :
* @Author : jack.jia
* @CreateDate : 2019-04-02
* @Modify:
**/
@Data
@Api("裁片工单明细MODEL")
public class MesWorkOrderCutDetailModel {
@ApiParam("裁片工单号")
private String cutWorkOrderNo;
@ApiParam("工单号")
private String workOrderNo;
@ApiParam("物料号")
private String partNo;
@ApiParam("物料名称")
private String partName;
@ApiParam("产成数量")
private Double qty;
@ApiParam("标包数量")
private Double packageQty;
@ApiParam("包装条码规则")
private String packageSnRule;
}

@ -442,4 +442,7 @@ public class MesPcnExtConstWords {
// 裁片方案代码
public static final String CUT_CODE = "cutCode";
// 裁片成品列表弹框打印
public static final String FUNCITON_CUT_ORDER_DIALOG_PRINT = "FUNCTION_CUT_ORDER_DIALOG_PRINT";
}

Loading…
Cancel
Save