物料新增修改后同步艾普MES的物料、流程生产订单审批后推送艾普MES
This commit is contained in:
		
							parent
							
								
									d918f9afb3
								
							
						
					
					
						commit
						91ce065bdf
					
				|  | @ -0,0 +1,184 @@ | |||
| package nc.bs.mmpac.pmo.pac0002.bp.rule; | ||||
| 
 | ||||
| 
 | ||||
| import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import nc.bs.logging.Log; | ||||
| import nc.bs.logging.Logger; | ||||
| import nc.bs.uapbd.util.MyHelper; | ||||
| import nc.bs.uapbd.util.ThirdPartyPostRequestUtil; | ||||
| import nc.impl.pubapp.pattern.rule.IRule; | ||||
| import nc.itf.arap.goldentax.SysParaInitQuery; | ||||
| 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.FactoryVO; | ||||
| import nc.vo.pub.BusinessException; | ||||
| import nc.vo.pubapp.pattern.exception.ExceptionUtils; | ||||
| import nc.vo.scmpub.util.ArrayUtil; | ||||
| 
 | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 流程生产订单审批后推送艾普MES | ||||
|  * | ||||
|  * @author mzr | ||||
|  * @date 2025/7/3 | ||||
|  */ | ||||
| public class AfterApproveSyncEpicMesRule implements IRule<PMOAggVO> { | ||||
| 
 | ||||
|     private static final String LOG_INFO_NAME = "OALOG"; | ||||
| 
 | ||||
|     private static final Log obmlog = Log.getInstance(LOG_INFO_NAME); | ||||
| 
 | ||||
|     private static final String MES_PMO_SYNC_URL = "/prj-v5-web/ext/api/wrokOrder"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void process(PMOAggVO[] pmoAggVOS) { | ||||
|         if (ArrayUtil.isEmpty(pmoAggVOS)) { | ||||
|             return; | ||||
|         } | ||||
|         try { | ||||
|             List<PMOAggVO> filteredOrders = checkAndFilterBillSrcOrg(pmoAggVOS); | ||||
|             if (filteredOrders.isEmpty()) { | ||||
|                 obmlog.debug("没有符合条件的生产订单需要同步到MES系统。"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             obmlog.info("开始同步生产订单到MES系统,符合条件的订单数量: " + filteredOrders.size()); | ||||
|             // 推送到MES系统 | ||||
|             JSONArray dataArr = new JSONArray(); | ||||
|             for (PMOAggVO aggVO : filteredOrders) { | ||||
|                 PMOHeadVO head = aggVO.getParentVO(); | ||||
|                 PMOItemVO[] bodys = aggVO.getChildrenVO(); | ||||
| 
 | ||||
|                 if (bodys == null || bodys.length == 0) { | ||||
|                     obmlog.warn("生产订单 " + head.getVbillcode() + " 没有行信息,跳过同步。"); | ||||
|                     continue; | ||||
|                 } | ||||
|                 JSONObject object = buildSyncData(aggVO); | ||||
|                 dataArr.add(object); | ||||
|             } | ||||
|             JSONObject data = new JSONObject(); | ||||
|             data.put("workOrders", dataArr); | ||||
|             pushData(data); | ||||
|             obmlog.info("生产订单同步到MES系统处理完成。"); | ||||
| 
 | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             obmlog.error("同步生产订单到MES系统失败: " + e.getMessage(), e); | ||||
|             ExceptionUtils.wrappException(e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 调用MES接口并处理特定错误 | ||||
|      * | ||||
|      * @param param 请求体 | ||||
|      * @throws BusinessException 如果发生非特定可忽略的错误 | ||||
|      */ | ||||
|     private void pushData(JSONObject param) throws BusinessException { | ||||
|         String responseString = null; | ||||
|         try { | ||||
|             String baseUrl = SysParaInitQuery.getParaString("GLOBLE00000000000000", "EPICMESURL"); | ||||
|             String requestUrl = baseUrl + MES_PMO_SYNC_URL; | ||||
|             responseString = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, param.toJSONString()); | ||||
|             obmlog.info(" MES系统原始返回: " + responseString); | ||||
| 
 | ||||
|             JSONObject jsonResponse = JSONObject.parseObject(responseString); | ||||
|         } catch (Exception e) { | ||||
|             obmlog.error(" 调用MES或处理响应时发生错误。原始响应: " + responseString + " 错误: " + e.getMessage(), e); | ||||
|             throw new BusinessException("调用MES或处理响应时发生错误:" + e.getMessage(), e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 检查并筛选需要同步的单据 | ||||
|      */ | ||||
|     private List<PMOAggVO> checkAndFilterBillSrcOrg(PMOAggVO[] pmoAggVOS) throws BusinessException { | ||||
|         List<PMOAggVO> aggvoList = new ArrayList<>(); | ||||
|         for (PMOAggVO aggVo : pmoAggVOS) { | ||||
|             String pkOrg = aggVo.getParentVO().getPk_org(); | ||||
|             String orgCode = MyHelper.transferField(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, pkOrg); | ||||
|             // 检查当前组织是否为电力电子 | ||||
|             if (MyHelper.checkIfDldzOrg(orgCode)) { | ||||
|                 aggvoList.add(aggVo); | ||||
|             } | ||||
|         } | ||||
|         return aggvoList; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 组装数据 | ||||
|      */ | ||||
|     private JSONObject buildSyncData(PMOAggVO aggVO) { | ||||
|         PMOHeadVO headVo = aggVO.getParentVO(); | ||||
|         PMOItemVO[] pmoItems = aggVO.getChildrenVO(); | ||||
|         JSONObject data = new JSONObject(); | ||||
|         //       { | ||||
|         //           "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; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 转换特殊字段  如 1/1 转换为小数 1.0 | ||||
|      */ | ||||
| 
 | ||||
|     private String transferSpecialField(String field) { | ||||
|         if (field == null || field.trim().isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|         String[] split = field.split("/"); | ||||
|         if (split.length == 2) { | ||||
|             String numStr = split[0].trim(); | ||||
|             String denStr = split[1].trim(); | ||||
|             if (denStr.equals("0")) { | ||||
|                 return "0.00"; // 分母不能为零 | ||||
|             } | ||||
|             try { | ||||
|                 BigDecimal numerator = new BigDecimal(numStr); | ||||
|                 BigDecimal denominator = new BigDecimal(denStr); | ||||
|                 return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString(); | ||||
|             } catch (NumberFormatException e) { | ||||
|                 return field; // 非法数字,返回原字段 | ||||
|             } | ||||
|         } | ||||
|         return field; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,110 @@ | |||
| package nccloud.api.uapbd.material.listener; | ||||
| 
 | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import nc.bs.bd.baseservice.ArrayClassConvertUtil; | ||||
| import nc.bs.businessevent.IBusinessEvent; | ||||
| import nc.bs.businessevent.IBusinessListener; | ||||
| import nc.bs.businessevent.bd.BDCommonEvent; | ||||
| import nc.bs.logging.Logger; | ||||
| import nc.bs.uapbd.util.MyHelper; | ||||
| import nc.bs.uapbd.util.ThirdPartyPostRequestUtil; | ||||
| import nc.itf.arap.goldentax.SysParaInitQuery; | ||||
| import nc.vo.bd.material.MaterialVO; | ||||
| import nc.vo.bd.material.marbasclass.MarBasClassVO; | ||||
| import nc.vo.bd.material.measdoc.MeasdocVO; | ||||
| import nc.vo.org.FactoryVO; | ||||
| import nc.vo.pub.BusinessException; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 物料新增修改后同步艾普MES的物料 | ||||
|  * | ||||
|  * @author mzr | ||||
|  * @date 2025/06/27 | ||||
|  */ | ||||
| public class MaterialToEpicMesListener implements IBusinessListener { | ||||
| 
 | ||||
|     private static final String reqUrl = "/prj-v5-web/ext/api/mrl"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void doAction(IBusinessEvent event) throws BusinessException { | ||||
|         BDCommonEvent e = (BDCommonEvent) event; | ||||
|         String eventType = event.getEventType(); | ||||
|         Object[] objs = e.getObjs(); | ||||
|         MaterialVO[] useVOs = ArrayClassConvertUtil.convert(objs, MaterialVO.class); | ||||
|         // EventType是事件编码 | ||||
|         if ("1002".equals(eventType)) { | ||||
|             // 新增后 | ||||
|             buildSyncData(useVOs, eventType); | ||||
|         } else if ("1004".equals(eventType)) { | ||||
|             // 修改后 | ||||
|             buildSyncData(useVOs, eventType); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 构建同步数据 | ||||
|      */ | ||||
|     private void buildSyncData(MaterialVO[] useVOs, String eventType) throws BusinessException { | ||||
|         for (MaterialVO vo : useVOs) { | ||||
|             // 判断物料的业务单元是否是电力电子公司,不是则跳过 | ||||
|             String pkOrg = vo.getPk_org(); | ||||
|             String orgCode = MyHelper.transferField(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, pkOrg); | ||||
|             if (!MyHelper.checkIfDldzOrg(orgCode)) { | ||||
|                 continue; | ||||
|             } | ||||
|             // 1=未启用;2=已启用;3=已停用; | ||||
|             Integer enablestate = vo.getEnablestate(); | ||||
|             String statusCode = (3 == enablestate) ? "N" : "Y"; | ||||
|             JSONObject singleObj = new JSONObject(); | ||||
|             singleObj.put("id", null);// 唯一标识(主键) | ||||
|             singleObj.put("siteCode", null);// 工厂编码 | ||||
|             singleObj.put("mrlCode", vo.getCode());// 物料编码 | ||||
|             singleObj.put("mrlName", vo.getName());// 物料名称 | ||||
|             String pkMeasdoc = vo.getPk_measdoc(); | ||||
|             String unitName = MyHelper.transferField(MeasdocVO.getDefaultTableName(), MeasdocVO.NAME, MeasdocVO.PK_MEASDOC, pkMeasdoc); | ||||
|             singleObj.put("unit", unitName);// 单位 | ||||
|             singleObj.put("model", vo.getMaterialtype());// 型号 | ||||
|             singleObj.put("specification", vo.getMaterialspec());// 规格 | ||||
|             singleObj.put("type", getType(eventType));// 类型(I:新增 U:修改 D:删除) | ||||
|             singleObj.put("deputyUnit", null);// 副单位 | ||||
|             singleObj.put("auditCode", "1");// 审核码 | ||||
|             singleObj.put("statusCode", statusCode);// 状态码(Y表示启用,N表示停用) | ||||
|             singleObj.put("mrlTypeErp", "1");// 物料类型ERP(1:专用件,3:通用件) | ||||
|             String pk_marbasclass = vo.getPk_marbasclass(); | ||||
|             String mrlTypeCOde = MyHelper.transferField(MarBasClassVO.getDefaultTableName(), MarBasClassVO.CODE, MarBasClassVO.PK_MARBASCLASS, pk_marbasclass); | ||||
|             singleObj.put("mrlType", mrlTypeCOde);// 物料分类编码 | ||||
|             singleObj.put("convertRate", "1");// 单位换算率 | ||||
|             singleObj.put("isCheck", "1");// 是否选中(1:是,0:否) | ||||
|             pushData(singleObj); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 推送同步数据 | ||||
|      */ | ||||
|     private void pushData(JSONObject param) throws BusinessException { | ||||
|         String baseUrl = SysParaInitQuery.getParaString("GLOBLE00000000000000", "EPICMESURL"); | ||||
|         String requestUrl = baseUrl + reqUrl; | ||||
|         String result = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, param.toJSONString()); | ||||
|         JSONObject resultObj = JSONObject.parseObject(result); | ||||
|         Logger.error("EpicMes-Material-req = " + result); | ||||
| 
 | ||||
|         if ("false".equals(resultObj.getString("success"))) { | ||||
|             throw new BusinessException("EpicMes-Material-fail,error:" + resultObj.getString("msg")); | ||||
|         } else { | ||||
|             Logger.error("EpicMes-Material-suc,result[" + resultObj.toJSONString() + "]"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private String getType(String eventType) { | ||||
|         // 类型(I:新增 U:修改 D:删除) | ||||
|         Map<String, String> map = new HashMap<>(); | ||||
|         map.put("1002", "I"); | ||||
|         map.put("1004", "U"); | ||||
|         return map.getOrDefault(eventType, "I"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue