From c359d385abc239d2435c12e95fdd991d3f0db0c4 Mon Sep 17 00:00:00 2001 From: administrator Date: Fri, 7 Jun 2024 11:56:42 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=89=93=E5=8D=B0=E4=B8=BB=E6=9D=A1?= =?UTF-8?q?=E7=A0=81=E4=B8=BB=E5=B7=A5=E6=AD=A5=E5=AE=8C=E6=88=90,?= =?UTF-8?q?=E7=BC=BA=E5=B0=91=E5=B0=81=E8=A3=85=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E7=AD=96=E7=95=A5,=E5=BE=85=E6=A0=87=E7=AD=BE=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=A1=AE=E8=AE=A4=E5=90=8E=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../print/IPrintTemplateStrategyService.java | 22 +++++ .../print/strategy/GzPrintSnStrategy.java | 29 ++++++ .../step/MesProductSnPrintStepService.java | 108 +++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/IPrintTemplateStrategyService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/GzPrintSnStrategy.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/IPrintTemplateStrategyService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/IPrintTemplateStrategyService.java new file mode 100644 index 0000000..6eaf3de --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/IPrintTemplateStrategyService.java @@ -0,0 +1,22 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.print; + +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; + +import java.util.List; + +/** + * @Description : 根据不同的条码,封装不同的数据来源 content 是打印模板,dataList + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/6 16:39 + * @Modify: + **/ +public interface IPrintTemplateStrategyService { + /** + * dataList + * 需要打印的数据,封装数据 + * @param sn + * @return + */ + List execute(MesProductionPsOutContext sn , String organizeCode); +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/GzPrintSnStrategy.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/GzPrintSnStrategy.java new file mode 100644 index 0000000..60f2920 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/GzPrintSnStrategy.java @@ -0,0 +1,29 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.print.strategy; + +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.print.IPrintTemplateStrategyService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; +import cn.estsh.i3plus.pojo.mes.repository.MesLabelTemplateRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @Description : 广州打印主条码使用 + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/6 17:03 + * @Modify: + **/ +@Service +@Slf4j +public class GzPrintSnStrategy implements IPrintTemplateStrategyService { + @Autowired + private MesLabelTemplateRepository labelTemplateRao; + @Override + public List execute(MesProductionPsOutContext sn, String organizeCode) { + //1.根据 templateCode + return null; + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java new file mode 100644 index 0000000..d701629 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java @@ -0,0 +1,108 @@ +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.print.IPrintTemplateStrategyService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.bean.MesLabelTemplate; +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.MesLabelTemplateRepository; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Description : 打印主条码 + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/6 13:39 + * @Modify: + **/ +@Service +public class MesProductSnPrintStepService extends BaseStepService { + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService; + + @Autowired + private MesLabelTemplateRepository labelTemplateRao; + + @Override + public StepResult execute(StationRequestBean reqBean) { + String organizeCode = reqBean.getOrganizeCode(); + StationResultBean resultBean = new StationResultBean(); + StepResult stepResult = StepResult.getSuccessComplete(); + //需要打印的数据 + Map> resultData = new HashMap<>(); + //用于保存客户模板代码 和 模板信息关系 + Map labelTemplateMap = new HashMap<>(); + //返回打印标识 给前端 + //1. 获取上下文中生成的主条码 + List productionPsOutContextList = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); + //2. 获取条码需要模板、模板代码、打印机 --- 循环遍历条码 封装数据 + for (MesProductionPsOutContext sn : productionPsOutContextList) { + String custLabelTemplate = sn.getCustLabelTemplate(); + MesLabelTemplate labelTemplate; + // 查模板代码 + if (!labelTemplateMap.containsKey(custLabelTemplate)) { + labelTemplate = getLabelTemplate(custLabelTemplate, organizeCode); + //模板信息丢失抛出异常 + if (labelTemplate == null) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("零件号[%s]的模板代码[%s]的模板信息丢失,请配置!", sn.getPartNo(),custLabelTemplate)); + } + labelTemplateMap.put(custLabelTemplate, labelTemplate); + }else { + labelTemplate = labelTemplateMap.get(custLabelTemplate); + } + //根据反射获取策略类--封装打印数据 + String methodCode = labelTemplate.getMethodCode(); + //模板信息丢失抛出异常 + if (methodCode == null) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("零件号[%s]的模板代码[%s]的反射类丢失,请配置!", sn.getPartNo(),custLabelTemplate)); + } + IPrintTemplateStrategyService strategyService = (IPrintTemplateStrategyService) SpringContextsUtil.getBean(methodCode); + List snData = strategyService.execute(sn, organizeCode); + if (resultData.containsKey(labelTemplate.getTemplateCode())){ + List printData = resultData.get(labelTemplate.getTemplateCode()); + printData.addAll(snData); + }else { + resultData.put(labelTemplate.getTemplateCode(),snData); + } + } + //前端接收到busiTyep是customComponent,并且 dataType是file类型的消息,就需要打印后续消息里的数据,一个模板对应多个打印数据 + resultBean.setBusiType(MesPcnEnumUtil.STATION_BUSI_TYPE.CUSTOM_COMPONENT.getValue()); + resultBean.setDataType(MesPcnEnumUtil.STATION_DATA_TYPE.FILE.getValue()); + resultBean.setResultObj(resultData); + //3. 发送数据给到前端 + this.sendMessage(reqBean,resultBean); + + return stepResult; + } + + /** + * 根据templateCode 获取模板信息 + * @param templateCode + * @param organizeCode + * @return + */ + private MesLabelTemplate getLabelTemplate(String templateCode,String organizeCode) { + DdlPackBean templatePackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(templateCode,"templateCode",templatePackBean); + List mesLabelTemplateList = labelTemplateRao.findByHqlWhere(templatePackBean); + return mesLabelTemplateList.isEmpty() ? null : mesLabelTemplateList.get(0); + } +} From ae0054cb92d3aecde1a85bd61b8b26d2aef4ea6a Mon Sep 17 00:00:00 2001 From: administrator Date: Tue, 11 Jun 2024 16:22:14 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=8A=A5=E5=B7=A5=E5=B7=A5=E6=AD=A5?= =?UTF-8?q?=E5=8F=8A=E9=9D=9E=E6=8E=92=E5=BA=8F=E6=8A=A5=E5=B7=A5job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ext/mes/pcn/api/busi/IMesWorkOrderService.java | 9 +- .../apiservice/schedulejob/BaseMesScheduleJob.java | 120 ++++++ .../apiservice/schedulejob/MesReportNoSortJob.java | 51 +++ .../serviceimpl/busi/MesWorkOrderService.java | 28 +- .../step/MesReportGenerateStepService.java | 70 +++- .../step/MesReportNoSortStepService.java | 240 ++++++++++++ .../serviceimpl/step/MesReportSortStepService.java | 411 +++++++++++++++++++++ .../mes/pcn/pojo/context/MesProdRuleContext.java | 4 +- 8 files changed, 914 insertions(+), 19 deletions(-) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/BaseMesScheduleJob.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesReportNoSortJob.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesWorkOrderService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesWorkOrderService.java index f10fa94..ffea1b4 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesWorkOrderService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesWorkOrderService.java @@ -28,5 +28,12 @@ public interface IMesWorkOrderService { public ListPager queryMesWorkOrderListByPager(MesWorkOrder workOrder, Pager pager); - void doProductReport(List mesProduceSnList, String organizeCode, String userName); + void doProductReport(List mesProduceSns, String organizeCode, String userName); + + /** + * 获取未报工 + * @param organizeCode + * @return + */ + List getUnReportMesProduceSn(String organizeCode); } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/BaseMesScheduleJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/BaseMesScheduleJob.java new file mode 100644 index 0000000..46ecafa --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/BaseMesScheduleJob.java @@ -0,0 +1,120 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob; + +import cn.estsh.i3plus.platform.common.util.CommonConstWords; +import cn.estsh.i3plus.platform.common.util.MesConstWords; +import cn.estsh.impp.framework.base.schedule.BaseImppScheduleJob; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import cn.estsh.impp.framework.boot.util.ImppRedis; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.quartz.JobExecutionContext; +import org.redisson.api.RLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.DigestUtils; + +import javax.annotation.Resource; + +/** + * @author ns + * @create 2021/11/15 0015 下午 17:04 + * 通过父类的方法来进行并发控制,解决xxljob不支持分布式并发的问题 + * 使用xxljob作为定时任务框架,一定要基础BaseMesScheduleJob,不然会出现并发问题 + */ +public abstract class BaseMesScheduleJob extends BaseImppScheduleJob { + + public static final Logger LOGGER = LoggerFactory.getLogger(BaseMesScheduleJob.class); + + @Resource(name = CommonConstWords.IMPP_REDIS_MES) + @Getter + @Setter + private ImppRedis redisMes; + + @Resource(name = CommonConstWords.IMPP_REDIS_RES) + private ImppRedis redisRes; + + private Class childClass; + private String childDesc; + + @Getter + @Setter + private String wmsJobParams; + + /** + * Redis 锁的存活时间,默认30分钟 + */ + @Getter + @Setter + private Integer redisLockTime = 1800; + + // 当一个 job class 需要同时运行多个 job 实例时把此属性设置为 true,默认为 false + @Getter + @Setter + private boolean isMultiInstance = true; + + public BaseMesScheduleJob(Class cls, String jobDesc) { + super(cls, jobDesc); + this.childClass = cls; + this.childDesc = jobDesc; + } + + @Override + public void executeImppJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + // 保存 job 参数 + this.wmsJobParams = super.getJobParam(); + String redisKey = MesConstWords.MES_JOB_REDIS_PREFIX + this.childClass.getName(); + + if (isMultiInstance) { + // 把 Job 参数也作为 key 的一部分,确保相同的 job class 配置多个 job instance 时可以各自运行 + redisKey = redisKey + ":" + getMd5String(this.getJobParam()); + } + + LOGGER.info("JOB REDIS KEY: " + redisKey); + + //添加redis锁(半小时失效) +// if (redisMes.getObject(redisKey) != null) { +// LOGGER.error("JOB REDIS KEY: " + redisKey+ " - "+this.childDesc + " 数据正在处理中,不能并发执行!"); +// // 直接返回 +// return; +// } + RLock rLock = (RLock) redisRes.getLock(redisKey); + try { + LOGGER.info("JOB REDIS KEY PUT: " + redisKey); + //使用tryLock拿不到锁直接返回 + //rlock的leaseTime为-1,会每隔WatchdogTimeout秒去续约 + if (rLock.tryLock()){ + this.executeMesJob(context, applicationProperties); + }else{ + LOGGER.error("JOB REDIS KEY: " + redisKey+ " - "+this.childDesc + " 数据正在处理中,不能并发执行!"); + } + // 直接返回 + return; +// redisMes.putObject(redisKey, redisKey, getRedisLockTime()); + } catch (Exception e) { + LOGGER.error(ExceptionUtils.getStackTrace(e)); + } finally { + LOGGER.info("JOB REDIS KEY DELETE: " + redisKey); + //解除REDIS执行锁 +// redisMes.deleteKey(redisKey); + if (rLock.isHeldByCurrentThread()) { + rLock.unlock(); + } + } + } + + public abstract void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties); + + /** + * 获取字符串的 MD5 值 + * @param context 输入字符串 + * @return MD5 值 + */ + private String getMd5String(String context) { + if (context == null || context.isEmpty()) { + return ""; + } + + return DigestUtils.md5DigestAsHex(context.getBytes()); + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesReportNoSortJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesReportNoSortJob.java new file mode 100644 index 0000000..8ced524 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesReportNoSortJob.java @@ -0,0 +1,51 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob; + + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesWorkOrderService; +import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +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 java.util.List; + +/** + * @author castle,暂时没有客供品移库 + * @version 1.0 + * @date 2021/2/2 16:44 + **/ +@Slf4j +@DisallowConcurrentExecution +@Component +@ApiOperation("非排序报工job") +public class MesReportNoSortJob extends BaseMesScheduleJob { + + @Autowired + private IMesWorkOrderService workOrderService; + + public MesReportNoSortJob() { + super(MesReportNoSortJob.class, "非排序报工JOB"); + } + @Override + public void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + String jobParam = this.getJobParam(); + JSONObject jsonObject= JSONUtil.parseObj(jobParam); + String organizeCode = jsonObject.getStr("organizeCode"); + String userName = jsonObject.getStr("userName"); + if (null == organizeCode){ + log.error("请添加需要报工的工厂代码!"); + return; + } + if (null == userName){ + userName = "JOB"; + } + List unReportMesProduceSn = workOrderService.getUnReportMesProduceSn(organizeCode); + workOrderService.doProductReport(unReportMesProduceSn,organizeCode,userName); + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesWorkOrderService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesWorkOrderService.java index 684e36a..3b00a21 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesWorkOrderService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesWorkOrderService.java @@ -51,6 +51,12 @@ public class MesWorkOrderService implements IMesWorkOrderService { @Autowired private MesProductOffLineRepository mesProductOffLineRDao; + @Autowired + private MesProductionRecordRepository productionRecordRao; + + @Autowired + private MesProduceSnRepository mesProduceSnRao; + @Override public MesWorkOrder queryMesWorkOrder(MesWorkOrder workOrder) { @@ -109,7 +115,7 @@ public class MesWorkOrderService implements IMesWorkOrderService { //新增初始化 todo Map> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo)); Map mesPartMap = new HashMap<>(); - MesPart mesPart = null; + MesPart mesPart; //查询工单状态 Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()}; for (Map.Entry> mesProduceSn : mesWorkOrderMap.entrySet()) { @@ -212,6 +218,26 @@ public class MesWorkOrderService implements IMesWorkOrderService { } } + @Override + public List getUnReportMesProduceSn(String organizeCode) { + List mesProduceSnList = new ArrayList<>(); + //1.获取生产加工记录production_record表中,report_status为待汇报状态的工单 + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getNumEqualPack( MesExtEnumUtil.REPORT_STATUS.REPORT_STATUS_10.getValue(),"reportStatus",ddlPackBean); + + List mesProductionRecordList = productionRecordRao.findByHqlTopWhere(ddlPackBean, 1); + if (mesProductionRecordList.isEmpty()){ + return mesProduceSnList; + } + //2.根据工单查询工单下的mesProduceSn + MesProductionRecord mesProductionRecord = mesProductionRecordList.get(0); + //工单号 + String workOrderNo = mesProductionRecord.getWorkOrderNo(); + DdlPackBean snPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(workOrderNo,"workOrderNo",snPackBean); + return mesProduceSnRao.findByHqlWhere(snPackBean); + } + private void saveMesProductPlan(MesWorkOrder bean, boolean isInsert, boolean isReport) { if (StringUtil.isEmpty(bean.getPlanOrderNo())) { DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode()); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java index f78faed..748a3fb 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportGenerateStepService.java @@ -5,48 +5,86 @@ import akka.actor.ActorSystem; 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.IMesWorkOrderService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; +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.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.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker; -import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.base.util.StringUtil; +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.*; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.exception.ImppBusiException; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * @Description : 生产汇报工步 - * @Author : zxw + * @Author : zxw --castle update + * @Date: 2024/06/07 **/ @Slf4j @Service public class MesReportGenerateStepService extends BaseStepService { + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; @Autowired - private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService; + private MesReportNoSortStepService reportNoSortStepService; @Autowired - private IMesWorkOrderService mesWorkOrderService; + private MesReportSortStepService reportSortStepService; + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + StepResult stepResult = StepResult.getSuccessComplete(); +// todo 根据产线判断是排序还是非排序,然后调用排序或者非排序的报工工步 +// //产品加工规则 +// List prodRuleDataContext = mesProductionDispatchContextStepService.getProdRuleDataContext(reqBean); +// //获取产成零件信息 +// List productionPartContext = mesProductionDispatchContextStepService.getProductionPartContext(reqBean); + //1. 校验当前有没有工单---只有有工单才能报工 + //如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号 +// List mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); + //获取上下文信息 + MesProductionProcessContext productionProcessContext = productionProcessContextStepService.getCurCellEquipment(reqBean); - public static final String ORDER_NO_JIS_SORT = "ORDER_NO_JIS_SORT"; + //配置错误 抛出异常 + if (!productionProcessContext.getSuccess()) + execExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); - private static final Map refMap = new ConcurrentHashMap<>(200); + //存储生产过程上下文对象 + productionProcessContextStepService.saveProductionProcessContext(reqBean, productionProcessContext); - @Override - public StepResult execute(StationRequestBean reqBean) { - StationResultBean resultBean = new StationResultBean(); + //从上下文中取出生产线对象 + MesWorkCenter workCenter = productionProcessContext.getWorkCenter(); - StepResult stepResult = StepResult.getSuccessComplete(); - List mesProduceSns = mesProductionDispatchContextStepService.getOutProduceSnDataContext(reqBean); + //排序线报工 + if (MesExtEnumUtil.WORK_CENTER_TYPE.SORT.getValue() == workCenter.getCenterType()) { + return reportSortStepService.execute(reqBean); + } else { + //非排序线报工 + return reportNoSortStepService.execute(reqBean); + } - mesWorkOrderService.doProductReport(mesProduceSns, reqBean.getOrganizeCode(), reqBean.getUserInfo()); - return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "保存加工结果成功"); - } + } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java new file mode 100644 index 0000000..5c15f43 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportNoSortStepService.java @@ -0,0 +1,240 @@ +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.pojo.context.MesProductionPsOutContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.platform.common.convert.ConvertBean; +import cn.estsh.i3plus.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.base.util.StringUtil; +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.*; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description : 生产汇报工步 非排序报工 + * + * @Author : zxw --castle update + * @Date: 2024/06/07 + **/ +@Slf4j +@Service +public class MesReportNoSortStepService extends BaseStepService { + + @Autowired + private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService; + + @Autowired + private MesPartRepository mesPartRDao; + + @Autowired + private MesWorkOrderRepository workOrderRepository; + + @Autowired + private MesWorkCenterRepository mesWorkCenterRDao; + + @Autowired + private MesProductVersionRepository mesProductVersionRDao; + + @Autowired + private MesBomRepository mesBomRDao; + + @Autowired + private MesProductOffLineRepository mesProductOffLineRDao; + + @Autowired + private MesProductPlanRepository mesProductPlanRDao; + + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + StepResult stepResult = StepResult.getSuccessComplete(); + // todo 先不使用缓存中的数据 + //1. 校验当前有没有工单---只有有工单才能报工 + //如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号 + List mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); + this.doProductReport(mesProduceSns, reqBean.getOrganizeCode(), reqBean.getUserInfo(),reqBean,resultBean); + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "报工成功"); + } + + public void doProductReport(List mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) { + //新增初始化 + Map> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo)); + Map mesPartMap = new HashMap<>(); + MesPart mesPart; + //查询工单状态 + Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()}; + for (Map.Entry> mesProduceSn : mesWorkOrderMap.entrySet()) { + List mesWorkOrderList = mesProduceSn.getValue(); + //获取物料信息 + if(mesPartMap.containsKey(mesProduceSn.getKey())){ + mesPart = mesPartMap.get(mesProduceSn.getKey()); + }else{ + //查询物料信息 + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesProduceSn.getKey(), "partNo", ddlPackBean); + mesPart = mesPartRDao.getByProperty(ddlPackBean); + if(Objects.isNull(mesPart)){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】信息不存在", mesProduceSn.getKey())); + } + mesPartMap.put(mesProduceSn.getKey(),mesPart); + } + //根据物料获取已发布的工单 + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getInPackArray(orderStatus, "workOrderStatus", ddlPackBean); + MesWorkOrder oldMesWorkOrder = workOrderRepository.getByProperty(ddlPackBean); + if(Objects.isNull(oldMesWorkOrder)){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】状态未已发布的工单信息不存在", mesPart.getPartNo())); + } + //查询工作中心 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getWorkCenterCode(), "workCenterCode", ddlPackBean); + MesWorkCenter mesWorkCenter = mesWorkCenterRDao.getByProperty(ddlPackBean); + if (Objects.isNull(mesWorkCenter)) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】不存在", oldMesWorkOrder.getWorkCenterCode())); + } + //获取生产版本 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(mesWorkCenter.getErpWorkCenter(), "workCenterCode", ddlPackBean); + DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getProductVersion(), "productVersion", ddlPackBean); + MesProductVersion mesProductVersion = mesProductVersionRDao.getByProperty(ddlPackBean); + if (null == mesProductVersion) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本信息不存在", mesPart.getPartNo())); + } + //物料+生产版本获取bom信息 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(mesProductVersion.getAlternativePartList(), "bomVersion", ddlPackBean); + List mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean); + if (CollectionUtils.isEmpty(mesBoms)) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本【%s】对应bom信息不存在", mesPart.getPartNo(), mesProductVersion.getProductVersion())); + } + oldMesWorkOrder.setNum(mesWorkOrderList.size()); + oldMesWorkOrder.setReportedQty(MathOperation.add(oldMesWorkOrder.getNum(), oldMesWorkOrder.getReportedQty())); + //更新SAP计划完成数量 + saveMesProductPlan(oldMesWorkOrder, false, true, reqBean, resultBean); + + //更新工单状态 + double unCompleteQty = MathOperation.sub(oldMesWorkOrder.getQty(), oldMesWorkOrder.getReportedQty()); + oldMesWorkOrder.setUnCompleteQty(unCompleteQty > 0 ? unCompleteQty : 0); + if (oldMesWorkOrder.getReportedQty() > oldMesWorkOrder.getQty()) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("工单报工数量【%s】大于工单数量【%s】,不允许报工", oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())); + } else if (Objects.equals(oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())) { + oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()); + } else { + oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()); + } + ConvertBean.serviceModelUpdate(oldMesWorkOrder,userName); + workOrderRepository.update(oldMesWorkOrder); + //保存数据 + List mesProductOffLineList = new ArrayList<>(); + MesProductOffLine newMesProductOffLine; + for (MesProduceSn produceSn : mesWorkOrderList) { + for (MesBom mesBom : mesBoms) { + newMesProductOffLine = new MesProductOffLine(); + newMesProductOffLine.setReportPartNo(oldMesWorkOrder.getPartNo()); + newMesProductOffLine.setReportPartNameRdd(oldMesWorkOrder.getPartName()); + newMesProductOffLine.setItemPartNo(mesBom.getItemPartNo()); + newMesProductOffLine.setItemPartName(mesBom.getItemPartName()); + newMesProductOffLine.setItemQty(mesBom.getItemQty()); + newMesProductOffLine.setAlort(mesProductVersion.getReceiveInventoryPoint()); + newMesProductOffLine.setStgeLoc(mesProductVersion.getShipInventoryPoint()); + newMesProductOffLine.setQty(1d); + newMesProductOffLine.setReportSn(produceSn.getProductSn()); + newMesProductOffLine.setBomVersion(oldMesWorkOrder.getProductVersion()); + newMesProductOffLine.setSerialNumber(produceSn.getProductSn()); + newMesProductOffLine.setUnit(mesBom.getUnit()); + newMesProductOffLine.setItemUnit(mesBom.getItemUnit()); + newMesProductOffLine.setWorkOrderNo(oldMesWorkOrder.getWorkOrderNo()); + newMesProductOffLine.setWorkCenterCode(oldMesWorkOrder.getWorkCenterCode()); + newMesProductOffLine.setWorkCellCode(oldMesWorkOrder.getWorkCellCode()); + newMesProductOffLine.setReportType(oldMesWorkOrder.getReportType()); + newMesProductOffLine.setSapWorkCenter(oldMesWorkOrder.getErpWorkCenter()); + newMesProductOffLine.setOrganizeCode(oldMesWorkOrder.getOrganizeCode()); + + ConvertBean.serviceModelInitialize(newMesProductOffLine, userName); + mesProductOffLineList.add(newMesProductOffLine); + } + } + mesProductOffLineRDao.saveAll(mesProductOffLineList); + } + } + + private void saveMesProductPlan(MesWorkOrder bean, boolean isInsert, boolean isReport,StationRequestBean reqBean, StationResultBean resultBean) { + if (StringUtil.isEmpty(bean.getPlanOrderNo())) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPlanStartTime(), "planStartDate", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPlanEndTime(), "planEndDate", ddlPackBean); + MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean); + if (null == mesProductPlan) { + MesProductPlan mesPlanOrder = new MesProductPlan(); + mesPlanOrder.setPlanOrderNo(""); + mesPlanOrder.setPlanQty(bean.getQty()); + mesPlanOrder.setPlanPartNo(bean.getPartNo()); + mesPlanOrder.setCompleteQty(0d); + mesPlanOrder.setUncompleteQty(bean.getQty()); + mesPlanOrder.setUnit(bean.getUnit()); + mesPlanOrder.setPlanStartDate(bean.getPlanStartTime()); + mesPlanOrder.setPlanEndDate(bean.getPlanEndTime()); + mesPlanOrder.setPartMappingWorkCenterCode(bean.getErpWorkCenter()); + mesPlanOrder.setPlanOrganizeCode(bean.getOrganizeCode()); + mesPlanOrder.setOrganizeCode(bean.getOrganizeCode()); + ConvertBean.serviceModelInitialize(mesPlanOrder, bean.getCreateUser()); + mesProductPlanRDao.insert(mesPlanOrder); + } else { + if (isInsert) { + mesProductPlan.setPlanQty(MathOperation.add(mesProductPlan.getPlanQty(), bean.getQty())); + } else { + //报工 + if (isReport) { + mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum())); + //报工调整 + } else { + mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum())); + } + } + mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty())); + ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser()); + mesProductPlanRDao.update(mesProductPlan); + } + } else { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(bean.getPlanOrderNo(), "planOrderNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean); + MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean); + if (null == mesProductPlan) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("SAP计划单号【%s】物料【%s】,不存在", bean.getPlanOrderNo(), bean.getPartNo())); + } + if (!isInsert) { + if (Objects.isNull(mesProductPlan.getCompleteQty())) { + mesProductPlan.setCompleteQty(0d); + } + //报工 + if (isReport) { + mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum())); + //报工调整 + } else { + mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum())); + } + mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty())); + ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser()); + mesProductPlanRDao.update(mesProductPlan); + } + } + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java new file mode 100644 index 0000000..568e2a8 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesReportSortStepService.java @@ -0,0 +1,411 @@ +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.pojo.context.MesProductionPsOutContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.platform.common.convert.ConvertBean; +import cn.estsh.i3plus.platform.common.tool.MathOperation; +import cn.estsh.i3plus.platform.common.tool.TimeTool; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.base.util.StringUtil; +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.*; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.auth.AuthUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description : 生产汇报工步 排序报工 + * + * @Author : zxw --castle update + * @Date: 2024/06/07 + **/ +@Slf4j +@Service +public class MesReportSortStepService extends BaseStepService { + + @Autowired + private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService; + + @Autowired + private MesPartRepository mesPartRDao; + + @Autowired + private MesWorkOrderRepository workOrderRepository; + + @Autowired + private MesWorkCenterRepository mesWorkCenterRDao; + + @Autowired + private MesProductVersionRepository mesProductVersionRDao; + + @Autowired + private MesBomRepository mesBomRDao; + + @Autowired + private MesProductOffLineRepository mesProductOffLineRDao; + + @Autowired + private MesProductPlanRepository mesProductPlanRDao; + + @Autowired + private MesProdRuleSortCfgRepository mesProdRuleSortCfgRDao; + + @Autowired + private IMesMoveRuleRepository moveRuleRao; + + @Autowired + private MesPartSapRepository mesPartSapRao; + + @Autowired + private MesPartRepository partRao; + + @Autowired + private MesMoveRepository mesMoveRDao; + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + StepResult stepResult = StepResult.getSuccessComplete(); + //如果产品加工规则中的foreignKey 和 产成零件信息 一一对应的,查询MesProductionPartContext的工单号 + List mesProduceSns = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean); + this.doProductReport(mesProduceSns, reqBean.getOrganizeCode(), reqBean.getUserInfo(),reqBean,resultBean); + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "报工成功"); + } + + public void doProductReport(List mesProduceSnList, String organizeCode, String userName, StationRequestBean reqBean, StationResultBean resultBean) { + //新增初始化 + Map> mesWorkOrderMap = mesProduceSnList.stream().collect(Collectors.groupingBy(MesProduceSn::getPartNo)); + Map mesPartMap = new HashMap<>(); + MesPart mesPart; + //查询工单状态 + Integer[] orderStatus =new Integer[]{MesExtEnumUtil.ORDER_STATUS.RELEASE.getValue(),MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()}; + for (Map.Entry> mesProduceSn : mesWorkOrderMap.entrySet()) { + List mesWorkOrderList = mesProduceSn.getValue(); + //获取物料信息 + if(mesPartMap.containsKey(mesProduceSn.getKey())){ + mesPart = mesPartMap.get(mesProduceSn.getKey()); + }else{ + //查询物料信息 + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesProduceSn.getKey(), "partNo", ddlPackBean); + mesPart = mesPartRDao.getByProperty(ddlPackBean); + if(Objects.isNull(mesPart)){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】信息不存在", mesProduceSn.getKey())); + } + mesPartMap.put(mesProduceSn.getKey(),mesPart); + } + //根据物料获取已发布的工单 + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getInPackArray(orderStatus, "workOrderStatus", ddlPackBean); + MesWorkOrder oldMesWorkOrder = workOrderRepository.getByProperty(ddlPackBean); + if(Objects.isNull(oldMesWorkOrder)){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】状态未已发布的工单信息不存在", mesPart.getPartNo())); + } + //查询工作中心 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getWorkCenterCode(), "workCenterCode", ddlPackBean); + MesWorkCenter mesWorkCenter = mesWorkCenterRDao.getByProperty(ddlPackBean); + if (Objects.isNull(mesWorkCenter)) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】不存在", oldMesWorkOrder.getWorkCenterCode())); + } + //获取生产版本 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(mesWorkCenter.getErpWorkCenter(), "workCenterCode", ddlPackBean); + DdlPreparedPack.getStringEqualPack(oldMesWorkOrder.getProductVersion(), "productVersion", ddlPackBean); + MesProductVersion mesProductVersion = mesProductVersionRDao.getByProperty(ddlPackBean); + if (null == mesProductVersion) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本信息不存在", mesPart.getPartNo())); + } + //物料+生产版本获取bom信息 + ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(mesProductVersion.getAlternativePartList(), "bomVersion", ddlPackBean); + List mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean); + if (CollectionUtils.isEmpty(mesBoms)) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("物料【%s】生产版本【%s】对应bom信息不存在", mesPart.getPartNo(), mesProductVersion.getProductVersion())); + } + oldMesWorkOrder.setNum(mesWorkOrderList.size()); + oldMesWorkOrder.setReportedQty(MathOperation.add(oldMesWorkOrder.getNum(), oldMesWorkOrder.getReportedQty())); + //更新SAP计划完成数量 + saveMesProductPlan(oldMesWorkOrder, false, true, reqBean, resultBean); + + //更新工单状态 + double unCompleteQty = MathOperation.sub(oldMesWorkOrder.getQty(), oldMesWorkOrder.getReportedQty()); + oldMesWorkOrder.setUnCompleteQty(unCompleteQty > 0 ? unCompleteQty : 0); + if (oldMesWorkOrder.getReportedQty() > oldMesWorkOrder.getQty()) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("工单报工数量【%s】大于工单数量【%s】,不允许报工", oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())); + } else if (Objects.equals(oldMesWorkOrder.getReportedQty(), oldMesWorkOrder.getQty())) { + oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.COMPLETE.getValue()); + } else { + oldMesWorkOrder.setWorkOrderStatus(MesExtEnumUtil.ORDER_STATUS.PROCESS.getValue()); + } + ConvertBean.serviceModelUpdate(oldMesWorkOrder,userName); + workOrderRepository.update(oldMesWorkOrder); + //保存数据 + List mesProductOffLineList = new ArrayList<>(); + List mesMoveList = new ArrayList<>(); + //条码 + List snList = mesProduceSnList.stream().map(MesProduceSn::getProductSn).collect(Collectors.toList()); + //物料信息 + Map> partSapMap = new HashMap<>(); + boolean isReport = false; + boolean isMove = false; + //排序加工规则 + MesProdRuleSortCfg mesProdRuleSortCfg = getMesProdRuleSortCfg(oldMesWorkOrder); + if (Objects.isNull(mesProdRuleSortCfg)){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】物料【%s】排序加工规则未维护", oldMesWorkOrder.getWorkCenterCode(), oldMesWorkOrder.getPartNo())); + } + + if(MesExtEnumUtil.MES_REPORT_TYPE.REPORT.getValue() == mesProdRuleSortCfg.getReportType()){ + isReport = true; + } else if (MesExtEnumUtil.MES_REPORT_TYPE.MOVE.getValue() == mesProdRuleSortCfg.getReportType()) { + isMove = true; + }else if (MesExtEnumUtil.MES_REPORT_TYPE.REPORT_MOVE.getValue() == mesProdRuleSortCfg.getReportType()) { + isReport = true; + isMove = true; + }else if (MesExtEnumUtil.MES_REPORT_TYPE.CUSTOMER_SUPPLY_MOVE.getValue() == mesProdRuleSortCfg.getReportType()) { + partSapMap = customerSupplyMove(oldMesWorkOrder, mesProductVersion, mesBoms, snList, mesProductOffLineList, mesMoveList); + }else{ + log.info("工单{}排序加工规则报工类型未维护",oldMesWorkOrder.getWorkOrderNo()); + return; + } + + //查询SAP物料信息 + List mesPartSaps = partSapMap.get(oldMesWorkOrder.getPartNo()); + if (mesPartSaps.isEmpty()){ + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("产线【%s】物料【%s】物料信息不存在", oldMesWorkOrder.getWorkCenterCode(), oldMesWorkOrder.getPartNo())); + } + MesPartSap mesPartSap = mesPartSaps.get(0); + for (String sn : snList) { + //成品汇报 + if(isReport){ + for (MesBom mesBom : mesBoms) { + mesProductOffLineList.add(creatMesProductOffLine(oldMesWorkOrder, mesProductVersion, sn, mesBom,false)); + } + } + //成品移库 + if(isMove){ + MesMove move = createMove(mesPartSap, mesProdRuleSortCfg.getSrcErpLocation(), mesProdRuleSortCfg.getDestErpLocation(), oldMesWorkOrder.getOrganizeCode(), 1d,sn,MesExtEnumUtil.MOVE_TYPE.FINISH_PRODUCTS_MOVE.getValue()); + move.setMatnr(oldMesWorkOrder.getPartNo()); + mesMoveList.add(move); + } + } + + //保存报工记录 + mesProductOffLineRDao.saveAll(mesProductOffLineList); + //保存移库记录 + mesMoveRDao.saveAll(mesMoveList); + } + } + + private void saveMesProductPlan(MesWorkOrder bean, boolean isInsert, boolean isReport,StationRequestBean reqBean, StationResultBean resultBean) { + if (StringUtil.isEmpty(bean.getPlanOrderNo())) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPlanStartTime(), "planStartDate", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPlanEndTime(), "planEndDate", ddlPackBean); + MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean); + if (null == mesProductPlan) { + MesProductPlan mesPlanOrder = new MesProductPlan(); + mesPlanOrder.setPlanOrderNo(""); + mesPlanOrder.setPlanQty(bean.getQty()); + mesPlanOrder.setPlanPartNo(bean.getPartNo()); + mesPlanOrder.setCompleteQty(0d); + mesPlanOrder.setUncompleteQty(bean.getQty()); + mesPlanOrder.setUnit(bean.getUnit()); + mesPlanOrder.setPlanStartDate(bean.getPlanStartTime()); + mesPlanOrder.setPlanEndDate(bean.getPlanEndTime()); + mesPlanOrder.setPartMappingWorkCenterCode(bean.getErpWorkCenter()); + mesPlanOrder.setPlanOrganizeCode(bean.getOrganizeCode()); + mesPlanOrder.setOrganizeCode(bean.getOrganizeCode()); + ConvertBean.serviceModelInitialize(mesPlanOrder, bean.getCreateUser()); + mesProductPlanRDao.insert(mesPlanOrder); + } else { + if (isInsert) { + mesProductPlan.setPlanQty(MathOperation.add(mesProductPlan.getPlanQty(), bean.getQty())); + } else { + //报工 + if (isReport) { + mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum())); + //报工调整 + } else { + mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum())); + } + } + mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty())); + ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser()); + mesProductPlanRDao.update(mesProductPlan); + } + } else { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(bean.getPlanOrderNo(), "planOrderNo", ddlPackBean); + DdlPreparedPack.getStringEqualPack(bean.getPartNo(), "planPartNo", ddlPackBean); + MesProductPlan mesProductPlan = mesProductPlanRDao.getByProperty(ddlPackBean); + if (null == mesProductPlan) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("SAP计划单号【%s】物料【%s】,不存在", bean.getPlanOrderNo(), bean.getPartNo())); + } + if (!isInsert) { + if (Objects.isNull(mesProductPlan.getCompleteQty())) { + mesProductPlan.setCompleteQty(0d); + } + //报工 + if (isReport) { + mesProductPlan.setCompleteQty(MathOperation.add(mesProductPlan.getCompleteQty(), bean.getNum())); + //报工调整 + } else { + mesProductPlan.setCompleteQty(MathOperation.sub(mesProductPlan.getCompleteQty(), bean.getNum())); + } + mesProductPlan.setUncompleteQty(MathOperation.sub(mesProductPlan.getPlanQty(), mesProductPlan.getCompleteQty())); + ConvertBean.serviceModelUpdate(mesProductPlan, bean.getCreateUser()); + mesProductPlanRDao.update(mesProductPlan); + } + } + } + + + private MesProdRuleSortCfg getMesProdRuleSortCfg(MesWorkOrder mesWorkOrder) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(mesWorkOrder.getPartNo(),"reportPartNo",ddlPackBean); + DdlPreparedPack.getStringEqualPack(mesWorkOrder.getWorkCenterCode(),"workCenterCode",ddlPackBean); + MesProdRuleSortCfg mesProdRuleSortCfg = mesProdRuleSortCfgRDao.getByProperty(ddlPackBean); + return mesProdRuleSortCfg; + } + + + private Map> customerSupplyMove(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, List mesBoms, List resultList, List mesProductOffLineList, List mesMoveList) { + boolean isItemMove; + boolean isItemReport; + MesMoveRule moveRule; + //查询零件生产组的移库规则 + List moveRules = this.findMesMoveRuleByPartProdGroupCode(mesWorkOrder.getPartProdGroupCode(), mesWorkOrder.getOrganizeCode()); + Map> mesMoveRuleMap = moveRules.stream().filter(t -> Objects.nonNull(t.getSrcType())).collect(Collectors.groupingBy(MesMoveRule::getSrcType)); + List itemPartNoList = mesBoms.stream().map(MesBom::getItemPartNo).collect(Collectors.toList()); + //子物料SAP下发信息 + Map> mesPartSapMap = getPartSapMap(mesWorkOrder, itemPartNoList); + //获取物料信息 + Map> itemPartMap = getItemPartMap(mesWorkOrder, itemPartNoList); + for (String sn : resultList) { + for (MesBom mesBom : mesBoms) { + isItemReport = false; + isItemMove = false; + moveRule = null; + if(itemPartMap.containsKey(mesBom.getItemPartNo())){ + MesPart itemPart = itemPartMap.get(mesBom.getItemPartNo()).iterator().next(); + if(!StringUtil.isEmpty(itemPart.getEsd()) && mesMoveRuleMap.containsKey(itemPart.getEsd())){ + moveRule = mesMoveRuleMap.get(itemPart.getEsd()).iterator().next(); + if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.REPORT_MOVE.getValue() == moveRule.getReportType()) { + isItemMove = true; + isItemReport = true; + } else if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.REPORT.getValue() == moveRule.getReportType()) { + isItemReport = true; + } else if (MesExtEnumUtil.MOVE_TYPE_REPORT_TYPE.MOVE.getValue() == moveRule.getReportType()) { + isItemMove = true; + } + } + } + //汇报 + if(isItemReport){ + mesProductOffLineList.add(creatMesProductOffLine(mesWorkOrder, mesProductVersion, sn, mesBom,true)); + } + //移库 + if(isItemMove){ + MesPartSap mesPartSap = null; + if(mesPartSapMap.containsKey(mesBom.getItemPartNo())){ + mesPartSap = mesPartSapMap.get(mesBom.getItemPartNo()).iterator().next(); + } + MesMove move = createMove(mesPartSap, moveRule.getErpSrcLocateNo(), moveRule.getErpDestLocateNo(), mesBom.getOrganizeCode(), mesBom.getItemQty(),"",MesExtEnumUtil.MOVE_TYPE.RAW_MATERIAL_MOVE.getValue()); + move.setMatnr(mesBom.getItemPartNo()); + mesMoveList.add(move); + } + } + } + //子物料SAP下发信息 + return mesPartSapMap ; + } + + + private List findMesMoveRuleByPartProdGroupCode(String partProdGroupCode, String organizeCode) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(partProdGroupCode, "partProdGroupCode", ddlPackBean); + List moveRules = moveRuleRao.findByHqlWhere(ddlPackBean); + return moveRules; + } + + private Map> getPartSapMap(MesWorkOrder mesWorkOrder, List itemPartNoList) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); + DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean); + List mesPartSapList = mesPartSapRao.findByHqlWhere(ddlPackBean); + Map> mesPartSapMap = mesPartSapList.stream().filter(t -> Objects.nonNull(t.getPartNo())).collect(Collectors.groupingBy(MesPartSap::getPartNo)); + return mesPartSapMap; + } + + private Map> getItemPartMap(MesWorkOrder mesWorkOrder, List itemPartNoList) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); + DdlPreparedPack.getInPackList(itemPartNoList, "partNo", ddlPackBean); + List mesPartList = partRao.findByHqlWhere(ddlPackBean); + Map> itemPartMap = mesPartList.stream().filter(t -> Objects.nonNull(t.getPartNo())).collect(Collectors.groupingBy(MesPart::getPartNo)); + return itemPartMap; + } + + private MesProductOffLine creatMesProductOffLine(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, + String sn, MesBom mesBom,boolean isItemReport) { + MesProductOffLine newMesProductOffLine; + newMesProductOffLine = new MesProductOffLine(); + if(!isItemReport){ + newMesProductOffLine.setReportPartNo(mesWorkOrder.getPartNo()); + newMesProductOffLine.setReportPartNameRdd(mesWorkOrder.getPartName()); + } + + newMesProductOffLine.setReportSn(sn); + newMesProductOffLine.setItemPartNo(mesBom.getItemPartNo()); + newMesProductOffLine.setItemPartName(mesBom.getItemPartName()); + newMesProductOffLine.setItemQty(mesBom.getItemQty()); + newMesProductOffLine.setAlort(mesProductVersion.getReceiveInventoryPoint()); + newMesProductOffLine.setStgeLoc(mesProductVersion.getShipInventoryPoint()); + newMesProductOffLine.setQty(1d); + newMesProductOffLine.setBomVersion(mesWorkOrder.getProductVersion()); + newMesProductOffLine.setSerialNumber(sn); + newMesProductOffLine.setUnit(mesBom.getUnit()); + newMesProductOffLine.setItemUnit(mesBom.getItemUnit()); + newMesProductOffLine.setWorkOrderNo(mesWorkOrder.getWorkOrderNo()); + newMesProductOffLine.setWorkCenterCode(mesWorkOrder.getWorkCenterCode()); + newMesProductOffLine.setWorkCellCode(mesWorkOrder.getWorkCellCode()); + newMesProductOffLine.setReportType(mesWorkOrder.getReportType()); + newMesProductOffLine.setSapWorkCenter(mesWorkOrder.getErpWorkCenter()); + newMesProductOffLine.setOrganizeCode(mesWorkOrder.getOrganizeCode()); + + ConvertBean.serviceModelInitialize(newMesProductOffLine, mesWorkOrder.getCreateUser()); + return newMesProductOffLine; + } + + private MesMove createMove(MesPartSap mesPart , String source, String target, String org,double qty,String sn,Integer moveType) { + MesMove move = new MesMove(); + if(!Objects.isNull(mesPart)){ + move.setMeins(mesPart.getUnit()); + } + move.setOrganizeCode(org); + move.setFactoryCode(org); + move.setLgort(source); + move.setUmlgo(target); + move.setMenge(qty); + move.setPostDate(TimeTool.getToday()); + move.setProductSn(sn); + move.setMoveType(moveType); + move.setPostTime(TimeTool.getTimeShortWithColon()); + ConvertBean.serviceModelInitialize(move, AuthUtil.getSessionUser().getUserName()); + return move; + } +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProdRuleContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProdRuleContext.java index ad72378..b11ce4b 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProdRuleContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProdRuleContext.java @@ -66,7 +66,9 @@ public class MesProdRuleContext implements Serializable { @ApiParam(name = "是否有装配件") private Integer isHasBind; - + /** + * 非排序报工方式 只有 汇报 或者 移库 二选一 + */ @ApiParam(name = "汇报方式") private Integer reportType; From c00cddc048ec3d8c82710c0dd4aa3478fbbda2b6 Mon Sep 17 00:00:00 2001 From: administrator Date: Thu, 13 Jun 2024 20:13:56 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BB=AA=E8=A1=A8=E8=AF=BB=E6=95=B0job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ext/mes/pcn/api/base/IMesMaximoService.java | 17 ++++ .../apiservice/schedulejob/MesMeterReadingJob.java | 48 +++++++++++ .../serviceimpl/base/MesMaximoServiceImpl.java | 94 ++++++++++++++++++++++ .../step/MesWorkOrderSaveStepService.java | 60 ++++++++++++++ .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 5 ++ 5 files changed, 224 insertions(+) create mode 100644 modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesMaximoService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesMeterReadingJob.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesMaximoServiceImpl.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveStepService.java diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesMaximoService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesMaximoService.java new file mode 100644 index 0000000..6fa20cb --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesMaximoService.java @@ -0,0 +1,17 @@ +package cn.estsh.i3plus.ext.mes.pcn.api.base; + +/** + * @Description : + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/13 17:54 + * @Modify: + **/ +public interface IMesMaximoService { + /** + * 仪表读数 + * @param organizeCode + * @param url + */ + void doMeterReading(String organizeCode,String url); +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesMeterReadingJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesMeterReadingJob.java new file mode 100644 index 0000000..582fce3 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesMeterReadingJob.java @@ -0,0 +1,48 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob; + + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesWorkOrderService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base.MesMaximoServiceImpl; +import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +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 java.util.List; + +/** + * @author castle,暂时没有客供品移库 + * @version 1.0 + * @date 2021/2/2 16:44 + **/ +@Slf4j +@DisallowConcurrentExecution +@Component +@ApiOperation("仪表读数job") +public class MesMeterReadingJob extends BaseMesScheduleJob { + + @Autowired + private MesMaximoServiceImpl maximoService; + + public MesMeterReadingJob() { + super(MesMeterReadingJob.class, "仪表读数job"); + } + @Override + public void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + String jobParam = this.getJobParam(); + JSONObject jsonObject= JSONUtil.parseObj(jobParam); + String organizeCode = jsonObject.getStr("organizeCode"); + String url = jsonObject.getStr("url"); + if (null == organizeCode){ + log.error("请添加需要报工的工厂代码!"); + return; + } + maximoService.doMeterReading(organizeCode,url); + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesMaximoServiceImpl.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesMaximoServiceImpl.java new file mode 100644 index 0000000..428ca04 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesMaximoServiceImpl.java @@ -0,0 +1,94 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base; + +import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesMaximoService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.platform.common.tool.TimeTool; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.bean.MesMouldMappingCfg; +import cn.estsh.i3plus.pojo.mes.repository.IMesMouldMappingCfgRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesProdMouldRecordRepository; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * @Description :Maximo 仪表读数汇总 + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/13 17:55 + * @Modify: + **/ +@Service +@Slf4j +public class MesMaximoServiceImpl implements IMesMaximoService { + @Autowired + private MesProdMouldRecordRepository prodMouldRecordRao; + @Autowired + private IMesMouldMappingCfgRepository mesMouldMappingCfgRao; + + @Override + public void doMeterReading(String organizeCode,String url) { + //1.查询表磨具映射关系维护表,查询出当前工厂需要统计的模具信息 + + //1.按天、按照meter_name 和 asset_num 汇总 + DdlPackBean modulePackBean = DdlPackBean.getDdlPackBean(organizeCode); + List mappingCfgList = mesMouldMappingCfgRao.findByHqlWhere(modulePackBean); + if (mappingCfgList.isEmpty()){ + log.info("当前工厂:{} 模具映射关系没有数据",organizeCode); + return; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + calendar.add(Calendar.DAY_OF_MONTH, -1); + Date date = calendar.getTime(); + String createDateTimeStart = TimeTool.getToday(date) + MesPcnExtConstWords.APPEND_ZERO_HMS; + String createDateTimeEnd = TimeTool.getToday(date) + MesPcnExtConstWords.APPEND_24_HMS; + for (MesMouldMappingCfg cfg : mappingCfgList) { + //循环模具映射关系维护 + DdlPackBean recordPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(cfg.getMeterName(),"meterName",recordPackBean); + DdlPreparedPack.getStringEqualPack(cfg.getAssetNum(),"assetNum",recordPackBean); + DdlPreparedPack.timeBuilder(createDateTimeStart,createDateTimeEnd,"createDatetime",recordPackBean,true); + int count = prodMouldRecordRao.findByHqlWhereCount(recordPackBean); + call(cfg.getMeterName(),cfg.getAssetNum(),organizeCode,count,url); + } + } + + + private void call(String meterName,String assetNum,String organizeCode,int count , String url){ + String xml = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ?\n" + + " %s\n" + + " %s\n" + + " %s\n" + + " %s\n" + + " %s\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + //2024-05-30T11:10:00 + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter isoDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + String today = now.format(isoDateTime); + String xmlString = String.format(xml, assetNum, meterName, count, today, organizeCode); + log.info("当前工厂:{},报文:{}",organizeCode,xmlString); + HttpRequest.post(url).header("Content-Type","text/xml").body(xmlString).execute().body(); + + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveStepService.java new file mode 100644 index 0000000..e8efe65 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderSaveStepService.java @@ -0,0 +1,60 @@ +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.pojo.context.MesProductionPartContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +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 lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Description : 保存加工单信息工步 + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/11 18:50 + * @Modify: + **/ +@Slf4j +@Service("mesWorkOrderSaveStepService") +public class MesWorkOrderSaveStepService extends BaseStepService { + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + StepResult stepResult = StepResult.getSuccessComplete(); + //1. 获取上下文中的MesProductionPartContext + List productionPartContext = productionDispatchContextStepService.getProductionPartContext(reqBean); + if (productionPartContext.isEmpty()){ + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "没有可保存的加工单信息"); + } + //2. 判断是否为空,id是否为空,如果没有则返回,id为工单id + List collectContext = productionPartContext.stream().filter(item -> item.getId() != null).collect(Collectors.toList()); + //3. 如果id不为空,查询工单信息 + if (collectContext.isEmpty()){ + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "没有可保存的加工单信息"); + } + //4. 判断当前产出的零件MesProductionPsOutContext中是否有id,如果有就是新生成的 + List productionPsOutContext = productionDispatchContextStepService.getProductionPsOutContext(reqBean); + //过滤出新生成的条码,没有条码id就是新生成的 + List produceSnList = productionPsOutContext.stream().filter(item -> item.getId() != null).collect(Collectors.toList()); + if (produceSnList.isEmpty()){ + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "没有可保存的加工单信息"); + } +// productionPsOutContext.stream().collect(Collectors.groupingBy(MesProductionPsOutContext::getId)) + //5. 修改完成数量,完成数量大于计划数量,就需要修改工单的状态为完成 + return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "保存加工单信息成功"); + } +} 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 7555549..7494f8c 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 @@ -10,6 +10,11 @@ package cn.estsh.i3plus.ext.mes.pcn.pojo.util; public class MesPcnExtConstWords { //-----------------COMMON-------------------------- + //拼接00时:00分:00秒 + public static final String APPEND_ZERO_HMS = " 00:00:00"; + //拼接23时:59分:59秒 + public static final String APPEND_24_HMS = " 23:59:59"; + public static final String REDIS_RES_PCN = "redisMesPcn"; // id常量