Merge remote-tracking branch 'origin/main'
This commit is contained in:
		
						commit
						3e2ba05328
					
				|  | @ -62,13 +62,38 @@ public class HttpPostOtherSysImpl implements IHttpPostOtherSys { | |||
| 
 | ||||
|             obmlog.debug("三方接口返回::" + jsonResponse.toJSONString()); // 记录三方接口返回的数据 | ||||
| 
 | ||||
|             String success = jsonResponse.getString("Success"); // 获取返回结果中的Success字段 | ||||
|             if ("false".equals(success)) { // 判断请求是否成功 | ||||
|                 String errorMessage = jsonResponse.getString("ErrorMessage"); // 获取错误信息 | ||||
|                 if (errorMessage == null) { | ||||
|                     errorMessage = "外部系统未提供错误消息。"; | ||||
|             // 检查是否存在 "Data" 数组 | ||||
|             if (jsonResponse.containsKey("Data") && jsonResponse.get("Data") instanceof com.alibaba.fastjson.JSONArray) { | ||||
|                 com.alibaba.fastjson.JSONArray dataArray = jsonResponse.getJSONArray("Data"); | ||||
|                 for (int i = 0; i < dataArray.size(); i++) { | ||||
|                     JSONObject dataObject = dataArray.getJSONObject(i); | ||||
|                     String successInData = dataObject.getString("Success"); | ||||
|                     if ("false".equalsIgnoreCase(successInData)) { | ||||
|                         String errorMessage = dataObject.getString("ErrorMessage"); | ||||
|                         if (errorMessage == null || errorMessage.isEmpty()) { | ||||
|                             errorMessage = dataObject.getString("Message"); // 尝试获取 Message 字段 | ||||
|                         } | ||||
|                         if (errorMessage == null || errorMessage.isEmpty()) { | ||||
|                             errorMessage = "外部系统未提供错误消息。"; | ||||
|                         } | ||||
|                         throw new BusinessException("同步mes系统失败,错误消息:" + errorMessage); | ||||
|                     } | ||||
|                 } | ||||
|                 // 如果Data数组中所有项都成功,则认为整体成功 | ||||
|                 // 当前逻辑:如果Data数组存在且所有项成功,则不再检查顶层Success,直接认为成功。 | ||||
|             } else { | ||||
|                 // 原有的逻辑,处理顶层Success字段 | ||||
|                 String success = jsonResponse.getString("Success"); // 获取返回结果中的Success字段 | ||||
|                 if ("false".equalsIgnoreCase(success)) { // 判断请求是否成功 | ||||
|                     String errorMessage = jsonResponse.getString("ErrorMessage"); // 获取错误信息 | ||||
|                     if (errorMessage == null || errorMessage.isEmpty()) { | ||||
|                         errorMessage = jsonResponse.getString("Message"); // 尝试获取 Message 字段 | ||||
|                     } | ||||
|                     if (errorMessage == null || errorMessage.isEmpty()) { | ||||
|                         errorMessage = "外部系统未提供错误消息。"; | ||||
|                     } | ||||
|                     throw new BusinessException("同步mes系统失败,错误消息:" + errorMessage); // 抛出业务异常 | ||||
|                 } | ||||
|                 throw new BusinessException("同步mes系统失败,错误消息:" + errorMessage); // 抛出业务异常 | ||||
|             } | ||||
| 
 | ||||
|         } catch (BusinessException e) { | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| package nc.bs.mmpac.pmo.pac0002.bp; | ||||
| 
 | ||||
| 
 | ||||
| import nc.bs.mmpac.pmo.pac0002.bp.rule.AfterApproveRuleSyncMes; | ||||
| import nc.bs.mmpac.pmo.pac0002.bp.rule.AfterApprovingSynchronizeRuleRZ; | ||||
| import nc.bs.mmpac.pmo.pac0002.pluginpoint.PMOPluginPoint; | ||||
| import nc.bs.mmpac.pmo.pac0002.rule.*; | ||||
|  | @ -51,6 +53,9 @@ public class PMOApproveBP { | |||
|         processer.addAfterRule(auditSupplyRule); | ||||
|         // 审批后推送到RZ系统 | ||||
|         processer.addAfterRule(new AfterApprovingSynchronizeRuleRZ()); | ||||
|         // 审批后推送流程生产订单到MES | ||||
|         processer.addAfterRule(new AfterApproveRuleSyncMes()); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public PMOAggVO[] approveCancel(PMOAggVO[] fullBills, PMOAggVO[] originBills) { | ||||
|  |  | |||
|  | @ -0,0 +1,290 @@ | |||
| package nc.bs.mmpac.pmo.pac0002.bp.rule; | ||||
| 
 | ||||
| 
 | ||||
| import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import nc.bs.dao.BaseDAO; | ||||
| import nc.bs.framework.common.NCLocator; | ||||
| import nc.bs.logging.Log; | ||||
| import nc.impl.pubapp.pattern.rule.IRule; | ||||
| import nc.jdbc.framework.processor.ColumnProcessor; | ||||
| import nc.vo.bd.bom.bom0202.entity.BomVO; | ||||
| import nc.vo.bd.material.MaterialVersionVO; | ||||
| import nc.vo.cmp.util.StringUtils; | ||||
| 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.pubapp.pattern.pub.SqlBuilder; | ||||
| import nc.vo.scmpub.util.ArrayUtil; | ||||
| import nc.vo.vorg.DeptVersionVO; | ||||
| import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; | ||||
| 
 | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 流程生产订单审批后推送MES | ||||
|  */ | ||||
| public class AfterApproveRuleSyncMes implements IRule<PMOAggVO> { | ||||
| 
 | ||||
|     public static final IHttpPostOtherSys HTTP_POST_OTHER_SYS = NCLocator.getInstance().lookup(IHttpPostOtherSys.class); | ||||
| 
 | ||||
|     private static final String LOG_INFO_NAME = "OALOG"; | ||||
| 
 | ||||
|     private static final Log obmlog = Log.getInstance(LOG_INFO_NAME); | ||||
| 
 | ||||
|     private static final BaseDAO dao = new BaseDAO(); | ||||
| 
 | ||||
|     private static final String MES_PMO_SYNC_URL = "/GTHINKING/AjaxService/N_SCSJJSA/102525006.ashx/receive_woinfo_insert"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void process(PMOAggVO[] pmoAggVOS) { | ||||
|         if (ArrayUtil.isEmpty(pmoAggVOS)) { | ||||
|             return; | ||||
|         } | ||||
|         try { | ||||
|             // 检查并筛选生产订单 | ||||
|             List<PMOAggVO> filteredOrders = checkAndFilterBillSrcOrg(pmoAggVOS); | ||||
|             if (filteredOrders.isEmpty()) { | ||||
|                 obmlog.info("没有符合条件的生产订单需要同步到MES系统。"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             obmlog.info("开始同步生产订单到MES系统,符合条件的订单数量: " + filteredOrders.size()); | ||||
|             // 推送到MES系统 | ||||
|             for (PMOAggVO aggVO : filteredOrders) { | ||||
|                 PMOHeadVO head = aggVO.getParentVO(); | ||||
|                 PMOItemVO[] bodys = aggVO.getChildrenVO(); | ||||
| 
 | ||||
|                 if (bodys == null || bodys.length == 0) { | ||||
|                     obmlog.warn("生产订单 " + head.getVbillcode() + " 没有行信息,跳过同步。"); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 for (PMOItemVO item : bodys) { | ||||
|                     syncOrderItemToMes(head, item); | ||||
|                 } | ||||
|             } | ||||
|             obmlog.info("生产订单同步到MES系统处理完成。"); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             obmlog.error("同步生产订单到MES系统失败: " + e.getMessage(), e); | ||||
|             ExceptionUtils.wrappException(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 = transferCodeByPk(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, pkOrg); | ||||
|             if ("C034".equals(orgCode)) { | ||||
|                 aggvoList.add(aggvo); | ||||
|             } | ||||
|         } | ||||
|         return aggvoList; | ||||
|     } | ||||
| 
 | ||||
|     private void syncOrderItemToMes(PMOHeadVO head, PMOItemVO item) throws BusinessException { | ||||
|         JSONObject data = new JSONObject(); | ||||
|         String vbillcode = head.getVbillcode(); // 单据号 | ||||
|         String itemRow = item.getVrowno(); // 行号 | ||||
| 
 | ||||
|         obmlog.info("开始为生产订单 " + vbillcode + " 行 " + itemRow + " 构建同步MES数据。"); | ||||
| 
 | ||||
|         // orderNo String 是 生产订单号 vbillcode | ||||
|         if (vbillcode.length() > 18) { | ||||
|             throw new BusinessException("MES同步要求:生产订单 " + vbillcode + " 行 " + itemRow + " 单据号长度不能超过18位。"); | ||||
|         } | ||||
| 
 | ||||
|         data.put("orderNo", vbillcode); | ||||
| 
 | ||||
|         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | ||||
| 
 | ||||
|         // startDate String 是 计划开工日期 格式yyyy-MM-dd tplanstarttime | ||||
|         if (item.getTplanstarttime() != null && item.getTplanstarttime().toStdString() != null) { | ||||
|             data.put("startDate", item.getTplanstarttime().getDate().toStdString().toString()); | ||||
|         } else { | ||||
|             data.put("startDate", null); | ||||
|         } | ||||
| 
 | ||||
|         // endDate String 是 计划完工日期 格式yyyy-MM-dd tplanendtime | ||||
|         if (item.getTplanendtime() != null && item.getTplanendtime().getDate().toStdString() != null) { | ||||
|             data.put("endDate", item.getTplanendtime().getDate().toStdString().toString()); | ||||
|         } else { | ||||
|             data.put("endDate", null); // Or handle as error if required | ||||
|         } | ||||
| 
 | ||||
|         // type String 是 类型 有传入销售订单号时传入MPS;否则传入EXT 默认:MPS | ||||
|         // status String 是 状态 有传入销售订单号时传入P;否则传入I 默认:P | ||||
|         // MRPMark String 是 MRP标志 有传入销售订单号时传入Y;否则传入N 默认:Y | ||||
|         data.put("type", "MPS"); | ||||
|         data.put("status", "P"); | ||||
|         data.put("MRPMark", "Y"); | ||||
| 
 | ||||
|         // materialId String 是 物料编码 cmaterialvid (物料版本PK) | ||||
|         if (!StringUtils.isEmpty(item.getCmaterialvid())) { | ||||
|             String materialCode = transferCodeByPk(MaterialVersionVO.getDefaultTableName(), MaterialVersionVO.CODE, MaterialVersionVO.PK_MATERIAL, item.getCmaterialvid()); | ||||
|             data.put("materialId", materialCode); | ||||
|         } else { | ||||
|             throw new BusinessException("生产订单 " + vbillcode + " 行 " + itemRow + " 物料版本信息获取失败。"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         // bomNum String 是 产品结构号 cbbomversionid (BOM版本PK) - | ||||
|         if (item.getCbomversionid() != null) { | ||||
|             String hcmaterialid = transferCodeByPk(BomVO.TABLE_NAME, BomVO.HCMATERIALID, nc.vo.bd.bom.bom0202.entity.BomVO.CBOMID, item.getCbomversionid()); | ||||
|             String bomNum = transferCodeByPk(MaterialVersionVO.getDefaultTableName(), MaterialVersionVO.CODE, MaterialVersionVO.PK_SOURCE, hcmaterialid); | ||||
|             data.put("bomNum", bomNum); | ||||
| 
 | ||||
|             // routeNum String 是 工艺路线号 vrtversion (工艺路线版本号)// 2025年5月23日9点50分,段京岗:routeNum和bomNum取相同值 | ||||
|             data.put("routeNum", bomNum); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         // departmentId String 是 部门编码 cdeptvid (生产车间PK) | ||||
|         if (!StringUtils.isEmpty(item.getCdeptvid())) { | ||||
|             String deptCode = transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE, DeptVersionVO.PK_VID, item.getCdeptvid()); | ||||
|             data.put("departmentId", deptCode); | ||||
|         } else { | ||||
|             throw new BusinessException("生产订单 " + vbillcode + " 行 :MES系统要求" + itemRow + " 部门信息不能为空。"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         // factoryId String 是 工厂编码 pk_org (库存组织PK) | ||||
|         if (!StringUtils.isEmpty(head.getPk_org())) { | ||||
|             String factoryCode = transferCodeByPk(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, head.getPk_org()); | ||||
|             data.put("factoryId", factoryCode); | ||||
|         } else { | ||||
|             throw new BusinessException("生产订单 " + vbillcode + " 行 : MES系统要求" + itemRow + " 工厂信息不能为空。"); | ||||
|         } | ||||
| 
 | ||||
|         // productNum String 制令号 vsalebillcode | ||||
|         data.put("productNum", item.getVsalebillcode()); | ||||
|         // saleOrderNo String 销售订单号 vsalebillcode | ||||
|         data.put("saleOrderNo", item.getVsalebillcode()); | ||||
| 
 | ||||
|         // saleSequenceNum Double 销售订单序号 vfirstrowno | ||||
|         if (!StringUtils.isEmpty(item.getVfirstrowno())) { | ||||
|             try { | ||||
|                 data.put("saleSequenceNum", Double.parseDouble(item.getVfirstrowno())); | ||||
|             } catch (NumberFormatException e) { | ||||
|                 obmlog.warn("生产订单 " + vbillcode + " 行 " + itemRow + "MES系统同步: 销售订单序号 (vfirstrowno) '" + item.getVfirstrowno() + "' 无法解析为小数。" + e.getMessage()); | ||||
|                 data.put("saleSequenceNum", null); | ||||
|             } | ||||
|         } else { | ||||
|             data.put("saleSequenceNum", null); | ||||
|         } | ||||
| 
 | ||||
|         // 备注 | ||||
|         data.put("remark", item.getVnote()); | ||||
| 
 | ||||
| 
 | ||||
|         // quantity double 是 需求数量 nnum | ||||
|         data.put("quantity", item.getNnum() != null ? item.getNnum().doubleValue() : 0.0); | ||||
|         // assitQuantity double 辅助需求数量 nastnum | ||||
|         data.put("assitQuantity", item.getNastnum() != null ? item.getNastnum().doubleValue() : 0.0); | ||||
| 
 | ||||
|         // scaleFactor double 换算系数 vchangerate | ||||
|         data.put("scaleFactor", transferSpecialField(item.getVchangerate())); | ||||
| 
 | ||||
|         // method String 是 排产方式 N|排产时指定 S|顺排 D|倒排 默认:N | ||||
|         data.put("method", "N"); | ||||
|         // priority Double 排产优先级 默认:空 | ||||
|         data.put("priority", null); | ||||
| 
 | ||||
|         // compileDate String 编制日期 格式yyyy-MM-dd 默认传入当前日期 dbilldate | ||||
|         String compileDateStr; | ||||
|         if (head.getDbilldate() != null) { | ||||
|             compileDateStr = head.getDbilldate().toStdString(); | ||||
|             data.put("compileDate", compileDateStr); | ||||
|         } | ||||
| 
 | ||||
|         // 通过自定义属性传 | ||||
|         JSONArray properties = new JSONArray(); | ||||
|         JSONObject SXZF16 = new JSONObject(); | ||||
|         JSONObject SXZF17 = new JSONObject(); | ||||
|         JSONObject SXZF18 = new JSONObject(); | ||||
| 
 | ||||
|         SXZF16.put("propertyFiled", "SXZF16"); | ||||
|         SXZF17.put("propertyFiled", "SXZF17"); | ||||
|         SXZF18.put("propertyFiled", "SXZF18"); | ||||
| 
 | ||||
|         SXZF16.put("propertyValue", item.getVparentbillcode()); | ||||
|         SXZF17.put("propertyValue", item.getVparentmorowno()); | ||||
|         SXZF18.put("propertyValue", head.getVtrantypecode()); | ||||
| 
 | ||||
|         properties.add(SXZF16); | ||||
|         properties.add(SXZF17); | ||||
|         properties.add(SXZF18); | ||||
| 
 | ||||
|         data.put("properties", properties); | ||||
|         JSONObject requestPayload = new JSONObject(); | ||||
|         JSONArray dataArr = new JSONArray(); | ||||
|         dataArr.add(data); | ||||
|         requestPayload.put("data", dataArr); | ||||
| 
 | ||||
| 
 | ||||
|         obmlog.info("生产订单 " + vbillcode + " 行 " + itemRow + " 同步MES请求数据: " + requestPayload.toJSONString()); | ||||
| 
 | ||||
|         // Send to MES | ||||
|         // Note: The actual endpoint URL might need to be configured or obtained from a central place. | ||||
|         HTTP_POST_OTHER_SYS.sendToExternalSystem(MES_PMO_SYNC_URL, requestPayload); | ||||
|         obmlog.info("生产订单 " + vbillcode + " 行 " + itemRow + " 已成功发送到MES系统。"); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 根据主键查询编码 | ||||
|      */ | ||||
|     private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { | ||||
|         if (StringUtils.isEmpty(pk)) { | ||||
|             return null; | ||||
|         } | ||||
|         SqlBuilder sqlBuilder = new SqlBuilder(); | ||||
|         sqlBuilder.append(" select " + selectField); | ||||
|         sqlBuilder.append(" from " + tableName); | ||||
|         sqlBuilder.append(" where "); | ||||
|         sqlBuilder.append(pkField, pk); | ||||
|         Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); | ||||
|         if (o == null) { | ||||
|             throw new BusinessException("未查询到编码信息,sql【" + sqlBuilder + "】"); | ||||
|         } | ||||
|         return o.toString(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 转换特殊字段  如 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; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue