From 494dc876b420c0776e298e64d6cf3eea4e462ffe Mon Sep 17 00:00:00 2001 From: mzr Date: Tue, 23 Sep 2025 17:14:36 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=B2=BE=E5=AF=86-=E5=90=AF=E6=BA=90?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E7=94=9F=E4=BA=A7=E8=AE=A2=E5=8D=95=E4=BC=A0?= =?UTF-8?q?=E5=8F=82=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bs/mmpac/pmo/pac0002/bp/rule/AfterPmoSyncJmQMSRule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterPmoSyncJmQMSRule.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterPmoSyncJmQMSRule.java index b1e300d3..ac4cbdf4 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterPmoSyncJmQMSRule.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterPmoSyncJmQMSRule.java @@ -100,7 +100,7 @@ public class AfterPmoSyncJmQMSRule implements IRule { JSONObject itemObj = new JSONObject(); itemObj.put("bipqdid", item.getCmoid());// BIP行id - itemObj.put("sgdh", projectCode);// 施工单号-BIP项目编码 + itemObj.put("sgdh", item.getCmoid());// 施工单号-BIP行id itemObj.put("xshth", item.getVfirstcode());// 销售合同号-BIP源头单据号 itemObj.put("htqdxh", item.getVfirstrowno());// 合同清单序号-BIP源头单据行号 itemObj.put("wlbh", mrlmap.get("code"));// 产品编号 @@ -162,7 +162,7 @@ public class AfterPmoSyncJmQMSRule implements IRule { if (!"true".equals(resultObj.getString("success"))) { logger.error("QMS-PMO-JM-error,result[" + resultObj.toJSONString() + "]"); - throw new BusinessException("QMS-PMO-JM-error:" + resultObj.getString("msg")); + throw new BusinessException("QMS-PMO-JM-error:" + resultObj.getString("message")); } } From 6c2d331de9cf9a58b7e221bf634e8fbcb807613d Mon Sep 17 00:00:00 2001 From: mzr Date: Tue, 23 Sep 2025 18:36:22 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=B2=BE=E5=AF=86-=E5=90=AF=E6=BA=90-?= =?UTF-8?q?=E7=89=A9=E6=96=99=E6=8E=A8=E9=80=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pfxx/plugin/MaterialPlanPfxxPlugin.java | 297 ++++++++++++++++++ .../listener/MaterialToJmQmsListener.java | 9 +- 2 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 uapbd/src/private/nc/bs/bd/pfxx/plugin/MaterialPlanPfxxPlugin.java diff --git a/uapbd/src/private/nc/bs/bd/pfxx/plugin/MaterialPlanPfxxPlugin.java b/uapbd/src/private/nc/bs/bd/pfxx/plugin/MaterialPlanPfxxPlugin.java new file mode 100644 index 00000000..7140b829 --- /dev/null +++ b/uapbd/src/private/nc/bs/bd/pfxx/plugin/MaterialPlanPfxxPlugin.java @@ -0,0 +1,297 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package nc.bs.bd.pfxx.plugin; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import nc.bs.dao.BaseDAO; +import nc.bs.dao.DAOException; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.bs.pfxx.ISwapContext; +import nc.bs.pfxx.plugin.AbstractPfxxPlugin; +import nc.bs.trade.business.HYPubBO; +import nc.bs.trade.business.HYSuperDMO; +import nc.bs.uapbd.util.MyHelper; +import nc.bs.uapbd.util.ThirdPartyPostRequestUtil; +import nc.itf.bd.material.assign.IMaterialAssignService; +import nc.itf.bd.material.plan.IMaterialPlanQueryService; +import nc.itf.bd.material.plan.IMaterialPlanService; +import nc.jdbc.framework.processor.MapProcessor; +import nc.pubitf.uapbd.IMaterialPubService; +import nc.util.mmf.framework.base.MMValueCheck; +import nc.vo.bd.defdoc.DefdocVO; +import nc.vo.bd.errorlog.ErrLogReturnValue; +import nc.vo.bd.material.MaterialVO; +import nc.vo.bd.material.plan.MaterialPlanVO; +import nc.vo.bd.material.stock.MaterialReplVO; +import nc.vo.bd.material.stock.MaterialStockVO; +import nc.vo.pfxx.auxiliary.AggxsysregisterVO; +import nc.vo.pfxx.util.PfxxPluginUtils; +import nc.vo.pub.BusinessException; + +import java.util.*; +import java.util.stream.Stream; + +public class MaterialPlanPfxxPlugin extends AbstractPfxxPlugin { + IMaterialPlanQueryService materialplanqueryservice = null; + IMaterialPlanService materialplanservice = null; + IMaterialAssignService assignservice = null; + + private static final String LOG_INFO_NAME = "qyMesLog"; + private static final Log logger = Log.getInstance(LOG_INFO_NAME); + private static final String reqUrl = "/IF_QyErpApi.ashx?action=addwlxx"; + private Map configParams; + + public MaterialPlanPfxxPlugin() { + } + + protected Object processBill(Object vo, ISwapContext swapContext, AggxsysregisterVO aggvo) throws BusinessException { + MaterialPlanVO planvo = (MaterialPlanVO) vo; + MaterialPlanVO[] pvos = this.getMaterialPlanQueryService().queryMaterialPlanVOs(new String[]{planvo.getPk_org()}, planvo.getPk_material()); + if (pvos != null && pvos.length != 0) { + planvo = this.updateMaterialPlan(pvos, planvo); + } else { + planvo = this.insertMaterialPlan(planvo); + PfxxPluginUtils.addDocIDVsPKContrast(swapContext.getBilltype(), swapContext.getDocID(), planvo.getPrimaryKey()); + } + + return planvo.getPrimaryKey(); + } + + private MaterialPlanVO insertMaterialPlan(MaterialPlanVO planvo) throws BusinessException { + ErrLogReturnValue value = this.getService().assignByPks(new String[]{planvo.getPk_material()}, new String[]{planvo.getPk_org()}, true); + MaterialPlanVO[] pvos = this.getMaterialPlanQueryService().queryMaterialPlanVOs(new String[]{planvo.getPk_org()}, planvo.getPk_material()); + if (pvos != null && pvos.length > 0) { + planvo = this.updateMaterialPlan(pvos, planvo); + } + + return planvo; + } + + private MaterialPlanVO updateMaterialPlan(MaterialPlanVO[] pvos, MaterialPlanVO planvo) throws BusinessException { + List list = new ArrayList(); + MaterialPlanVO vo = pvos[0]; + String[] attrs = planvo.getAttributeNames(); + + for (String attr : attrs) { + if (planvo.getAttributeValue(attr) != null && !"materialrepl".equals(attr)) { + vo.setAttributeValue(attr, planvo.getAttributeValue(attr)); + } + } + + if (vo.getMaterialrepl() != null && vo.getMaterialrepl().length > 0) { + for (MaterialReplVO replvo : vo.getMaterialrepl()) { + replvo.setStatus(3); + list.add(replvo); + } + } + + if (planvo.getMaterialrepl() != null && planvo.getMaterialrepl().length > 0) { + for (MaterialReplVO replvo : planvo.getMaterialrepl()) { + replvo.setStatus(2); + list.add(replvo); + } + } + + vo.setMaterialrepl((MaterialReplVO[]) list.toArray(new MaterialReplVO[0])); + vo = this.getMaterialPlanService().updateMaterialPlanVO(vo); + syncQMS(vo); + return vo; + } + + private IMaterialPlanQueryService getMaterialPlanQueryService() { + if (this.materialplanqueryservice == null) { + this.materialplanqueryservice = (IMaterialPlanQueryService) NCLocator.getInstance().lookup(IMaterialPlanQueryService.class); + } + + return this.materialplanqueryservice; + } + + private IMaterialPlanService getMaterialPlanService() { + if (this.materialplanservice == null) { + this.materialplanservice = (IMaterialPlanService) NCLocator.getInstance().lookup(IMaterialPlanService.class); + } + + return this.materialplanservice; + } + + private IMaterialAssignService getService() { + if (this.assignservice == null) { + this.assignservice = (IMaterialAssignService) NCLocator.getInstance().lookup(IMaterialAssignService.class); + } + + return this.assignservice; + } + + private void syncQMS(MaterialPlanVO planVO) throws BusinessException { + // 修改物料计划信息的接口执行之后同步修改启源物料 + configParams = MyHelper.getConfigParams("jm-config", null); + buildSyncData(planVO); + } + + /** + * 构建同步数据 + */ + private void buildSyncData(MaterialPlanVO planVO) throws BusinessException { + String pkMaterial = planVO.getPk_material(); + String pkOrg = planVO.getPk_org(); + HYPubBO hyPub = new HYPubBO(); + MaterialVO vo = (MaterialVO) hyPub.queryByPrimaryKey(MaterialVO.class, pkMaterial); + // 判断物料的业务单元是否是精密公司,不是则跳过 + Integer num = MyHelper.checkIfOrg(configParams, pkMaterial, "jmOrg"); + if (num <= 0) { + return; + } + // 字段值翻译 + // String pk_marbasclass = vo.getPk_marbasclass(); + // String mrlTypeName = MyHelper.getStrValByCondition(MarBasClassVO.getDefaultTableName(), MarBasClassVO.NAME, + // "pk_marbasclass = '" + pk_marbasclass + "'"); + // 计量单位 + Map unitMap = getGoodsInfo(pkMaterial); + // 启源物料编码 + Map planMap = queryMaterialPlanInfoByPks(new String[]{pkMaterial}, pkOrg, + new String[]{MaterialPlanVO.DEF2}); + // 计划信息自定义项2(原系统编码)BIP传启源物料档案的物料编码,BIP中物料编码传启源自定义字段“BIP物料编码” + String qyCode = ""; + if (MMValueCheck.isNotEmpty(planMap) && + MMValueCheck.isNotEmpty(planMap.get(pkMaterial))) { + qyCode = planMap.get(pkMaterial).getDef2(); + } else { + qyCode = vo.getCode(); + } + // 1=未启用;2=已启用;3=已停用; + Integer enablestate = vo.getEnablestate(); + String statusCode = (3 == enablestate) ? "1" : "0"; + Map stockMap = MyHelper.getMapValByCondition(MaterialStockVO.getDefaultTableName(), "def3,def4,martype", + MaterialStockVO.PK_MATERIAL + " = '" + pkMaterial + "' and pk_org = '" + pkOrg + "'"); + // 制造件传启源 + if (!"MR".equals(stockMap.get("martype"))) { + return; + } + // 物料标志和产品分类字段在库存信息页签中,分配物料的时候没有默认值,需要在此处设置 + // 物料标志 + String wlbz = "产品"; + String wlbzId = stockMap.get("def3") + ""; + String defName = getDefName("zdy-jmzz001", wlbzId); + if (MMValueCheck.isNotEmpty(defName)) { + wlbz = defName; + } + // 产品分类 + String cpfl = "内配铸造件成品"; + String cpflId = stockMap.get("def4") + ""; + String defName1 = getDefName("zdy-jmzz002", cpflId); + if (MMValueCheck.isNotEmpty(defName1)) { + cpfl = defName1; + } + // 组装数据 + JSONObject singleObj = new JSONObject(); + // 批次编号,用于唯一标识当前传输的物料数据批次,便于追溯和批量处理 + long cts = System.currentTimeMillis(); + singleObj.put("batchid", cts); + JSONObject contentObj = new JSONObject(); + contentObj.put("meswlbh", qyCode); // 启源物料编码 + contentObj.put("bipwlbh", vo.getCode()); // BIP物料编码 + contentObj.put("wlmc", vo.getName()); // 物料名称 + contentObj.put("wlxhgg", vo.getMaterialtype() + vo.getMaterialspec()); // 物料型号规格 + contentObj.put("wlfl", ""); // 物料分类 + contentObj.put("cpfl", cpfl); // 产品分类 + contentObj.put("wlbz", wlbz); // 物料标志 + contentObj.put("sjjldw", unitMap.get("unitname")); // 设计计量单位 + contentObj.put("cgjldw", unitMap.get("deputy_unitname")); // 采购计量单位 + contentObj.put("zhxs", unitMap.getOrDefault("convertRate", "1.00")); // 转换系数 + contentObj.put("flag_fq", statusCode); // 1/0 传递1代表物料废弃 + contentObj.put("bz", vo.getMemo()); // 备注信息 + JSONArray contentArr = new JSONArray(); + contentArr.add(contentObj); + singleObj.put("Content", contentArr); + pushData(singleObj); + } + + /** + * 推送同步数据 + */ + private void pushData(JSONObject param) throws BusinessException { + // String jsonString = param.toJSONString(); + // 转json字符串的时候保留null值 + String jsonStr = JSON.toJSONString(param, + SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteNullStringAsEmpty + ); + logger.error("QMS-Material-param = " + jsonStr); + // NCCForUAPLogger.debug("QMS-Material-param = " + jsonStr); + String baseUrl = configParams.get("qmsBaseUrl"); + String requestUrl = baseUrl + reqUrl; + logger.error("QMS-Material-url = " + requestUrl); + String result = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, jsonStr); + JSONObject resultObj = JSONObject.parseObject(result); + logger.error("QMS-Material-res = " + result); + + if (!"true".equals(resultObj.getString("success"))) { + logger.error("QMS-Material-error,result[" + resultObj.toJSONString() + "]"); + throw new BusinessException("QMS-Material-error:" + resultObj.getString("message")); + } + } + + private Map getGoodsInfo(String pkMaterial) throws BusinessException { + String sql = " select a.pk_measdoc, c.name unitname, b.pk_measdoc deputyUnit, d.name deputy_unitname, nvl(b.measrate, '1/1') measrate " + + "from bd_material a " + + "left join bd_materialconvert b on a.pk_material = b.pk_material " + + "left join bd_measdoc c on a.pk_measdoc = c.pk_measdoc " + + "left join bd_measdoc d on b.pk_measdoc = d.pk_measdoc " + + "where a.pk_material = '" + pkMaterial + "' "; + Map map = (Map) new BaseDAO().executeQuery(sql, new MapProcessor()); + map.put("convertRate", MyHelper.transferSpecialField(map.get("measrate") + "")); + return map; + } + + private boolean checkIfOrg(String code, Map configParams) throws BusinessException { + String targetCode = configParams.get("jmOrg"); + if (targetCode == null || nc.vo.am.common.util.StringUtils.isEmpty(targetCode)) { + throw new BusinessException("未配置组织参数"); + } + String[] orgItem = targetCode.split(","); + for (String orgCode : orgItem) { + if (!orgCode.isEmpty() && orgCode.equals(code)) { + return false; + } + } + return true; + } + + public Map queryMaterialPlanInfoByPks(String[] pks, String pk_stockorg, + String[] fields) throws BusinessException { + Map map = null; + List vids = Stream.of(pks).filter(Objects::nonNull).distinct().toList(); + if (vids.isEmpty()) { + map = new HashMap<>(); + } else { + map = NCLocator.getInstance().lookup(IMaterialPubService.class) + .queryMaterialPlanInfoByPks(vids.toArray(new String[0]), pk_stockorg, fields); + } + + return map; + } + + /** + * 获取自定义项信息 + */ + private String getDefName(String code, String pk_defdoc) { + String res = ""; + String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='" + code + "' and dr=0 ) and dr = 0 and pk_defdoc = '" + pk_defdoc + "'"; + try { + DefdocVO[] defdocVOs = (DefdocVO[]) new HYSuperDMO().queryByWhereClause(DefdocVO.class, strWhere); + if (defdocVOs != null && defdocVOs.length > 0) { + res = defdocVOs[0].getName().trim(); + } + } catch (DAOException e) { + logger.error("gyMes-SaleOrder-error,getDefName[" + e.getMessage() + "]"); + } + return res; + } +} diff --git a/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToJmQmsListener.java b/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToJmQmsListener.java index af64e4b8..49354287 100644 --- a/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToJmQmsListener.java +++ b/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToJmQmsListener.java @@ -72,8 +72,8 @@ public class MaterialToJmQmsListener implements IBusinessListener { List list = new ArrayList<>(); // 计划信息修改 MaterialPlanVO[] planVOS = ArrayClassConvertUtil.convert(objs, MaterialPlanVO.class); - for (MaterialPlanVO stockVO : planVOS) { - String pkMaterial = stockVO.getPk_material(); + for (MaterialPlanVO planVO : planVOS) { + String pkMaterial = planVO.getPk_material(); if (MMValueCheck.isEmpty(pkMaterial)) { continue; } @@ -140,6 +140,8 @@ public class MaterialToJmQmsListener implements IBusinessListener { if (MMValueCheck.isNotEmpty(planMap) && MMValueCheck.isNotEmpty(planMap.get(pkMaterial))) { qyCode = planMap.get(pkMaterial).getDef2(); + } else { + qyCode = vo.getCode(); } // 1=未启用;2=已启用;3=已停用; Integer enablestate = vo.getEnablestate(); @@ -172,9 +174,6 @@ public class MaterialToJmQmsListener implements IBusinessListener { singleObj.put("batchid", cts); JSONObject contentObj = new JSONObject(); // 计划信息自定义项2(原系统编码)BIP传启源物料档案的物料编码,BIP中物料编码传启源自定义字段“BIP物料编码” - if (MMValueCheck.isEmpty(qyCode)) { - qyCode = vo.getCode(); - } contentObj.put("meswlbh", qyCode); // 启源物料编码 contentObj.put("bipwlbh", vo.getCode()); // BIP物料编码 contentObj.put("wlmc", vo.getName()); // 物料名称 From ae95edbd61fa07c47f5a332e7ef9f4bd116602d6 Mon Sep 17 00:00:00 2001 From: mzr Date: Tue, 23 Sep 2025 19:10:49 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=94=B5=E5=8A=9B=E7=94=B5=E5=AD=90-?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E7=94=9F=E4=BA=A7=E8=AE=A2=E5=8D=95=E5=92=8C?= =?UTF-8?q?BOM=E8=B7=B3=E8=BF=87=E6=9C=9F=E5=88=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pmo/pac0002/bp/rule/AfterDelSyncEpicMesRule.java | 10 ++++++++++ .../pmo/pac0002/bp/rule/util/SyncEpicMesUtil.java | 10 +++++++++- .../bd/bom/bom0202/rule/BomSaveAfterEpicMesRule.java | 5 +++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterDelSyncEpicMesRule.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterDelSyncEpicMesRule.java index 9b968634..02e36891 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterDelSyncEpicMesRule.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterDelSyncEpicMesRule.java @@ -22,6 +22,7 @@ import nc.vo.pubapp.pattern.exception.ExceptionUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; /** * 流程生产订单删除后同步艾普MES @@ -66,7 +67,16 @@ public class AfterDelSyncEpicMesRule implements IRule { // logDl.info("开始同步生产订单到艾普MES系统,符合条件的订单数量: " + filteredOrders.size()); JSONArray jsonArray = new JSONArray(); // 推送到艾普MES系统 + Set billTypeCodes = Set.of( + "55A2-Cxx-01", "55A2-Cxx-18" + ); for (PMOAggVO aggVO : filteredOrders) { + PMOHeadVO headVo = aggVO.getParentVO(); + // 判断订单类型,期初订单不处理 + String vtrantypecode = headVo.getVtrantypecode(); + if (billTypeCodes.contains(vtrantypecode)) { + continue; + } buildSyncData(aggVO, jsonArray); } if (!jsonArray.isEmpty()) { diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/util/SyncEpicMesUtil.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/util/SyncEpicMesUtil.java index deda644a..302c8401 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/util/SyncEpicMesUtil.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/util/SyncEpicMesUtil.java @@ -24,6 +24,7 @@ import nccloud.commons.lang.StringUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; /** * 流程生产订单审批后推送艾普MES @@ -67,10 +68,18 @@ public class SyncEpicMesUtil { return; } logDl.info("开始同步生产订单到艾普MES系统,符合条件的订单数量: " + filteredOrders.size()); + Set billTypeCodes = Set.of( + "55A2-Cxx-01", "55A2-Cxx-18" + ); JSONArray jsonArray = new JSONArray(); // 推送到艾普MES系统 for (PMOAggVO aggVO : filteredOrders) { PMOHeadVO head = aggVO.getParentVO(); + // 判断订单类型,期初订单不处理 + String vtrantypecode = head.getVtrantypecode(); + if (billTypeCodes.contains(vtrantypecode)) { + continue; + } PMOItemVO[] bodys = aggVO.getChildrenVO(); if (bodys == null || bodys.length == 0) { logDl.error("生产订单 " + head.getVbillcode() + " 没有行信息,跳过同步。"); @@ -93,7 +102,6 @@ public class SyncEpicMesUtil { pushData(codeUrl, jsonArray); } - logDl.info("生产订单同步到艾普MES系统处理完成。"); } diff --git a/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BomSaveAfterEpicMesRule.java b/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BomSaveAfterEpicMesRule.java index 255e2d7d..ab27fc70 100644 --- a/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BomSaveAfterEpicMesRule.java +++ b/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BomSaveAfterEpicMesRule.java @@ -54,6 +54,11 @@ public class BomSaveAfterEpicMesRule implements IRule { for (AggBomVO vo : useVOs) { // 判断物料的业务单元是否是电力电子公司,不是则跳过 BomVO hvo = (BomVO) vo.getParentVO(); + String hvnote = hvo.getHvnote(); + // 跳过期初的BOM + if ("202509QC".equals(hvnote)) { + continue; + } String pkOrg = (String) hvo.getAttributeValue("pk_org"); String orgCode = MyHelper.transferField(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg); if (MyHelper.checkIfDldzOrg(orgCode, configParams)) { From c32aabcb8da9885a371c0e989e7cbbd88ed7981d Mon Sep 17 00:00:00 2001 From: mzr Date: Tue, 23 Sep 2025 20:49:17 +0800 Subject: [PATCH 4/4] =?UTF-8?q?PMO-=E8=89=BE=E6=99=AEmes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mmpac/pmo/action/PmoToEpicMesAction.java | 49 +++ .../web/mmpac/pmo/action/PmoToPlmAction.java | 4 +- .../pmo/pac0002/util/HttpPmoEpicMesUtil.java | 296 ++++++++++++++++++ 3 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToEpicMesAction.java create mode 100644 mmpac/src/public/nc/vo/mmpac/pmo/pac0002/util/HttpPmoEpicMesUtil.java diff --git a/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToEpicMesAction.java b/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToEpicMesAction.java new file mode 100644 index 00000000..aa6083ef --- /dev/null +++ b/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToEpicMesAction.java @@ -0,0 +1,49 @@ +package nccloud.web.mmpac.pmo.action; + +import nc.bs.logging.Log; +import nc.itf.mmpac.pmo.pac0002.IPMOQueryService; +import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO; +import nc.vo.mmpac.pmo.pac0002.util.HttpPmoEpicMesUtil; +import nc.vo.scmpub.util.ArrayUtil; +import nccloud.framework.core.exception.ExceptionUtils; +import nccloud.framework.service.ServiceLocator; +import nccloud.framework.web.action.itf.ICommonAction; +import nccloud.framework.web.container.IRequest; +import nccloud.framework.web.json.JsonFactory; +import nccloud.web.mmpub.pub.resexp.PfResumeExceptionNccUtils; + +import java.util.List; +import java.util.Map; + +/** + * 流程生产订单手动推艾普MES + * + * @author mzr + * @date 2025/9/23 + */ +public class PmoToEpicMesAction implements ICommonAction { + private static final String LOG_INFO_NAME = "dldzlog"; + + private static final Log logDl = Log.getInstance(LOG_INFO_NAME); + + @Override + public Object doAction(IRequest iRequest) { + String json = iRequest.read(); + Map paraMap = (Map) JsonFactory.create().fromJson(json, Map.class); + try { + // 获取主键 + List pkList = (List) paraMap.get("pks"); + String[] pks = pkList.toArray(new String[0]); + PMOAggVO[] pmoAggVOS = ServiceLocator.find(IPMOQueryService.class).queryByPks(pks); + if (ArrayUtil.isEmpty(pmoAggVOS)) { + ExceptionUtils.wrapBusinessException("查询不到对应流程生产订单"); + } + HttpPmoEpicMesUtil mesUtil = new HttpPmoEpicMesUtil(); + // mesUtil.pushData(pmoAggVOS, "Y"); + } catch (Exception e) { + logDl.error("同步生产订单到艾普MES系统失败: " + e.getMessage(), e); + return PfResumeExceptionNccUtils.handleResumeException(e); + } + } + +} diff --git a/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToPlmAction.java b/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToPlmAction.java index 02dbd22d..df492e7a 100644 --- a/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToPlmAction.java +++ b/mmpac/src/client/nccloud/web/mmpac/pmo/action/PmoToPlmAction.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import nc.bs.dao.BaseDAO; import nc.bs.dao.DAOException; -import nc.bs.framework.common.NCLocator; import nc.bs.logging.Log; import nc.bs.logging.Logger; import nc.bs.trade.business.HYPubBO; @@ -20,6 +19,7 @@ import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO; import nc.vo.org.OrgVO; import nc.vo.pub.BusinessException; import nc.vo.util.CloneUtil; +import nccloud.framework.service.ServiceLocator; import nccloud.framework.web.action.itf.ICommonAction; import nccloud.framework.web.container.IRequest; import nccloud.framework.web.json.JsonFactory; @@ -76,7 +76,7 @@ public class PmoToPlmAction implements ICommonAction { // 获取主键 List pkList = (List) paraMap.get("pks"); String[] pks = pkList.toArray(new String[0]); - PMOAggVO[] pmoAggVOS = NCLocator.getInstance().lookup(IPMOQueryService.class).queryByPks(pks); + PMOAggVO[] pmoAggVOS = ServiceLocator.find(IPMOQueryService.class).queryByPks(pks); configParams = getConfigParams("Dldz-config"); PMOAggVO[] cloneOrderVOS = (PMOAggVO[]) CloneUtil.deepClone(pmoAggVOS); // 检查并筛选生产订单 diff --git a/mmpac/src/public/nc/vo/mmpac/pmo/pac0002/util/HttpPmoEpicMesUtil.java b/mmpac/src/public/nc/vo/mmpac/pmo/pac0002/util/HttpPmoEpicMesUtil.java new file mode 100644 index 00000000..51bdcca2 --- /dev/null +++ b/mmpac/src/public/nc/vo/mmpac/pmo/pac0002/util/HttpPmoEpicMesUtil.java @@ -0,0 +1,296 @@ +package nc.vo.mmpac.pmo.pac0002.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import nc.bs.dao.BaseDAO; +import nc.bs.logging.Log; +import nc.bs.uapbd.util.MyHelper; +import nc.bs.uapbd.util.ThirdPartyPostRequestUtil; +import nc.jdbc.framework.processor.MapListProcessor; +import nc.jdbc.framework.processor.MapProcessor; +import nc.vo.bd.bom.bom0202.entity.BomVO; +import nc.vo.bd.material.MaterialVO; +import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO; +import nc.vo.mmpac.pmo.pac0002.entity.PMOHeadVO; +import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO; +import nc.vo.org.DeptVO; +import nc.vo.org.OrgVO; +import nc.vo.pub.BusinessException; +import nc.vo.pubapp.pattern.pub.SqlBuilder; +import nccloud.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 流程生产订单审批后推送艾普MES工具类 + * + * @author mzr + * @date 2025/7/3 + */ +public class HttpPmoEpicMesUtil { + + private static final String LOG_INFO_NAME = "dldzlog"; + + private static final Log logDl = Log.getInstance(LOG_INFO_NAME); + + private static final String pmoUrl = "/prj-v5-web/ext/api/workOrder"; + private static final String codeUrl = "/prj-v5-web/ext/api/releaseNo"; + private static String auditCode = "Y"; + private Map configParams; + private Map deptParams; + + private static final BaseDAO dao = new BaseDAO(); + + /** + * 调用MES的生产工单接口推送ERP的流程生产订单和备料计划或推送出厂编号 + * + * @param param 请求体 + * @throws BusinessException 如果发生非特定可忽略的错误 + */ + public void pushData(String reqUrl, Object param) throws BusinessException { + String responseString = null; + try { + // 转json字符串的时候保留null值 + String jsonStr = JSON.toJSONString(param, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty); + logDl.error("EpicMes-PMO-param = " + jsonStr); + String baseUrl = configParams.get("epicMesUrl"); + String requestUrl = baseUrl + reqUrl; + logDl.error(" EpicMes-PMO-url = " + requestUrl); + responseString = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, jsonStr); + logDl.error(" EpicMes-PMO-res = " + responseString); + + JSONObject resultObj = JSONObject.parseObject(responseString); + if (!"1".equals(resultObj.getString("flag"))) { + logDl.error("EpicMes-PMO-error,result[" + resultObj.toJSONString() + "]"); + throw new BusinessException("艾普MES返回错误信息:" + resultObj.getString("msg")); + } + } catch (Exception e) { + logDl.error(" 调用MES或处理响应时发生错误。原始响应: " + responseString + " 错误: " + e.getMessage(), e); + throw new BusinessException("调用艾普MES或处理响应时发生错误:" + e.getMessage(), e); + } + } + + /** + * 检查并筛选需要同步的单据 + */ + public List checkAndFilterBillSrcOrg(PMOAggVO[] pmoAggVOS) throws BusinessException { + List aggvoList = new ArrayList<>(); + for (PMOAggVO aggVo : pmoAggVOS) { + String pkOrg = aggVo.getParentVO().getPk_org(); + String orgCode = MyHelper.transferField(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg); + // 检查当前组织是否为电力电子 + if (MyHelper.checkIfDldzOrg(orgCode, configParams)) { + continue; + } + // 按照部门筛选生产订单,只传消弧车间、电容车间、成套车间(部门是配置项) + PMOItemVO childrenVO = aggVo.getChildrenVO()[0]; + String cdeptid = childrenVO.getCdeptid(); + String deptCode = MyHelper.transferField(DeptVO.getDefaultTableName(), DeptVO.CODE, DeptVO.PK_DEPT, cdeptid); + // 如果部门不在范围内则跳过本次循环 + String deptRange = configParams.get("deptRange"); + if (deptCode == null || !deptRange.contains(deptCode)) { + continue; + } + aggvoList.add(aggVo); + } + + return aggvoList; + } + + /** + * 组装数据-流程生产订单+备料计划 + */ + public JSONObject buildSyncData(PMOAggVO aggVO) throws BusinessException { + PMOHeadVO headVo = aggVO.getParentVO(); + // 目前电力电子只做一个表体的订单,故只处理的流程生产订单第一个子表行 + PMOItemVO pmoItem = aggVO.getChildrenVO()[0]; + // 翻译字段值 + // 组织 + String pkOrg = headVo.getPk_org(); + String selectFields = OrgVO.CODE + "," + OrgVO.NAME; + Map orgMap = MyHelper.transferFields(OrgVO.getDefaultTableName(), selectFields, OrgVO.PK_ORG, pkOrg); + // 物料 + String cmaterialid = pmoItem.getCmaterialid(); + selectFields = MaterialVO.CODE + "," + MaterialVO.NAME; + Map goodsMap = MyHelper.transferFields(MaterialVO.getDefaultTableName(), selectFields, MaterialVO.PK_MATERIAL, cmaterialid); + // 项目 + // String cprojectid = pmoItem.getCprojectid(); + // selectFields = ProjectHeadVO.PROJECT_CODE + "," + ProjectHeadVO.PROJECT_NAME; + // Map projectMap = MyHelper.transferFields(ProjectHeadVO.getDefaultTableName(), selectFields, ProjectHeadVO.PK_PROJECT, cprojectid); + // 生产部门 cdeptid + String cdeptid = pmoItem.getCdeptid(); + String deptCode = MyHelper.transferField(DeptVO.getDefaultTableName(), DeptVO.CODE, DeptVO.PK_DEPT, cdeptid); + // 生产BOM版本 + String cbomversionid = pmoItem.getCbomversionid(); + String bomCode = MyHelper.transferField(BomVO.TABLE_NAME, BomVO.HVERSION, BomVO.CBOMID, cbomversionid); + // 组装数据 + JSONObject data = new JSONObject(); + JSONObject orderParam = new JSONObject(); + orderParam.put("id", null); // 唯一标识(主键) + // 根据自定义档案中的映射关系,部门编码转换为MES中的编码 + orderParam.put("siteCode", deptParams.getOrDefault(deptCode, ""));// 工厂编码 + orderParam.put("contractNo", pmoItem.getVfirstcode());// 合同号-取ERP的源头单据号-销售订单号 + /*if (projectMap != null) { + orderParam.put("contractNo", projectMap.get(ProjectHeadVO.PROJECT_CODE));// 合同号 + orderParam.put("contractName", projectMap.get(ProjectHeadVO.PROJECT_NAME)); // 合同名称 + }*/ + orderParam.put("workOrderCode", headVo.getVbillcode());// 工单号 + orderParam.put("qty", String.valueOf(pmoItem.getNastnum())); // 计划数量,字符串类型 + if (goodsMap != null) { + orderParam.put("produCode", goodsMap.get(MaterialVO.CODE)); // 产品编码 + orderParam.put("produName", goodsMap.get(MaterialVO.NAME)); // 产品名称 + } + // cbomversionid 生产BOM版本 + orderParam.put("bomCode", bomCode); // BOM 编码 + // NCCForUAPLogger.debug("计划开始时间:" + pmoItem.getTplanstarttime().getMillis()); + // NCCForUAPLogger.debug("计划完成时间:" + pmoItem.getTplanendtime().getMillis()); + orderParam.put("planBeginDate", pmoItem.getTplanstarttime().getMillis()); // 计划开始时间(毫秒级时间戳) + orderParam.put("planEndDate", pmoItem.getTplanendtime().getMillis()); // 计划完成时间(毫秒级时间戳) + // orderParam.put("endDate", null); // 试验结束时间(毫秒级时间戳) + orderParam.put("type", "I"); // 类型:I:新增 U:修改 D:删除 + orderParam.put("auditCode", auditCode); // 审核状态(Y:已审核 N:未审核) + // orderParam.put("transferPlanTime", null); // 生产转检计划时间(格式为YYYY-MM-DD) + // orderParam.put("receiptScheduledTime", null); // 完工入库时间(格式为YYYY-MM-DD) + if (orgMap != null) { + orderParam.put("companyCode", orgMap.get(OrgVO.CODE)); // 公司编码 + orderParam.put("companyName", orgMap.get(OrgVO.NAME)); // 公司名称 + } + JSONArray orderArr = new JSONArray(); + orderArr.add(orderParam); + // 流程生产订单 + data.put("workOrders", orderArr); + data.put("mrls", getPickmInfo(pmoItem.getPrimaryKey())); // 备料计划 + // { + // "workOrders": [// 流程生产订单 + // { + // "id": null, // 唯一标识(主键) + // "siteCode": "04", // 工厂编码 + // "contractNo": "HDDK0111325", // 合同号 + // "workOrderCode": "DSF01-2501230028",// 工单号 + // "qty": "1.000", // 计划数量(字符串类型) + // "produCode": "103248250005", // 产品编码 + // "produName": "150KV滤抗-特高压宝塔山(试装)-低端", // 产品名称 + // "bomCode": "103248250005", // BOM 编码 + // "planBeginDate": 1751328000000, // 计划开始时间(毫秒级时间戳) + // "planEndDate": 1751328000000, // 计划结束时间(毫秒级时间戳) + // "endDate": 1751328000000, // 试验结束时间(毫秒级时间戳) + // "type": null, // 类型(I:新增 U:修改 D:删除) + // "auditCode": "Y", // 审核码(Y:已审核 N:未审核) + // "contractName": "特高压宝塔山±800 千伏换流站工程", // 合同名称 + // "transferPlanTime": "2025-07-01", // 生产转检计划时间(格式:YYYY-MM-DD) + // "receiptScheduledTime": "2025-07-01", // 完工入库时间(格式:YYYY-MM-DD) + // "companyCode": "DLDZ", // 公司编码 + // "companyName": "泰开电力电子" // 公司名称 + // } + // ], + // "mrls": [ 备料计划 + // { + // "workOrderCode": "DSF01-2501230028",// 工单号 + // "mrlCode": "2305050447", // 物料编码 + // "mrlName": "铝加工件", // 物料名称 + // "qty": 1.000, // 数量(浮点数) + // "unit": "套" // 单位 + // } + // ] + // } + + return data; + } + + /** + * 备料计划数据封装 + * + * @param sourceId 流程生产订单唯一标识 + * @return + * @throws BusinessException + */ + public JSONArray getPickmInfo(String sourceId) throws BusinessException { + // vsourcemorowid 来源生产订单明细id + JSONArray pickmArr = new JSONArray(); + if (StringUtils.isEmpty(sourceId) || "~".equals(sourceId)) { + return pickmArr; + } + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select c.code mrlcode, c.name mrlname, d.name unit, b.nplanoutastnum qty"); + sqlBuilder.append(" from mm_pickm_b b"); + sqlBuilder.append(" left join mm_pickm a on b.cpickmid = a.cpickmid"); + sqlBuilder.append(" left join bd_material c on b.cbmaterialid = c.pk_material"); + sqlBuilder.append(" left join bd_measdoc d on b.cbastunitid = d.pk_measdoc"); + sqlBuilder.append(" where b.dr = 0"); + sqlBuilder.append(" and "); + // sqlBuilder.append("a.csourcebillid", sourceId); + sqlBuilder.append("a.vsourcemorowid", sourceId);// 来源生产订单明细id + logDl.error("查询备料计划数据:" + sqlBuilder); + List> result = (List>) dao.executeQuery(sqlBuilder.toString(), new MapListProcessor()); + for (Map objectMap : result) { + JSONObject bodyJson = new JSONObject(); + bodyJson.put("mrlCode", objectMap.get("mrlcode"));// 物料编码 + bodyJson.put("mrlName", objectMap.get("mrlname"));// 物料名称 + bodyJson.put("qty", objectMap.get("qty"));// 数量 + bodyJson.put("unit", objectMap.get("unit"));// 单位 + pickmArr.add(bodyJson); + } + if (pickmArr.isEmpty()) { + logDl.error("查询备料计划为空,sourceId = " + sourceId + ",sql = " + sqlBuilder); + } + return pickmArr; + + } + + public JSONObject buildSyncCodeData(PMOAggVO vo) throws BusinessException { +// [ +// { +// "siteCode": "", // 工厂编码 +// "workOrderCode": "", // 工单号 +// "companyCode": "DLDZ", //公司编码 +// "companyName": "泰开电力电子",//公司名称 +// "releaseNo": [] // 出厂编号 +// } +//] + PMOHeadVO hvo = vo.getParentVO(); + PMOItemVO pmoItem = vo.getChildrenVO()[0]; + // 生产部门 cdeptid + String cdeptid = pmoItem.getCdeptid(); + String deptCode = MyHelper.transferField(DeptVO.getDefaultTableName(), DeptVO.CODE, DeptVO.PK_DEPT, cdeptid); + JSONObject obj = new JSONObject(); + obj.put("siteCode", deptParams.getOrDefault(deptCode, "")); + obj.put("workOrderCode", hvo.getVbillcode()); + + BaseDAO dao = new BaseDAO(); + String orgsql = "select code,name from org_factory where pk_factory = '" + hvo.getPk_org() + "' "; + Map tr = (Map) dao.executeQuery(orgsql, new MapProcessor()); + obj.put("companyCode", tr.get("code")); + obj.put("companyName", tr.get("name")); + JSONArray jsonArray = new JSONArray(); + for (PMOItemVO item : vo.getChildrenVO()) { + // HYPubBO hybo = new HYPubBO(); + // List materialtype = (List) hybo.findColValue("mm_pmo_serialno", "vsncode", "cmoid = '" + item.getCmoid() + "' and dr = 0 "); + // IBillcodeManage billcodeManage = NCLocator.getInstance().lookup(IBillcodeManage.class); + // String code = billcodeManage.getPreBillCode_RequiresNew("xxxxx-code-rule", hvo.getPk_group(), hvo.getPk_org()); + String vsncode = " select vsncode from mm_pmo_serialno where cmoid in ( '" + item.getCmoid() + "' ) and mm_pmo_serialno.dr = 0 "; + // Map vsncodeList = (Map) dao.executeQuery(vsncode, new MapProcessor()); + ArrayList> vsncodeList = (ArrayList>) dao.executeQuery(vsncode, new MapListProcessor()); + if (vsncodeList.isEmpty()) { + // jsonArray.add(""); + continue; + } + for (Map v : vsncodeList) { + jsonArray.add(v.get("vsncode")); + } + // String detailItem = (null != materialtype ? materialtype : "") + hvo.getDbilldate().toStdString().substring(0, 3) + hvo.getDbilldate().toStdString().substring(5, 6) + code; + // jsonArray.add(detailItem); + } + if (jsonArray.isEmpty()) { + return null; + } + obj.put("releaseNo", jsonArray); + + return obj; + } + +}