diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java index 57525ca..219a8d3 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java @@ -1,8 +1,6 @@ package cn.estsh.i3plus.ext.mes.pcn.api.busi; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdShiftContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; @@ -115,4 +113,10 @@ public interface IMesProductionCustomContextStepService { @ApiOperation(value = "删除排序线工单队列推送锁数据") void removeSortQueuePushLockContext(StationRequestBean reqBean, String queuePushId); + @ApiOperation(value = "处理工位维度的工单完成数上下文[查询]") + MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyCellContext(StationRequestBean reqBean, Boolean isCellNoCalcQty, MesProductionPartContext productionPartContext); + + @ApiOperation(value = "处理工位维度的工单完成数上下文[保存]") + void dispatchWorkOrderCompleteQtyCellContext(StationRequestBean reqBean, Boolean isCellNoCalcQty, String workOrderNo, Double calcCompleteQty); + } diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java index df51b07..b959656 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java @@ -28,6 +28,9 @@ public interface IMesProductionDispatchContextStepService { @ApiOperation(value = "获取上下文加工结果") String getProductResultContext(StationRequestBean reqBean); + @ApiOperation(value = "获取上下文加工结果") + Integer getProductResultQcContext(StationRequestBean reqBean); + @ApiOperation(value = "保存上下文加工结果", notes = "加工结果:成功/报废/可疑 【写入的值是变量类别代码对应的条码质量状态】【报废/可疑: 在保存逻辑条码时有特殊业务处理】") Boolean dispatchProductResultContext(StationRequestBean reqBean, String productResult); diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreDispatchService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreDispatchService.java new file mode 100644 index 0000000..f9f934b --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreDispatchService.java @@ -0,0 +1,28 @@ +package cn.estsh.i3plus.ext.mes.pcn.api.job; + +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCalcQtyRecord; +import cn.estsh.impp.framework.boot.exception.ImppBusiException; +import io.swagger.annotations.ApiOperation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +public interface IMesWorkOrderCalcQtyRestoreDispatchService { + + @ApiOperation(value = "查询生产工单计数记录表") + List getWorkOrderCalcQtyRecordList(String organizeCode, Integer qty); + + @ApiOperation(value = "查询工单") + @Transactional(propagation = Propagation.NOT_SUPPORTED) + MesWorkOrder getWorkOrderDb(String organizeCode, Long workOrderId); + + @ApiOperation(value = "补录生产工单计数JOB修改数据") + @Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {ImppBusiException.class, Exception.class}) + void doRestoreWorkOrderCalcQty(String organizeCode, MesWorkOrder workOrder, List value); + + @ApiOperation(value = "修改记录状态") + void saveWorkOrderCalcQtyRecord(String organizeCode, List idList, Integer dealStatus, String remark); + +} diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreService.java new file mode 100644 index 0000000..23ed63a --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/job/IMesWorkOrderCalcQtyRestoreService.java @@ -0,0 +1,12 @@ +package cn.estsh.i3plus.ext.mes.pcn.api.job; + +import io.swagger.annotations.ApiOperation; + +import java.util.Map; + +public interface IMesWorkOrderCalcQtyRestoreService { + + @ApiOperation(value = "补录离线生产工单数据JOB") + void doRestoreWorkOrderCalcQty(Map paramMap); + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesWorkOrderCalcQtyRestoreJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesWorkOrderCalcQtyRestoreJob.java new file mode 100644 index 0000000..20a2851 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesWorkOrderCalcQtyRestoreJob.java @@ -0,0 +1,77 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob; + + +import cn.estsh.i3plus.ext.mes.pcn.api.job.IMesWorkOrderCalcQtyRestoreService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StopWatch; +import org.springframework.util.StringUtils; + +import java.util.Map; + +/** + * @author wangjie + * @Description 生产工单计数补录JOB + * @version 1.0 + * @date 2021/2/2 16:44 + **/ +@Slf4j +@DisallowConcurrentExecution +@Component +@ApiOperation("补录生产工单计数JOB") +public class MesWorkOrderCalcQtyRestoreJob extends BaseMesScheduleJob { + + public MesWorkOrderCalcQtyRestoreJob() { + super(MesWorkOrderCalcQtyRestoreJob.class, "补录生产工单计数JOB"); + } + + @Autowired + private IMesWorkOrderCalcQtyRestoreService workOrderCalcQtyRestoreService; + + @Override + public void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + + String jobParam = this.getJobParam(); + if (StringUtils.isEmpty(jobParam)) { + log.info("--- 异常 --- 补录生产工单计数JOB --- 参数为空 ---"); + return; + } + + Map paramMap = JSONObject.parseObject(jobParam, Map.class); + + if (CollectionUtils.isEmpty(paramMap) || !paramMap.containsKey(MesPcnExtConstWords.ORGANIZE_CODE)) { + log.info("--- 异常 --- 补录生产工单计数JOB --- 参数未配置:工厂代码[organizeCode] ---"); + return; + } + + StopWatch stopWatch = new StopWatch(); + + try { + + stopWatch.start(); + + workOrderCalcQtyRestoreService.doRestoreWorkOrderCalcQty(paramMap); + + } catch (Exception e) { + + log.info("--- 异常 --- 补录生产工单计数JOB --- ERROR --- {} ---", e.toString()); + + } finally { + + stopWatch.stop(); + + log.info("补录生产工单计数JOB --- END --- 耗时: {} ms ---", stopWatch.getTotalTimeMillis()); + + } + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/ButtonDynamicExtService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/ButtonDynamicExtService.java index 635fe45..d2aadec 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/ButtonDynamicExtService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/ButtonDynamicExtService.java @@ -76,7 +76,7 @@ public class ButtonDynamicExtService extends ButtonDynamicService { MesConfig apiCfg = configService.getMesConfigByCfgCode(MesPcnExtConstWords.AUTO_INIT_WORK_CELL_MODULE_URL, organizeCode); if (null == configGateWay || StringUtils.isEmpty(configGateWay.getCfgValue())) return false; if (null == apiCfg || StringUtils.isEmpty(apiCfg.getCfgValue())) return false; - log.info("工厂{}生产线{}工位{}: --- 初始化工位按钮 --- START --- 执行结果:{}", organizeCode, workCenterCode, workCellCode); + log.info("工厂{}生产线{}工位{}: --- 初始化工位按钮 --- START", organizeCode, workCenterCode, workCellCode); Map paramsMap = new HashMap<>(); paramsMap.put(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode); paramsMap.put(MesPcnExtConstWords.ID, id.toString()); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreDispatchService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreDispatchService.java new file mode 100644 index 0000000..b3c1222 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreDispatchService.java @@ -0,0 +1,188 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.job; + +import cn.estsh.i3plus.ext.mes.pcn.api.job.IMesWorkOrderCalcQtyRestoreDispatchService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCalcQtyRecord; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCalcQtyRecordRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +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.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class MesWorkOrderCalcQtyRestoreDispatchService implements IMesWorkOrderCalcQtyRestoreDispatchService { + + @Autowired + private MesWorkOrderCalcQtyRecordRepository workOrderCalcQtyRecordRepository; + + @Autowired + private MesWorkOrderRepository workOrderRepository; + + @Override + public List getWorkOrderCalcQtyRecordList(String organizeCode, Integer qty) { + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getNumEqualPack(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.SYSTEM_SYNC_STATUS, packBean); + DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.CREATE_DATE_TIME}, packBean); + return workOrderCalcQtyRecordRepository.findByHqlTopWhere(packBean, qty); + } + + @Override + public MesWorkOrder getWorkOrderDb(String organizeCode, Long workOrderId) { + return workOrderRepository.getByProperty( + new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ID}, + new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderId}); + } + + @Override + public void doRestoreWorkOrderCalcQty(String organizeCode, MesWorkOrder workOrder, List workOrderCalcQtyRecordList) { + + //搜集记录ID集合 + List idList = workOrderCalcQtyRecordList.stream().filter(o -> null != o).map(MesWorkOrderCalcQtyRecord::getId).collect(Collectors.toList()); + if (null == workOrder) { + //修改记录状态 + saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_FAILURE.getValue(), "工单信息不存在"); + log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---", + workOrderCalcQtyRecordList.get(0).getWorkOrderNo(), workOrderCalcQtyRecordList.get(0).getId(), MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_FAILURE.getDescription(), "工单信息不存在", idList.toString()); + return; + } + + //计数 + Double completeQty = !StringUtils.isEmpty(workOrder.getCompleteQty()) ? workOrder.getCompleteQty() : new Double(MesPcnExtConstWords.ZERO); + Double suspiciousPartQty = !StringUtils.isEmpty(workOrder.getSuspiciousPartQty()) ? workOrder.getSuspiciousPartQty() : new Double(MesPcnExtConstWords.ZERO); + Double scrapPartQty = !StringUtils.isEmpty(workOrder.getScrapPartQty()) ? workOrder.getScrapPartQty() : new Double(MesPcnExtConstWords.ZERO); + for (MesWorkOrderCalcQtyRecord workOrderCalcQtyRecord : workOrderCalcQtyRecordList) { + if (null == workOrderCalcQtyRecord) continue; + if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getCompleteQty())) completeQty = MathOperation.add(completeQty, workOrderCalcQtyRecord.getCompleteQty()); + if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getSuspiciousPartQty())) suspiciousPartQty = MathOperation.add(suspiciousPartQty, workOrderCalcQtyRecord.getSuspiciousPartQty()); + if (!StringUtils.isEmpty(workOrderCalcQtyRecord.getScrapPartQty())) scrapPartQty = MathOperation.add(scrapPartQty, workOrderCalcQtyRecord.getScrapPartQty()); + } + + //未完成数 + Double unCompleteQty = !StringUtils.isEmpty(workOrder.getUnCompleteQty()) ? workOrder.getUnCompleteQty() : workOrder.getQty(); + unCompleteQty = MathOperation.compareTo(unCompleteQty, new Double(MesPcnExtConstWords.ZERO)) <= MesPcnExtConstWords.ZERO ? new Double(MesPcnExtConstWords.ZERO) : MathOperation.sub(workOrder.getQty(), completeQty); + if (MathOperation.compareTo(unCompleteQty, new Double(MesPcnExtConstWords.ZERO)) < MesPcnExtConstWords.ZERO) unCompleteQty = new Double(MesPcnExtConstWords.ZERO); + + //状态 + Integer workOrderStatus = workOrder.getWorkOrderStatus(); + if (workOrderStatus.compareTo(MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue()) == MesPcnExtConstWords.ZERO || workOrderStatus.compareTo(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()) == MesPcnExtConstWords.ZERO) { + if (MathOperation.compareTo(completeQty, workOrder.getQty()) >= MesPcnExtConstWords.ZERO) workOrderStatus = MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue(); + else workOrderStatus = MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue(); + } + + //添加修改属性 + Map propertyMap = new HashMap<>(); + Map conditionMap = new HashMap<>(); + conditionMap.put(MesPcnExtConstWords.ID, workOrder.getId()); + conditionMap.put(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode); + conditionMap.put(MesPcnExtConstWords.IS_DELETED, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + conditionMap.put(MesPcnExtConstWords.IS_VALID, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()); + if (MathOperation.compareTo(workOrder.getCompleteQty(), completeQty) != MesPcnExtConstWords.ZERO) { + propertyMap.put(MesPcnExtConstWords.COMPLETE_QTY, completeQty); + conditionMap.put(MesPcnExtConstWords.COMPLETE_QTY, workOrder.getCompleteQty()); + } + if (MathOperation.compareTo(workOrder.getSuspiciousPartQty(), suspiciousPartQty) != MesPcnExtConstWords.ZERO) { + propertyMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, suspiciousPartQty); + conditionMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, workOrder.getSuspiciousPartQty()); + } + if (MathOperation.compareTo(workOrder.getScrapPartQty(), scrapPartQty) != MesPcnExtConstWords.ZERO) { + propertyMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, scrapPartQty); + conditionMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, workOrder.getScrapPartQty()); + } + if (MathOperation.compareTo(workOrder.getUnCompleteQty(), unCompleteQty) != MesPcnExtConstWords.ZERO) { + propertyMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, unCompleteQty); + conditionMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, workOrder.getUnCompleteQty()); + } + if (workOrder.getWorkOrderStatus().compareTo(workOrderStatus) != MesPcnExtConstWords.ZERO) { + propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, workOrderStatus); + conditionMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, workOrder.getWorkOrderStatus()); + } + + //当前没有任何修改 + if (CollectionUtils.isEmpty(propertyMap)) { + //修改记录状态 + saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue(), "工单信息无变更"); + log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---", + workOrder.getWorkOrderNo(), workOrder.getId(), MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getDescription(), "工单信息无变更", idList.toString()); + return; + } + + //添加常规字段判断是否需要修改 + if (workOrder.getSystemSyncStatus().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) != 0) { + propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + conditionMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, workOrder.getSystemSyncStatus()); + } + + if (!workOrder.getSystemSyncDatetime().equals(MesPcnExtConstWords.EMPTY)) propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME, MesPcnExtConstWords.EMPTY); + + String userInfo = workOrderCalcQtyRecordList.get(workOrderCalcQtyRecordList.size() - MesPcnExtConstWords.ONE).getCreateUser(); + if (!workOrder.getModifyUser().equals(userInfo)) propertyMap.put(MesPcnExtConstWords.MODIFY_USER, userInfo); + + propertyMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date())); + conditionMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, workOrder.getModifyDatetime()); + + //修改值 + String[] propertyName = new String[propertyMap.size()]; + Object[] propertyValue = new Object[propertyMap.size()]; + + Integer index = 0; + for (Map.Entry innerEntry : propertyMap.entrySet()) { + if (null == innerEntry) continue; + propertyName[index] = innerEntry.getKey(); + propertyValue[index] = innerEntry.getValue(); + index ++; + } + + //修改条件 + String[] conditionName = new String[conditionMap.size()]; + Object[] conditionValue = new Object[conditionMap.size()]; + + index = 0; + for (Map.Entry innerEntry : conditionMap.entrySet()) { + if (null == innerEntry) continue; + conditionName[index] = innerEntry.getKey(); + conditionValue[index] = innerEntry.getValue(); + index ++; + } + + //当工单修改成功后, 再修改记录状态 + if (workOrderRepository.updateByPropertiesNoSync(conditionName, conditionValue, propertyName, propertyValue) == 1) { + //修改记录状态 + saveWorkOrderCalcQtyRecord(organizeCode, idList, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue(), "工单信息已变更成功"); + + log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- END --- conditionMap: {} --- propertyMap: {} --- {} {} --- MesWorkOrderCalcQtyRecord: {} ---", + workOrder.getWorkOrderNo(), workOrder.getId(), JSONObject.toJSONString(conditionMap), JSONObject.toJSONString(propertyMap), + MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getDescription(), "工单信息已变更成功", idList.toString()); + } + + } + + //修改记录状态 + @Override + public void saveWorkOrderCalcQtyRecord(String organizeCode, List idList, Integer dealStatus, String remark) { + String[] propertyName = new String[]{MesPcnExtConstWords.DEAL_STATUS, MesPcnExtConstWords.MODIFY_USER, + MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.REMARK}; + Object[] propertyValue = new Object[]{dealStatus, MesPcnExtConstWords.JOB, + (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), remark}; + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getInPackList(idList, MesPcnExtConstWords.ID, packBean); + workOrderCalcQtyRecordRepository.updateByPropertiesNoSync(propertyName, propertyValue, packBean); + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreService.java new file mode 100644 index 0000000..2a6c6f2 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/job/MesWorkOrderCalcQtyRestoreService.java @@ -0,0 +1,65 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.job; + +import cn.estsh.i3plus.ext.mes.pcn.api.job.IMesWorkOrderCalcQtyRestoreDispatchService; +import cn.estsh.i3plus.ext.mes.pcn.api.job.IMesWorkOrderCalcQtyRestoreService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCalcQtyRecord; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class MesWorkOrderCalcQtyRestoreService implements IMesWorkOrderCalcQtyRestoreService { + + @Autowired + private IMesWorkOrderCalcQtyRestoreDispatchService workOrderCalcQtyRestoreDispatchService; + + @Override + public void doRestoreWorkOrderCalcQty(Map paramMap) { + + //参数 工厂 + String organizeCode = paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE); + + //参数 处理数据量 + Integer qty = paramMap.containsKey(MesPcnExtConstWords.QTY) ? Integer.valueOf(paramMap.get(MesPcnExtConstWords.QTY)) : MesPcnExtConstWords.ONE_HUNDRED; + + //生产工单计数记录表 + List workOrderCalcQtyRecordList = workOrderCalcQtyRestoreDispatchService.getWorkOrderCalcQtyRecordList(organizeCode, qty); + + Map> workOrderNoMap = CollectionUtils.isEmpty(workOrderCalcQtyRecordList) ? null : + workOrderCalcQtyRecordList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesWorkOrderCalcQtyRecord::getWorkOrderNo)); + + log.info("补录生产工单计数JOB --- 查询到未补录完成的记录 {} 条 --- 生产工单包含: {} ---", + CollectionUtils.isEmpty(workOrderCalcQtyRecordList) ? "[]" : workOrderCalcQtyRecordList.size(), + CollectionUtils.isEmpty(workOrderNoMap) ? "[]" : workOrderNoMap.keySet().toString()); + + if (CollectionUtils.isEmpty(workOrderNoMap)) return; + + for (Map.Entry> entry : workOrderNoMap.entrySet()) { + + if (null == entry) continue; + + //查询工单, 无事务查询 + MesWorkOrder workOrder = workOrderCalcQtyRestoreDispatchService.getWorkOrderDb(organizeCode, entry.getValue().get(0).getPid()); + + if (null == workOrder) log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- START --- 信息不存在 ---", entry.getKey(), entry.getValue().get(0).getPid()); + else log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- START ---", entry.getKey(), entry.getValue().get(0).getPid()); + + try { + workOrderCalcQtyRestoreDispatchService.doRestoreWorkOrderCalcQty(organizeCode, workOrder, entry.getValue()); + } catch (Exception e) { + log.info("补录生产工单计数JOB --- 补录: {} --- ID: {} --- EXCEPTION: {} ---", entry.getKey(), entry.getValue().get(0).getPid(), e.toString()); + } + + } + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java index 1b321aa..a0d855e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -165,4 +166,41 @@ public class MesTimeEfficientCfgMatchService implements IMesTimeEfficientCfgMatc return true; } + public static void main(String[] args) { + try { + Double minValue = 1d; + Double maxValue = 240d; + SimpleDateFormat sdf = new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT); +// Date now = new Date(); + Date now = sdf.parse("2025-03-21 11:19:06"); + Date productDateTime = sdf.parse("2025-03-21 11:15:06"); + int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000)); + Integer matchRule = 40; + if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_20.getValue().equals(matchRule)) { + //差值 小于最小时差有效 + if (minDiff >= minValue){ + System.out.println(false); + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_30.getValue().equals(matchRule)) { + // 差值 大于最大时差有效 + if (minDiff <= maxValue){ + System.out.println(false); + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_40.getValue().equals(matchRule)) { + // 差值 最大最小时差有效 在 最大值 最小值之间 + if (minDiff <= minValue || minDiff >= maxValue){ + System.out.println(false); + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_50.getValue().equals(matchRule)) { + // 差值 最大外或最小内有效 + if (minDiff >= minValue && minDiff <= maxValue){ + System.out.println(false); + } + } + System.out.println("执行完成"); + } catch (ParseException e) { + e.printStackTrace(); + } + } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblySaveStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblySaveStepService.java index fc20a1b..09f2c43 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblySaveStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblySaveStepService.java @@ -86,6 +86,7 @@ public class MesAssemblySaveStepService extends BaseStepService { if (CollectionUtils.isEmpty(productionPsOutContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在产出零件条码信息,请重置工序解决!"); + //获取上下文工位扫描监控信息 MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true); //从上下文中取出工位当前要使用的设备 diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java index 6aedb9b..7ebe1a1 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java @@ -1,19 +1,18 @@ 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.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; 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.serviceimpl.fsm.BaseStepService; import cn.estsh.i3plus.mes.pcn.util.PojoAttrUtil; import cn.estsh.i3plus.mes.pcn.util.StringUtil; -import cn.estsh.i3plus.platform.common.tool.MathOperation; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.bean.MesProdRuleIgnoreCfg; 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; @@ -60,6 +59,9 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { @Autowired private IFsmCommonService fsmCommonService; + @Autowired + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; + @Override public StepResult execute(StationRequestBean reqBean) { @@ -102,8 +104,12 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //封装非排序加工规则 doHandleProdRuleData(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList); + //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则 + workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext( + reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList); + //匹配失败需要清除本次扫描/读取信息 - if (!stepResult.isCompleted() && doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList)) + if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.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) { @@ -193,72 +199,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { 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 productionPartContextList, List productionPsInContextList, MesWorkCenter workCenter, StepResult stepResult, StationResultBean resultBean) { - // 验证超工单 - log.info("验证是否超工单begin ->"); - - //判断是否还存在待匹配的主条码信息, 内部循环匹配成功会标记 foreignKey - Optional optional = productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkOrderNo()))).findFirst(); - if (null == optional || !optional.isPresent()) return stepResult; - - // 对MesProductionPartContext中的工单号经行分组,每个工单可能对应多条数据,筛选掉foreignkey为空的数据 - Map> productionPartContextMap = productionPartContextList.stream().filter(productionPartContext -> !StringUtils.isEmpty(productionPartContext.getForeignKey())) - .collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo)); - // 获取涉及到的所有工单列表 - List workOrderList = workOrderExtService.getWorkOrderList(reqBean.getOrganizeCode(), new ArrayList<>(productionPartContextMap.keySet())); - - // 对工单经行分组 - Map> orderListMap = workOrderList.stream().collect(Collectors.groupingBy(MesWorkOrder::getWorkOrderNo)); - - for (Map.Entry> entry : productionPartContextMap.entrySet()) { - String workOrder = entry.getKey(); - List productionPartContexts = entry.getValue(); - MesWorkOrder mesWorkOrder = orderListMap.get(workOrder).get(0); - - Double complateQty = mesWorkOrder.getCompleteQty() + productionPartContexts.size(); - Double qty = mesWorkOrder.getQty(); - log.info("验证超工单,工单号【{}】,qty=【{}】,complateQty =【{}】begin ->", mesWorkOrder.getWorkOrderNo(), qty, complateQty); - // 如果预完成数量 小于等于工单数量,则直接过 - if (complateQty <= qty) continue; - - // 以下则是超工单逻辑 - // 如果产线中没有配置超工单,则直接阻断 - if (!Objects.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), workCenter.getIsCheckOrderQty())) { - productionPartContextList.forEach(o -> o.busiCheckToDelete()); - if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); - return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), - MathOperation.compareTo(mesWorkOrder.getQty(), mesWorkOrder.getCompleteQty()) == 0 - ? String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前已完成!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue()) - : String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前不支持超工单!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue())); - } - // 如果配置了超工单,且比例已经超过了配置的超工单比例,也需要阻断 - Double rate = (complateQty - qty)/qty; - if (rate > workCenter.getOrderRate()/100) { - productionPartContextList.forEach(o -> o.busiCheckToDelete()); - if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); - return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), - String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前超出超工单比例[%s]!", workOrder, mesWorkOrder.getQty().intValue(), mesWorkOrder.getCompleteQty().intValue(), workCenter.getOrderRate())); - } - log.info("验证超工单,工单号【{}】,qty=【{}】,complateQty =【{}】,isCheckOrderQty=【{}】, rate = 【{}】end ->", mesWorkOrder.getWorkOrderNo(), qty, complateQty,workCenter.getIsCheckOrderQty(),rate); - } - log.info("验证是否超工单end ->"); return stepResult; } @@ -453,8 +394,6 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { productSnStr)); } - // 默认头道才有超工单 - validSuperWorkOrder(reqBean, productionPartContextList,productionPsInContextList,workCenter, stepResult, resultBean); return stepResult; } @@ -592,22 +531,6 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { return attrBeanList; } - //清除本次扫描/读取信息 有进料【只】需要清除进料,否则存在产出零件需要清除产出零件 【只需要清除被标记的数据】 - private Boolean doBusiCheckToDelete(StationRequestBean reqBean, StepResult stepResult, List productionPartContextList, List 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; - } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java index ffcfdd1..543b073 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java @@ -177,7 +177,7 @@ public class MesProductSnCheckStepService extends BaseStepService { } //未知条码, 工序为空, 条码数量等于1, 已打印 【打印件, 首工位自进自出未加工完成】 - if (produceSn.getPrintStatus().compareTo(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue()) == 0) { + if (!StringUtils.isEmpty(produceSn.getPrintStatus()) && produceSn.getPrintStatus().compareTo(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue()) == 0) { productionPsInContextList.add(new MesProductionPsInContext(produceSn).isCheck(workCell).messageSource(equipVariableCollectContext.getMessageSource()).relateId(produceSn.getId())); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java index 65f14b2..547f50a 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java @@ -5,6 +5,7 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService; 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.apiservice.serviceimpl.step.method.MesPartDataMapSaveStepService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; 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.IFsmRouteDataService; @@ -74,6 +75,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { @Autowired private IMesProdShiftRecordService prodShiftRecordService; + @Autowired + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; + @Override public StepResult execute(StationRequestBean reqBean) { @@ -154,9 +158,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { MesPart part = partDataMap.get(prodRuleContext.getOutPartNo()); //验证进料零件与产出零件是否一致 - Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, prodRuleContext); - //工位是否不累计工单完成数 - Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty()); + Boolean isSamePart = workOrderCheckCompleteQtyStepService.isSamePart(productionPsInContext, productionPartContext, prodRuleContext); + //验证是否计数 + Boolean isCalcCompleteQty = workOrderCheckCompleteQtyStepService.isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext); MesProduceSn produceSn; //进出一致, 不累计工单完成数量 在显示装配件工步中已经验证了 进出一致 进出存在工单则必须一致 @@ -222,7 +226,9 @@ public class MesProductSnGenerateStepService extends BaseStepService { produceSn = produceSnExtService.insert(produceSn); } else produceSnExtService.updateNoSync(produceSn); - MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().copy(produceSn, prodRuleContext.getForeignKey()).isCalcCompleteQty(isCalcCompleteQty(isCellNoCalcQty, isSamePart, productionPartContext)); + //isCalcCompleteQty=true的情况下【工位是否不累计工单完成数isCellNoCalcQty=true最终不会实际累加到工单上】【isCellNoCalcQty=false代表生产线维度的统计,才会实际累加到工单上】 + MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext() + .copy(produceSn, prodRuleContext.getForeignKey()).isCalcCompleteQty(isCalcCompleteQty, isSamePart, workCell.getNoCalcOrderQty()); log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- MesProduceSn:{} --- MesProductionPsOutContext:{}", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), @@ -256,31 +262,4 @@ public class MesProductSnGenerateStepService extends BaseStepService { return part.getProductMatchRule(); } - //验证进料零件与产出零件是否一致 - private Boolean isSamePart(MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext, MesProdRuleContext prodRuleContext) { - if (null == productionPsInContext) return false; - if (StringUtils.isEmpty(productionPsInContext.getPartNo())) return false; - if (null != productionPartContext) { - if (!productionPsInContext.getPartNo().equals(productionPartContext.getPartNo())) return false; - else return true; - } else { - if (!productionPsInContext.getPartNo().equals(prodRuleContext.getOutPartNo())) return false; - else return true; - } - } - - //工位是否不累计工单完成数 - private Boolean isCellNoCalcQty(Integer noCalcOrderQty) { - return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false; - } - - //判断是否累计工单完成数 - private Boolean isCalcCompleteQty(Boolean isCellNoCalcQty, Boolean isSamePart, MesProductionPartContext productionPartContext) { - //工位不消耗工单完成数 - if (isCellNoCalcQty) return false; - //未选工单场景 - if (null == productionPartContext || StringUtils.isEmpty(productionPartContext.getWorkOrderNo())) return false; - return isSamePart ? false : true; - } - } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java new file mode 100644 index 0000000..8631098 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java @@ -0,0 +1,81 @@ +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.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; +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.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.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.model.StationResultBean; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.StringJoiner; + +/** + * @Description : 验证加工单数量后保存加工结果工步 + * @Author : wangjie + **/ +@Slf4j +@Service("mesProductionDataSaveBeforeLockOrderStepService") +public class MesProductionDataSaveBeforeLockOrderStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Autowired + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; + + @Override + public StepResult execute(StationRequestBean reqBean) { + + StationResultBean resultBean = new StationResultBean(); + + StepResult stepResult = StepResult.getSuccessComplete(); + + //获取上下文信息: 处理加工不可用规则 + MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchProdRuleIgnoreCfgContext(reqBean); + + //配置错误 抛出异常 + if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + + //存储生产过程上下文对象 + productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); + + //获取上下文产出零件数据信息集合 + List productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean); + + //获取上下文进料零件条码信息集合 + List productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean); + + synchronized (new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()).add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).toString().intern()) { + + //验证加工单完成数量 + workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext( + reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList); + + //匹配失败需要清除本次扫描/读取信息 + if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList)) + return stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_PART_NO); + + //非排序线 保存加工结果工步 execute 方法 使用的是 新事务 + stepResult = ((IStepService) SpringContextsUtil.getBean("mesProductionDataSaveStepService")).execute(reqBean); + + } + + return stepResult; + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveStepService.java index bf53035..aa59548 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveStepService.java @@ -1,8 +1,10 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +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.StringUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.model.StationResultBean; @@ -53,7 +55,7 @@ public class MesProductionDataSaveStepService extends BaseStepService { LinkedList stepList = !isSort ? noSortStepList : sortStepList; for (String stepService : stepList) { - if (StringUtils.isEmpty(stepResult)) continue; + if (StringUtils.isEmpty(stepService)) continue; StepResult innerStepResult = ((IStepService) SpringContextsUtil.getBean(stepService)).executeInState(reqBean); if (!StringUtils.isEmpty(innerStepResult.getNextTriggerEvent())) stepResult.nextTriggerEvent(innerStepResult.getNextTriggerEvent()); if (!StringUtils.isEmpty(innerStepResult.getStepAfterState())) stepResult.stepAfterState(innerStepResult.getStepAfterState()); @@ -63,5 +65,4 @@ public class MesProductionDataSaveStepService extends BaseStepService { return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "保存加工结果成功!"); } - } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionRecordGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionRecordGenerateStepService.java index 00dcc01..ef056d1 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionRecordGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionRecordGenerateStepService.java @@ -102,8 +102,13 @@ public class MesProductionRecordGenerateStepService extends BaseStepService { //获取上下文(头道)模具号 String mouldNo = getMouldNo(reqBean, workCenter, prodRuleContextList); + //获取上下文工位扫描监控信息 + MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true); + //生成加工记录 - productionPsOutContextList.stream().filter(o -> null != o).forEach(o -> saveProductionRecordData(reqBean, workCenter, mouldNo, prodRuleContextList, productionProcessContext, o, prMap, cellEquipContext, CollectionUtils.isEmpty(psiMap) ? null : psiMap.get(o.getForeignKey()))); + productionPsOutContextList.stream().filter(o -> null != o).forEach(o -> + saveProductionRecordData(reqBean, workCenter, scanMonitorContext, mouldNo, prodRuleContextList, productionProcessContext, o, prMap, cellEquipContext, CollectionUtils.isEmpty(psiMap) ? null : psiMap.get(o.getForeignKey())) + ); //保存上下文产品加工规则信息集合 productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); @@ -119,8 +124,9 @@ public class MesProductionRecordGenerateStepService extends BaseStepService { } - private void saveProductionRecordData(StationRequestBean reqBean, MesWorkCenter workCenter, String mouldNo, List prodRuleContextList, MesProductionProcessContext productionProcessContext, - MesProductionPsOutContext productionPsOutContext, Map prMap, MesCellEquipContext cellEquipContext, MesProductionPsInContext productionPsInContext) { + private void saveProductionRecordData(StationRequestBean reqBean, MesWorkCenter workCenter, MesScanMonitorContext scanMonitorContext, String mouldNo, + List prodRuleContextList, MesProductionProcessContext productionProcessContext, MesProductionPsOutContext productionPsOutContext, + Map prMap, MesCellEquipContext cellEquipContext, MesProductionPsInContext productionPsInContext) { MesProdRuleContext prodRuleContext = CollectionUtils.isEmpty(prMap) ? null : prMap.get(productionPsOutContext.getForeignKey()); @@ -163,7 +169,6 @@ public class MesProductionRecordGenerateStepService extends BaseStepService { productionRecord.setProcessCode(reqBean.getProcessCode()); productionRecord.setCraftCode(productionProcessContext.getCraftCode()); - MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true); if (null != scanMonitorContext) { productionRecord.setMouldRecordId(scanMonitorContext.getMouldRecordId()); productionRecord.setStartDateTime(scanMonitorContext.getStartDateTime()); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderCutSaveStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderCutSaveStepService.java index 624cb57..1d3dee8 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderCutSaveStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderCutSaveStepService.java @@ -1,24 +1,14 @@ 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.mes.pcn.serviceimpl.fsm.BaseStepService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; -import cn.estsh.i3plus.platform.common.convert.ConvertBean; -import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; -import cn.estsh.i3plus.pojo.mes.bean.*; 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.util.MesExtEnumUtil; import cn.estsh.impp.framework.boot.util.SpringContextsUtil; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - -import java.util.*; /** * @Description : 裁片工单保存加工结果工步【非排序】 * @Author : wangjie @@ -27,12 +17,6 @@ import java.util.*; @Service("mesWorkOrderCutSaveStepService") public class MesWorkOrderCutSaveStepService extends BaseStepService { - @Autowired - private IMesProductionProcessContextStepService productionProcessContextStepService; - - @Autowired - private MesProductionAssemblyRepository productionAssemblyRepository; - @Override public StepResult execute(StationRequestBean reqBean) { @@ -54,48 +38,5 @@ public class MesWorkOrderCutSaveStepService extends BaseStepService { 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.getAreaCode()); - 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); - } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepService.java index 3902246..65e10ff 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepService.java @@ -1,22 +1,25 @@ 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.IMesWorkOrderExtService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; 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.MesProductionPsOutContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesScanMonitorContext; 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.StringUtil; +import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.tool.MathOperation; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; -import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrderCalcQtyRecord; 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.MesWorkOrderRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderCalcQtyRecordRepository; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; @@ -25,9 +28,11 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import javax.persistence.EntityManager; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -48,13 +53,13 @@ public class MesWorkOrderSaveNosortStepService extends BaseStepService { private IMesProductionDispatchContextStepService productionDispatchContextStepService; @Autowired - private IMesWorkOrderExtService workOrderExtService; + private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService; @Autowired - private MesWorkOrderRepository workOrderRepository; + private MesWorkOrderCalcQtyRecordRepository workOrderCalcQtyRecordRepository; @Autowired - private EntityManager entityManager; + private IMesProductionCustomContextStepService productionCustomContextStepService; @Override public StepResult execute(StationRequestBean reqBean) { @@ -83,22 +88,31 @@ public class MesWorkOrderSaveNosortStepService extends BaseStepService { List productionPsOutContextList = productionDispatchContextStepService.getProductionPsOutContext(reqBean); //保存生产工单数据 - doHandleWorkOrderData(reqBean, resultBean, productionPartContextList, productionPsOutContextList); + doHandleWorkOrderData(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsOutContextList); return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "保存加工单信息成功!"); } //保存生产工单数据 - private void doHandleWorkOrderData(StationRequestBean reqBean, StationResultBean resultBean, List productionPartContextList, List productionPsOutContextList) { + private void doHandleWorkOrderData(StationRequestBean reqBean, StationResultBean resultBean, + StepResult stepResult, MesProductionProcessContext productionProcessContext, + List productionPartContextList, List productionPsOutContextList) { + + //工位是否不累计工单完成数 + Boolean isCellNoCalcQty = workOrderCheckCompleteQtyStepService.isCellNoCalcQty(productionProcessContext.getWorkCell().getNoCalcOrderQty()); + + //获取上下文工位扫描监控信息 + MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true); //产出零件信息根据生产工单分组 Map> ppMap = productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo)); //产出条码 根据生产工单分组 - Map> proMap = productionPsOutContextList.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(MesProductionPsOutContext::getWorkOrderNo)); + Map> proMap = productionPsOutContextList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProductionPsOutContext::getWorkOrderNo)); - String productResult = productionDispatchContextStepService.getProductResultContext(reqBean); + //获取上下文加工结果 + Integer productResult = productionDispatchContextStepService.getProductResultQcContext(reqBean); //遍历产出零件信息 for(Map.Entry> entry : ppMap.entrySet()) { @@ -107,86 +121,89 @@ public class MesWorkOrderSaveNosortStepService extends BaseStepService { //获取对应的加工规则 List produceSnContextList = proMap.get(entry.getKey()); //生产数量 - Integer calcCompleteQty = 0; + Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO); //遍历产出物料 for (MesProductionPsOutContext productionPsOutContext : produceSnContextList) { if (null == productionPsOutContext) continue; - //产出零件是否是 - if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty += 1; + //产出零件需要计算工单完成数量 + if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE)); } - if (calcCompleteQty.compareTo(MesPcnExtConstWords.ZERO) == 0) continue; - - MesWorkOrder workOrder = workOrderExtService.getWorkOrder(reqBean.getOrganizeCode(), entry.getValue().get(0).getId()); + if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) continue; - if (null == workOrder) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息不存在!", entry.getKey())); + // 赋值 stepAfterState, 当前工步集执行结束后会执行当前工步重写的executeStepAfterState方法 + if (StringUtils.isEmpty(stepResult.getStepAfterState())) stepResult.stepAfterState(StringUtil.toLowerCaseFirst(this.getClass().getSimpleName())); - //工单状态分 排序工单 和非排序工单; 现在必须是非排序工单 - if (!MesExtEnumUtil.ORDER_STATUS.checkNosortAllowStatus(workOrder.getWorkOrderStatus())) - stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息工单状态[%s]!", entry.getKey(), MesExtEnumUtil.ORDER_STATUS.valueOfDescription(workOrder.getWorkOrderStatus()))); - //工单产线要和当前产线一致 - if (!workOrder.getWorkCenterCode().equals(reqBean.getWorkCenterCode())) - stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息所属生产线[%s]与当前生产线[%s]不一致!", entry.getKey(), workOrder.getWorkCenterCode(), reqBean.getWorkCenterCode())); + //TODO 排序考虑多工位扫描可疑码; 非排序考虑自进自出可疑或报废; 可疑数/报废数是否需要增加的问题[条码+零件+质量状态 增加履历] - Map propertyMap = new HashMap<>(); + //工位不累计工单完成数 + if (isCellNoCalcQty) continue; - //修改完成数量 - propertyMap.put(MesPcnExtConstWords.COMPLETE_QTY, MathOperation.add(workOrder.getCompleteQty(), calcCompleteQty)); - - //修改未完成数量 - if (workOrder.getUnCompleteQty().compareTo(new Double(0)) > 0 && MathOperation.compareTo(MathOperation.sub(workOrder.getUnCompleteQty(), new Double(calcCompleteQty)), new Double(0)) >= 0) { - propertyMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, MathOperation.sub(workOrder.getUnCompleteQty(), new Double(calcCompleteQty))); + MesWorkOrderCalcQtyRecord workOrderCalcQtyRecord = new MesWorkOrderCalcQtyRecord(); + workOrderCalcQtyRecord.setOrganizeCode(reqBean.getOrganizeCode()); + workOrderCalcQtyRecord.setWorkCenterCode(reqBean.getWorkCenterCode()); + workOrderCalcQtyRecord.setWorkCellCode(reqBean.getWorkCellCode()); + workOrderCalcQtyRecord.setWorkOrderNo(entry.getKey()); + workOrderCalcQtyRecord.setPid(entry.getValue().get(0).getId()); + workOrderCalcQtyRecord.setCompleteQty(calcCompleteQty); + //可疑数量 + if (!StringUtils.isEmpty(productResult) && productResult.compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS.getValue()) == 0) { + workOrderCalcQtyRecord.setSuspiciousPartQty(calcCompleteQty); } - - /** - * 可疑品、报废数量、上下线时间; - * sql改成修改固定字段 - * 在上下文中获取busi中获取prodResult上下文 是数字 (标志着条码质量状态,与条码质量状态枚举一致) - * 上下文中 已经按照工单分组了,因为有一模多腔问题 - */ - - if (!StringUtils.isEmpty(productResult)) { - //可疑品 - if (Integer.valueOf(productResult).compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS.getValue()) == 0 && !CollectionUtils.isEmpty(productionPsOutContextList)){ - propertyMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, MathOperation.add(workOrder.getSuspiciousPartQty(), new Double(productionPsOutContextList.size()))); - } - //报废数量 - if (Integer.valueOf(productResult).compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SCRAP.getValue()) == 0 && !CollectionUtils.isEmpty(productionPsOutContextList)){ - propertyMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, MathOperation.add(workOrder.getScrapPartQty(), new Double(productionPsOutContextList.size()))); - } + //报废数量 + if (!StringUtils.isEmpty(productResult) && productResult.compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SCRAP.getValue()) == 0) { + workOrderCalcQtyRecord.setScrapPartQty(calcCompleteQty); } - if (MathOperation.compareTo(MathOperation.add(workOrder.getCompleteQty(), calcCompleteQty), workOrder.getQty()) >= 0 && workOrder.getWorkOrderStatus().compareTo(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()) != 0) { - propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()); - } else if (workOrder.getCompleteQty() >= 0 && workOrder.getWorkOrderStatus() == MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue()) { - propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()); - } + if (null != scanMonitorContext) workOrderCalcQtyRecord.setMouldRecordId(scanMonitorContext.getMouldRecordId()); - if (CollectionUtils.isEmpty(propertyMap)) continue; + workOrderCalcQtyRecord.setDealStatus(MesExtEnumUtil.MES_LOG_DEAL_STATUS.UNDEAL.getValue()); + workOrderCalcQtyRecord.setCreateUser(reqBean.getUserInfo()); + workOrderCalcQtyRecord.setModifyUser(reqBean.getUserInfo()); + workOrderCalcQtyRecord.setCreateDatetime((new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date())); + workOrderCalcQtyRecord.setModifyDatetime(workOrderCalcQtyRecord.getCreateDatetime()); + workOrderCalcQtyRecord.setIsValid(CommonEnumUtil.IS_VAILD.VAILD.getValue()); + workOrderCalcQtyRecord.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); - propertyMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date())); - propertyMap.put(MesPcnExtConstWords.MODIFY_USER, reqBean.getUserInfo()); - propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); - propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME, MesPcnExtConstWords.EMPTY); + workOrderCalcQtyRecord = workOrderCalcQtyRecordRepository.insert(workOrderCalcQtyRecord); - String[] propertyName = new String[propertyMap.size()]; - Object[] propertyValue = new Object[propertyMap.size()]; + log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- ORDER:{} --- QUERY_CompleteQty:{} --- productResult:{} --- MesWorkOrderCalcQtyRecord:{}", + reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), + StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), entry.getKey(), entry.getValue().get(0).getCompleteQty(), productResult, JSONObject.toJSONString(workOrderCalcQtyRecord)); - Integer index = 0; - for (Map.Entry innerEntry : propertyMap.entrySet()) { - if (null == innerEntry) continue; - propertyName[index] = innerEntry.getKey(); - propertyValue[index] = innerEntry.getValue(); - index ++; - } + } + } + + //当前工步集完成之后执行当前方法 + @Override + public void executeStepAfterState(StationRequestBean reqBean, StepResult stepResult) { + if (!stepResult.isCompleted()) return; + + //获取上下文产出零件数据信息集合 + List productionPsOutContextList = productionDispatchContextStepService.getProductionPsOutContext(reqBean); + if (CollectionUtils.isEmpty(productionPsOutContextList)) return; - workOrderRepository.updateByPropertiesNoSync(new String[]{MesPcnExtConstWords.ID, MesPcnExtConstWords.ORGANIZE_CODE}, new Object[]{workOrder.getId(), reqBean.getOrganizeCode()}, propertyName, propertyValue); + //工位是否不累计工单完成数 + Boolean isCellNoCalcQty = workOrderCheckCompleteQtyStepService.isCellNoCalcQty(productionPsOutContextList.get(0).getNoCalcOrderQty()); - log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- ORDER:{} --- QUERY:{} --- calcCompleteQty:{} --- productResult:{} --- UPDATE:{}", - reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), - StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), workOrder.getWorkOrderNo(), JSONObject.toJSONString(workOrder), calcCompleteQty, productResult, JSONObject.toJSONString(propertyMap)); + //产出条码 根据生产工单分组 + Map> proMap = productionPsOutContextList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesProductionPsOutContext::getWorkOrderNo)); + //遍历产出物料 + for (Map.Entry> entry : proMap.entrySet()) { + if (null == entry) continue; + //生产数量 + Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO); + for (MesProductionPsOutContext productionPsOutContext : entry.getValue()) { + if (null == productionPsOutContext) continue; + //产出零件需要计算工单完成数量 + if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE)); + } + if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) continue; + //处理工位维度的工单完成数上下文[保存] + productionCustomContextStepService.dispatchWorkOrderCompleteQtyCellContext(reqBean, isCellNoCalcQty, productionPsOutContextList.get(0).getWorkOrderNo(), calcCompleteQty); } + } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepServiceBak.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepServiceBak.java new file mode 100644 index 0000000..36be4f8 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveNosortStepServiceBak.java @@ -0,0 +1,193 @@ +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.MesProductionPartContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; +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.StringUtil; +import cn.estsh.i3plus.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; +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.MesWorkOrderRepository; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +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 javax.persistence.EntityManager; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description : 保存加工单信息工步 【非排序】 + * @Reference : + * @Author : wangjie + * @CreateDate : 2024/6/11 18:50 + * @Modify: + **/ +@Slf4j +@Service("mesWorkOrderSaveNosortStepServiceBak") +public class MesWorkOrderSaveNosortStepServiceBak extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Autowired + private IMesWorkOrderExtService workOrderExtService; + + @Autowired + private MesWorkOrderRepository workOrderRepository; + + @Autowired + private EntityManager entityManager; + + @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); + + //获取上下文产出零件数据信息集合 + List productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean); + + //没有产出零件或者没有工单 + if (CollectionUtils.isEmpty(productionPartContextList) || StringUtils.isEmpty( + productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).findFirst().get().getWorkOrderNo())) return stepResult; + + //获取上下文产出零件数据信息集合 + List productionPsOutContextList = productionDispatchContextStepService.getProductionPsOutContext(reqBean); + + //保存生产工单数据 + doHandleWorkOrderData(reqBean, resultBean, productionPartContextList, productionPsOutContextList); + + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "保存加工单信息成功!"); + + } + + //保存生产工单数据 + private void doHandleWorkOrderData(StationRequestBean reqBean, StationResultBean resultBean, List productionPartContextList, List productionPsOutContextList) { + + //产出零件信息根据生产工单分组 + Map> ppMap = productionPartContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo)); + + //产出条码 根据生产工单分组 + Map> proMap = productionPsOutContextList.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(MesProductionPsOutContext::getWorkOrderNo)); + + String productResult = productionDispatchContextStepService.getProductResultContext(reqBean); + + //遍历产出零件信息 + for(Map.Entry> entry : ppMap.entrySet()) { + + if (null == entry) continue; + //获取对应的加工规则 + List produceSnContextList = proMap.get(entry.getKey()); + //生产数量 + Integer calcCompleteQty = 0; + //遍历产出物料 + for (MesProductionPsOutContext productionPsOutContext : produceSnContextList) { + if (null == productionPsOutContext) continue; + //产出零件是否是 + if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty += 1; + } + + if (calcCompleteQty.compareTo(MesPcnExtConstWords.ZERO) == 0) continue; + + MesWorkOrder workOrder = workOrderExtService.getWorkOrder(reqBean.getOrganizeCode(), entry.getValue().get(0).getId()); + + if (null == workOrder) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息不存在!", entry.getKey())); + + //工单状态分 排序工单 和非排序工单; 现在必须是非排序工单 + if (!MesExtEnumUtil.ORDER_STATUS.checkNosortAllowStatus(workOrder.getWorkOrderStatus())) + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息工单状态[%s]!", entry.getKey(), MesExtEnumUtil.ORDER_STATUS.valueOfDescription(workOrder.getWorkOrderStatus()))); + //工单产线要和当前产线一致 + if (!workOrder.getWorkCenterCode().equals(reqBean.getWorkCenterCode())) + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("请检查工单信息,加工单[%s]信息所属生产线[%s]与当前生产线[%s]不一致!", entry.getKey(), workOrder.getWorkCenterCode(), reqBean.getWorkCenterCode())); + + Map propertyMap = new HashMap<>(); + + //修改完成数量 + propertyMap.put(MesPcnExtConstWords.COMPLETE_QTY, MathOperation.add(workOrder.getCompleteQty(), calcCompleteQty)); + + //修改未完成数量 + if (workOrder.getUnCompleteQty().compareTo(new Double(0)) > 0 && MathOperation.compareTo(MathOperation.sub(workOrder.getUnCompleteQty(), new Double(calcCompleteQty)), new Double(0)) >= 0) { + propertyMap.put(MesPcnExtConstWords.UN_COMPLETE_QTY, MathOperation.sub(workOrder.getUnCompleteQty(), new Double(calcCompleteQty))); + } + + /** + * 可疑品、报废数量、上下线时间; + * sql改成修改固定字段 + * 在上下文中获取busi中获取prodResult上下文 是数字 (标志着条码质量状态,与条码质量状态枚举一致) + * 上下文中 已经按照工单分组了,因为有一模多腔问题 + */ + + if (!StringUtils.isEmpty(productResult)) { + //可疑品 + if (Integer.valueOf(productResult).compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS.getValue()) == 0 && !CollectionUtils.isEmpty(productionPsOutContextList)){ + propertyMap.put(MesPcnExtConstWords.SUSPICIOUS_PART_QTY, MathOperation.add(workOrder.getSuspiciousPartQty(), new Double(productionPsOutContextList.size()))); + } + //报废数量 + if (Integer.valueOf(productResult).compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.SCRAP.getValue()) == 0 && !CollectionUtils.isEmpty(productionPsOutContextList)){ + propertyMap.put(MesPcnExtConstWords.SCRAP_PART_QTY, MathOperation.add(workOrder.getScrapPartQty(), new Double(productionPsOutContextList.size()))); + } + } + + if (MathOperation.compareTo(MathOperation.add(workOrder.getCompleteQty(), calcCompleteQty), workOrder.getQty()) >= 0 && workOrder.getWorkOrderStatus().compareTo(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()) != 0) { + propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()); + } else if (workOrder.getCompleteQty() >= 0 && workOrder.getWorkOrderStatus() == MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue()) { + propertyMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()); + } + + if (CollectionUtils.isEmpty(propertyMap)) continue; + + propertyMap.put(MesPcnExtConstWords.MODIFY_DATE_TIME, (new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date())); + propertyMap.put(MesPcnExtConstWords.MODIFY_USER, reqBean.getUserInfo()); + propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + propertyMap.put(MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME, MesPcnExtConstWords.EMPTY); + + String[] propertyName = new String[propertyMap.size()]; + Object[] propertyValue = new Object[propertyMap.size()]; + + Integer index = 0; + for (Map.Entry innerEntry : propertyMap.entrySet()) { + if (null == innerEntry) continue; + propertyName[index] = innerEntry.getKey(); + propertyValue[index] = innerEntry.getValue(); + index ++; + } + + workOrderRepository.updateByPropertiesNoSync(new String[]{MesPcnExtConstWords.ID, MesPcnExtConstWords.ORGANIZE_CODE}, new Object[]{workOrder.getId(), reqBean.getOrganizeCode()}, propertyName, propertyValue); + + log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- ORDER:{} --- QUERY:{} --- calcCompleteQty:{} --- productResult:{} --- UPDATE:{}", + reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), + StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), workOrder.getWorkOrderNo(), JSONObject.toJSONString(workOrder), calcCompleteQty, productResult, JSONObject.toJSONString(propertyMap)); + + } + } + +} + diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java index 3836714..6c49094 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java @@ -1,12 +1,11 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.context; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdShiftContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; +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.StationKvBeanUtil; +import cn.estsh.i3plus.platform.common.tool.MathOperation; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; @@ -327,4 +326,39 @@ public class MesProductionCustomContextStepService extends BaseStepService imple removeFsmBusiData(reqBean.getOrganizeCode(), getSortQueuePushLockContextKey(reqBean), queuePushId); } + //工单完成数KEY【isCellNoCalcQty=true代表工位维度的统计,最终不一定会实际累加到工单上】【isCellNoCalcQty=false代表生产线维度的统计】 + private String getWorkOrderCompleteQtyContextCellKey(StationRequestBean reqBean, Boolean isCellNoCalcQty, String workOrderNo) { + StringJoiner sj = new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()); + if (isCellNoCalcQty) sj.add(reqBean.getWorkCellCode()); + return sj.add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).add(workOrderNo).toString(); + } + + //处理工位维度的工单完成数上下文[查询], 有效期三天 + @Override + public MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyCellContext(StationRequestBean reqBean, Boolean isCellNoCalcQty, MesProductionPartContext productionPartContext) { + String key = getWorkOrderCompleteQtyContextCellKey(reqBean, isCellNoCalcQty, productionPartContext.getWorkOrderNo()); + String context = getFsmBusiData(reqBean.getOrganizeCode(), key); + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = !StringUtils.isEmpty(context) + ? JSONObject.parseObject(context, MesWorkOrderCompleteQtyContext.class) + : new MesWorkOrderCompleteQtyContext(productionPartContext.getWorkOrderNo(), productionPartContext.getQty(), productionPartContext.getCompleteQty()); + //假如缓存中的完成数小于当前传参工单的完成数,则覆盖 + Boolean isNeedSave = !StringUtils.isEmpty(context) && MathOperation.compareTo(productionPartContext.getCompleteQty(), workOrderCompleteQtyContext.getCompleteQty()) > 0; + if (isNeedSave) workOrderCompleteQtyContext.overrideCompleteQty(productionPartContext.getCompleteQty()); + //判断是否需要存储 + if (StringUtils.isEmpty(context) || isNeedSave) dispatchFsmBusiData(reqBean.getOrganizeCode(), key, JSONObject.toJSONString(workOrderCompleteQtyContext), MesPcnEnumUtil.EXPIRE_TIME.THREE_DAY.getValue()); + return workOrderCompleteQtyContext; + } + + //处理工位维度的工单完成数上下文[保存], 有效期三天 + //【isCellNoCalcQty=true代表工位维度的统计,最终不一定会实际累加到工单上】【isCellNoCalcQty=false代表生产线维度的统计】 + @Override + public void dispatchWorkOrderCompleteQtyCellContext(StationRequestBean reqBean, Boolean isCellNoCalcQty, String workOrderNo, Double calcCompleteQty) { + String key = getWorkOrderCompleteQtyContextCellKey(reqBean, isCellNoCalcQty, workOrderNo); + String context = getFsmBusiData(reqBean.getOrganizeCode(), key); + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = !StringUtils.isEmpty(context) ? JSONObject.parseObject(context, MesWorkOrderCompleteQtyContext.class) : null; + if (null == workOrderCompleteQtyContext) return; + workOrderCompleteQtyContext.overrideCompleteQty(MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty)); + dispatchFsmBusiData(reqBean.getOrganizeCode(), key, JSONObject.toJSONString(workOrderCompleteQtyContext), MesPcnEnumUtil.EXPIRE_TIME.THREE_DAY.getValue()); + } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java index 79c3b3a..4541dee 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java @@ -11,6 +11,7 @@ import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging; import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import lombok.extern.slf4j.Slf4j; @@ -63,6 +64,18 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp return getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PRODUCT_RESULT_CONTEXT); } + //获取上下文加工结果 + @Override + public Integer getProductResultQcContext(StationRequestBean reqBean) { + String productResult = getProductResultContext(reqBean); + if (StringUtils.isEmpty(productResult)) return MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue(); + try { + return Integer.valueOf(productResult); + } catch (NumberFormatException e) { + return MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue(); + } + } + //保存上下文加工结果 加工结果:成功/报废/可疑 【写入的值是变量类别代码对应的条码质量状态】【报废/可疑: 在保存逻辑条码时有特殊业务处理】 @Override public Boolean dispatchProductResultContext(StationRequestBean reqBean, String productResult) { diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java new file mode 100644 index 0000000..208b527 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java @@ -0,0 +1,215 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method; + +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.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.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.model.StationResultBean; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +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.stream.Collectors; + +/** + * @Description : 加工单验证工单完成数量通用工步方法 + * @Author : wangjie + **/ +@Slf4j +@Service("mesWorkOrderCheckCompleteQtyStepService") +public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单; + public List dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean, + StepResult stepResult, MesProductionProcessContext productionProcessContext, + List productionPartContextList, List productionPsInContextList) { + //是否存在产成零件信息 + if (!stepResult.isCompleted() || CollectionUtils.isEmpty(productionPartContextList)) return null; + + //根据产出零件或者腔数拿到需要的加工规则数量, 优先使用产出零件数量 + Integer needQty = !CollectionUtils.isEmpty(productionPartContextList) ? productionPartContextList.size() : productionProcessContext.getCurCellEquip().getCavity(); + //验证是否满足腔数 + if (!CollectionUtils.isEmpty(productionPsInContextList) && productionPsInContextList.size() < needQty) return null; + + //对MesProductionPartContext中的工单号经行分组,每个工单可能对应多条数据, 筛选掉foreignkey为空的数据 + Map> productionPartContextMap = productionPartContextList.stream().filter(o -> + (!StringUtils.isEmpty(o.getWorkOrderNo()) && !StringUtils.isEmpty(o.getForeignKey()))).collect(Collectors.groupingBy(MesProductionPartContext::getWorkOrderNo)); + + if (CollectionUtils.isEmpty(productionPartContextMap)) return null; + + //根据foreignkey分组进料零件条码 + Map productionPsInContextMap = CollectionUtils.isEmpty(productionPsInContextList) ? null : + productionPsInContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsInContext::getForeignKey, o -> o)); + + //生产线与工位信息 + MesWorkCenter workCenter = productionProcessContext.getWorkCenter(); + MesWorkCell workCell = productionProcessContext.getWorkCell(); + //工位是否不累计工单完成数 + Boolean isCellNoCalcQty = isCellNoCalcQty(workCell.getNoCalcOrderQty()); + + //遍历验证加工单完成数量 + List workOrderCompleteQtyContextList = null; + for (Map.Entry> entry : productionPartContextMap.entrySet()) { + if (null == entry) continue; + + //验证加工单完成数量 + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = dispatchWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, isCellNoCalcQty, entry.getValue(), productionPsInContextMap); + + //验证失败直接退出 + if (!stepResult.isCompleted()) break; + + if (null != workOrderCompleteQtyContext) { + if (CollectionUtils.isEmpty(workOrderCompleteQtyContextList)) workOrderCompleteQtyContextList = new ArrayList<>(); + workOrderCompleteQtyContextList.add(workOrderCompleteQtyContext); + } + + } + + //验证失败标记删除标志 + if (!stepResult.isCompleted()) { + productionPartContextList.forEach(o -> o.busiCheckToDelete()); + if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList.forEach(o -> o.busiCheckToDelete()); + if (!CollectionUtils.isEmpty(workOrderCompleteQtyContextList)) workOrderCompleteQtyContextList.clear(); + } + + return workOrderCompleteQtyContextList; + + } + + //验证加工单完成数量 + private MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQty(StationRequestBean reqBean, StationResultBean resultBean, + StepResult stepResult, MesWorkCenter workCenter, Boolean isCellNoCalcQty, + List productionPartContextList, Map productionPsInContextMap) { + Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO); + for (MesProductionPartContext productionPartContext : productionPartContextList) { + MesProductionPsInContext productionPsInContext = getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey()); + //验证进料零件与产出零件是否一致 + Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, null); + //验证是否计数 + Boolean isCalcCompleteQty = isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext); + if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE)); + } + //当前工单无须计算工单完成数 + if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return null; + + //处理工位维度的工单完成数上下文; + //flag查询=2;保存=1 + //【isCellNoCalcQty=true代表工位维度的统计,最终不会实际累加到工单上】【isCellNoCalcQty=false代表生产线维度的统计,才会实际累加到工单上】 + MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = productionCustomContextStepService.dispatchWorkOrderCompleteQtyCellContext(reqBean, isCellNoCalcQty, productionPartContextList.get(0)); + + //验证工单完成数 + checkWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, workOrderCompleteQtyContext, calcCompleteQty); + + if (!stepResult.isCompleted()) return null; + + return workOrderCompleteQtyContext; + + } + + //工位是否不累计工单完成数 + public Boolean isCellNoCalcQty(Integer noCalcOrderQty) { + return (!StringUtils.isEmpty(noCalcOrderQty) && noCalcOrderQty.compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0) ? true : false; + } + + //验证进料零件与产出零件是否一致 + public Boolean isSamePart(MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext, MesProdRuleContext prodRuleContext) { + if (null == productionPsInContext) return false; + if (StringUtils.isEmpty(productionPsInContext.getPartNo())) return false; + if (null != productionPartContext) { + if (!productionPsInContext.getPartNo().equals(productionPartContext.getPartNo())) return false; + else return true; + } else { + if (!productionPsInContext.getPartNo().equals(prodRuleContext.getOutPartNo())) return false; + else return true; + } + } + + //验证是否计数 + public Boolean isCalcCompleteQty(Boolean isSamePart, MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext) { + //未选工单场景 + if (null == productionPartContext || StringUtils.isEmpty(productionPartContext.getWorkOrderNo())) return false; + //进出不一致 + if (!isSamePart) return true; + //进出一致的情况下: 【打印件已经是产成的情况下也需要计数】 + if (!StringUtils.isEmpty(productionPsInContext.getId()) && StringUtils.isEmpty(productionPsInContext.getProcessCode()) && + !StringUtils.isEmpty(productionPsInContext.getPrintStatus()) && productionPsInContext.getPrintStatus().compareTo(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue()) == 0) { + return true; + } + //进出一致 + return false; + } + + //根据数据关联键获取进料零件信息 + private MesProductionPsInContext getProductionPsInContext(Map productionPsInContextMap, Integer foreignKey) { + if (CollectionUtils.isEmpty(productionPsInContextMap) || StringUtils.isEmpty(foreignKey)) return null; + return productionPsInContextMap.get(foreignKey); + } + + //验证工单完成数 + private void checkWorkOrderCompleteQty(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, + MesWorkCenter workCenter, MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext, Double calcCompleteQty) { + + //当前工序的预计达到的完成数 + Double complateQty = MathOperation.add(workOrderCompleteQtyContext.getCompleteQty(), calcCompleteQty); + // 如果预完成数量 小于等于工单数量,则直接过 + if (MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), complateQty) >= 0) return; + //判断不支持超工单生产 + if (StringUtils.isEmpty(workCenter.getIsCheckOrderQty()) || workCenter.getIsCheckOrderQty().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0) { + //stepResult.obj(false)目的是在工步最后可以判断是否需要清除进料 + stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s]!", + workOrderCompleteQtyContext.getWorkOrderNo(), workOrderCompleteQtyContext.getQty().intValue(), workOrderCompleteQtyContext.getCompleteQty().intValue(), + MathOperation.compareTo(workOrderCompleteQtyContext.getQty(), workOrderCompleteQtyContext.getCompleteQty()) == 0 ? "当前已完成!" : "当前不支持超工单!")); + return; + } + //支持超工单生产情况下判断超出比例 + Double rate = MathOperation.div((MathOperation.sub(complateQty, workOrderCompleteQtyContext.getQty())), workOrderCompleteQtyContext.getQty()); + if (MathOperation.compareTo(rate, MathOperation.div(workCenter.getOrderRate(), new Double(MesPcnExtConstWords.ONE_HUNDRED))) > 0) { + stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.obj(false), + String.format("请检查工单数量,工单[%s]计划数量[%s]已完成数量[%s],当前超出超工单比例[%s]!", + workOrderCompleteQtyContext.getWorkOrderNo(), workOrderCompleteQtyContext.getQty().intValue(), workOrderCompleteQtyContext.getCompleteQty().intValue(), workCenter.getOrderRate())); + return; + } + } + + //清除本次扫描/读取信息 有进料【只】需要清除进料,否则存在产出零件需要清除产出零件 【只需要清除被标记的数据】 + public Boolean doBusiCheckToDelete(StationRequestBean reqBean, StepResult stepResult, List productionPartContextList, List 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; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionProcessContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionProcessContext.java index 32fa4eb..99e8d91 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionProcessContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionProcessContext.java @@ -1,6 +1,7 @@ package cn.estsh.i3plus.ext.mes.pcn.pojo.context; 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.MesEquipmentVariable; import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariableCfg; import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; @@ -171,6 +172,9 @@ public class MesProductionProcessContext implements Serializable { //上下文赋值生产线对象 public MesProductionProcessContext workCenterJson(MesWorkCenter workCenter) { + if (StringUtils.isEmpty(workCenter.getIsCheckOrderQty())) workCenter.setIsCheckOrderQty(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCenter.getIsIgnoreQc())) workCenter.setIsCheckOrderQty(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCenter.getIsPushQueue())) workCenter.setIsPushQueue(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); this.workCenterJson = null != workCenter ? JSONObject.toJSONString(workCenter) : null; return this.isNeedCache(); } @@ -184,6 +188,12 @@ public class MesProductionProcessContext implements Serializable { //上下文赋值工位对象 public MesProductionProcessContext workCellJson(MesWorkCell workCell) { + if (StringUtils.isEmpty(workCell.getIsCheckSeq())) workCell.setIsCheckSeq(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCell.getIsCheckCraft())) workCell.setIsCheckCraft(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCell.getIsSeqScan())) workCell.setIsCheckSeq(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCell.getIsResetScan())) workCell.setIsResetScan(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCell.getNoCalcOrderQty())) workCell.setNoCalcOrderQty(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + if (StringUtils.isEmpty(workCell.getIsEndWorkCell())) workCell.setIsEndWorkCell(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); this.workCellJson = null != workCell ? JSONObject.toJSONString(workCell) : null; return this.isNeedCache(); } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java index fde017f..1ce12f0 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java @@ -49,6 +49,9 @@ public class MesProductionPsInContext implements Serializable { @ApiParam("零件条码状态【用于发送设备加工参数】") private Integer snStatus; + @ApiParam("打印状态") + private Integer printStatus; + @ApiParam("零件号") private String partNo; diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsOutContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsOutContext.java index 3abbfe3..9731f5d 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsOutContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsOutContext.java @@ -1,5 +1,6 @@ package cn.estsh.i3plus.ext.mes.pcn.pojo.context; +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.MesProduceSn; import io.swagger.annotations.ApiParam; @@ -22,6 +23,12 @@ public class MesProductionPsOutContext extends MesProduceSn implements Serializa @ApiParam(name = "是否计算工单完成数量") private Integer isCalcCompleteQty = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(); + @ApiParam(name = "是否进出一致") + private Integer isSamePart = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(); + + @ApiParam(name = "是否不累计工单完成数") + private Integer noCalcOrderQty = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(); + public MesProductionPsOutContext() {} public MesProductionPsOutContext copy(MesProduceSn produceSn, Integer foreignKey) { @@ -41,8 +48,10 @@ public class MesProductionPsOutContext extends MesProduceSn implements Serializa return this; } - public MesProductionPsOutContext isCalcCompleteQty(Boolean isCalcCompleteQty) { + public MesProductionPsOutContext isCalcCompleteQty(Boolean isCalcCompleteQty, Boolean isSamePart, Integer noCalcOrderQty) { if (isCalcCompleteQty) this.isCalcCompleteQty = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(); + if (isSamePart) this.isSamePart = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(); + this.noCalcOrderQty = noCalcOrderQty; return this; } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java new file mode 100644 index 0000000..c825cfe --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesWorkOrderCompleteQtyContext.java @@ -0,0 +1,38 @@ +package cn.estsh.i3plus.ext.mes.pcn.pojo.context; + +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import io.swagger.annotations.ApiParam; +import lombok.Data; +import org.springframework.util.StringUtils; + +import java.io.Serializable; + +/** + * 生产过程上下文对象-加工单完成数 + */ +@Data +public class MesWorkOrderCompleteQtyContext implements Serializable { + + private static final long serialVersionUID = -1602007855074296100L; + + @ApiParam("生产工单号") + private String workOrderNo; + + @ApiParam("工单数量") + private Double qty; + + @ApiParam("完成数量") + private Double completeQty; + + public MesWorkOrderCompleteQtyContext(String workOrderNo, Double qty, Double completeQty) { + this.workOrderNo = workOrderNo; + this.qty = qty; + this.completeQty = StringUtils.isEmpty(completeQty) ? new Double(MesPcnExtConstWords.ZERO) : completeQty; + } + + public MesWorkOrderCompleteQtyContext overrideCompleteQty(Double completeQty) { + this.completeQty = completeQty; + return this; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java index f13772b..a3aa13b 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java @@ -664,6 +664,8 @@ public class MesPcnExtConstWords { public static final String QUEUE_PUSH_CONTEXT = "QUEUE_PUSH_CONTEXT"; // 工位零件打印机上下文 public static final String CELL_PART_PRINTER_CONTEXT = "CELL_PART_PRINTER_CONTEXT"; + // 工单完成数上下文 + public static final String WORK_ORDER_COMPLETE_CONTEXT = "WORK_ORDER_COMPLETE_CONTEXT"; // 上下文: 展示组件数据 public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";