diff --git a/qc/src/private/nc/bs/qc/c003/maintain/ReportInsertBP.java b/qc/src/private/nc/bs/qc/c003/maintain/ReportInsertBP.java index 17418c46..2207c256 100644 --- a/qc/src/private/nc/bs/qc/c003/maintain/ReportInsertBP.java +++ b/qc/src/private/nc/bs/qc/c003/maintain/ReportInsertBP.java @@ -48,7 +48,7 @@ public class ReportInsertBP { this.addAfterFinalRule(processer); processer.before(aggVO); BillInsert bo = new BillInsert(); - ReportVO[] vos = (ReportVO[])bo.insert(aggVO); + ReportVO[] vos = (ReportVO[]) bo.insert(aggVO); processer.after(aggVO); return vos; } diff --git a/qc/src/private/nc/bs/qc/c003/maintain/rule/SyncQcQmsRule.java b/qc/src/private/nc/bs/qc/c003/maintain/rule/SyncQcQmsRule.java index 5020419b..36d454db 100644 --- a/qc/src/private/nc/bs/qc/c003/maintain/rule/SyncQcQmsRule.java +++ b/qc/src/private/nc/bs/qc/c003/maintain/rule/SyncQcQmsRule.java @@ -107,10 +107,8 @@ public class SyncQcQmsRule implements IRule { String creatorName = MyHelper.getStrValByCondition("sm_user", UserVO.USER_NAME, UserVO.CUSERID + " = '" + hvo.getBillmaker() + "'"); JSONObject singleObj = new JSONObject(); - String cghth = ""; - if (bvo != null && bvo.length > 0) { - cghth = bvo[0].getVsourcecode(); - } + // 采购合同号 + String cghth = getCghthVal(bvo); // 启源送检单主表 long cts = System.currentTimeMillis(); singleObj.put("batchid", cts); @@ -123,7 +121,7 @@ public class SyncQcQmsRule implements IRule { singleObj.put("bz", hvo.getVmemo());// 摘要备注,用于填写送检单的补充说明信息 // 查询关联的质检报告-传入启源送检单的明细 HYPubBO hybo = new HYPubBO(); - ReportItemVO[] reportItemVOS = (ReportItemVO[]) hybo.queryByCondition(ReportItemVO.class, " and cfirstid = '" + pk_arriveorder + "'"); + ReportItemVO[] reportItemVOS = (ReportItemVO[]) hybo.queryByCondition(ReportItemVO.class, " cfirstid = '" + pk_arriveorder + "'"); JSONArray contentArray = new JSONArray(); for (ReportItemVO reportItemVO : reportItemVOS) { String pkReportbill = reportItemVO.getPk_reportbill(); @@ -150,6 +148,26 @@ public class SyncQcQmsRule implements IRule { } } + private String getCghthVal(ArriveItemVO[] bvo) { + String cghth = ""; + if (bvo != null && bvo.length > 0) { + StringBuilder cghthBuilder = new StringBuilder(); + for (int i = 0; i < bvo.length; i++) { + String vsourcecode = bvo[i].getVsourcecode(); + if (vsourcecode == null || vsourcecode.isEmpty() || "~".equals(vsourcecode)) { + continue; + } + if (i > 0) { + cghthBuilder.append(","); + } + cghthBuilder.append(vsourcecode); + // 查询采购员名称 + } + cghth = cghthBuilder.toString(); + } + return cghth; + } + private void buildSyncData1(ReportVO[] useVOs) throws BusinessException { for (ReportVO vo : useVOs) { ReportHeaderVO hvo = vo.getHVO(); diff --git a/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleQMS.java b/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleQMS.java index ad485c28..0f18fa0a 100644 --- a/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleQMS.java +++ b/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleQMS.java @@ -176,8 +176,8 @@ public class AfterApprovingSynchronizeRuleQMS implements IRule { String requestUrl = baseUrl + reqUrl; logger.error("QMS-SaleOrder-url = " + requestUrl); String result = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, jsonStr); - JSONObject resultObj = JSONObject.parseObject(result); logger.error("QMS-SaleOrder-res = " + result); + JSONObject resultObj = JSONObject.parseObject(result); if (!"true".equals(resultObj.getString("success"))) { logger.error("QMS-SaleOrder-error,result[" + resultObj.toJSONString() + "]"); diff --git a/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java b/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java index 1d84ac29..fb30851f 100644 --- a/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java +++ b/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java @@ -170,7 +170,7 @@ public class ApproveSaleOrderAction { // 在审批后推送到QMS系统 processer.addAfterRule(new AfterApprovingSynchronizeRuleQMS()); // 在审批后推送到高压MES - processer.addAfterRule(new AfterSoSyncRuleGyMes()); + processer.addAfterRule(new AfterSoSyncRuleGyMes()); } private boolean isExistDelivery(String ctranstype) { diff --git a/uapbd/src/private/nc/bs/uapbd/task/MaterialOutGyImsPlugin.java b/uapbd/src/private/nc/bs/uapbd/task/MaterialOutGyImsPlugin.java new file mode 100644 index 00000000..cb455a14 --- /dev/null +++ b/uapbd/src/private/nc/bs/uapbd/task/MaterialOutGyImsPlugin.java @@ -0,0 +1,258 @@ +package nc.bs.uapbd.task; + +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.bs.logging.Logger; +import nc.bs.pub.pa.PreAlertObject; +import nc.bs.pub.taskcenter.BgWorkingContext; +import nc.bs.pub.taskcenter.IBackgroundWorkPlugin; +import nc.bs.uapbd.util.MyHelper; +import nc.itf.mmpac.pickm.IPickmQueryService; +import nc.itf.uap.pf.busiflow.PfButtonClickContext; +import nc.jdbc.framework.JdbcSession; +import nc.jdbc.framework.PersistenceManager; +import nc.jdbc.framework.exception.DbException; +import nc.jdbc.framework.processor.MapListProcessor; +import nc.pubitf.ic.m4d.api.IMaterialOutMaintainAPI; +import nc.util.mmf.busi.service.PFPubService; +import nc.util.mmf.framework.base.MMValueCheck; +import nc.vo.bd.material.MaterialVO; +import nc.vo.fi.pub.SqlUtils; +import nc.vo.ic.m4d.entity.MaterialOutBodyVO; +import nc.vo.ic.m4d.entity.MaterialOutHeadVO; +import nc.vo.ic.m4d.entity.MaterialOutVO; +import nc.vo.mmpac.pickm.entity.AggPickmVO; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDate; +import nc.vo.pub.lang.UFDateTime; +import nc.vo.pub.lang.UFDouble; +import nc.vo.scmpub.res.billtype.ICBillType; +import nc.vo.scmpub.res.billtype.MMBillType; +import nccloud.baseapp.core.log.NCCForUAPLogger; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 定时同步高压加工车间IMS的材料出库 + * + * @author mzr + * @date 20250930 + */ +public class MaterialOutGyImsPlugin implements IBackgroundWorkPlugin { + + private static final String LOG_INFO_NAME = "gymeslog"; + private static final Log logger = Log.getInstance(LOG_INFO_NAME); + + private SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd"); + private SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // BIP数据源 + public static final BaseDAO baseDAO = new BaseDAO(); + // IMS数据源 + public BaseDAO imsDao; + + /** + * 获取IMS数据源 + */ + public BaseDAO getImsDao() { + if (imsDao == null) { + imsDao = new BaseDAO("gyims"); + // 禁用时间戳ts + imsDao.setAddTimeStamp(false); + } + return imsDao; + } + + @Override + public PreAlertObject executeTask(BgWorkingContext arg0) { + Logger.error("---start----任务开始运行--"); + try { + IPickmQueryService queryService = NCLocator.getInstance().lookup(IPickmQueryService.class); + // IMS 同步状态:BIP:C-创建;U-修改D-删除 IMS:2-MES单据接收完成 + String selSql = "select * from BIPOutMainTab where status != '2'"; + List> mainList = (List>) getImsDao().executeQuery(selSql, new MapListProcessor()); + Set imsIdSet = new HashSet<>(); + for (Map mainMap : mainList) { + String cgeneralhid = mainMap.get("cgeneralhid") + ""; + try { + String pkSql = "select * from BIPOutDetailTab where cgeneralhid = '" + cgeneralhid + "'"; + List> detailList = (List>) getImsDao().executeQuery(pkSql, new MapListProcessor()); + Map> detailIdMap = new HashMap<>(); + for (Map detailMap : detailList) { + detailIdMap.put(detailMap.get("vbdef17") + "", detailMap); + } + if (detailList.isEmpty()) { + continue; + } + String csourcebillhid = detailList.get(0).get("vbdef16") + "";// 备料计划主键 + // 查询备料计划的VO + AggPickmVO[] pickmVOS = queryService.queryBillsByPks(new String[]{csourcebillhid}); + // 调用单据转换规则转换出流程材料出库的VO + MaterialOutVO[] vos = (MaterialOutVO[]) PFPubService.runChangeData(MMBillType.PickMo.getCode(), ICBillType.MaterialOut.getCode(), + pickmVOS, null, PfButtonClickContext.ClassifyByItfdef); + if (MMValueCheck.isEmpty(vos)) { + continue; + } + // 设置行号 + setMaterialOutRowNum(vos); + // 根据IMS字段赋值 + for (MaterialOutVO vo : vos) { + MaterialOutHeadVO hvo = vo.getHead(); + MaterialOutBodyVO[] bodys = vo.getBodys(); + hvo.setVbillcode(mainMap.get("vbillcode") + ""); + hvo.setCreator("BIP"); + hvo.setBillmaker("BIP"); + hvo.setVtrantypecode("4D-01"); + if (mainMap.get("dmakedate") != null && mainMap.get("dmakedate") instanceof Timestamp dmakedate1) { + String dmakedateStr = DATE_FORMATTER.format(dmakedate1); + UFDate dmakedate = new UFDate(dmakedateStr); + hvo.setDmakedate(dmakedate); + } + if (mainMap.get("creationtime") != null && mainMap.get("creationtime") instanceof Timestamp creationtime1) { + String creationtimeStr = DATETIME_FORMATTER.format(creationtime1); + UFDateTime creationtime = new UFDateTime(creationtimeStr); + hvo.setCreationtime(creationtime); + } + for (MaterialOutBodyVO bvo : bodys) { + String getCsourcebillbid = bvo.getCsourcebillbid();// 备料计划明细id + Map detailMap = detailIdMap.get(getCsourcebillbid); + if (detailMap != null) { + // 物料或数量替换 + bvo.setNshouldnum(skipNullNum(detailMap.get("nshouldnum"), bvo.getNshouldnum()));// 应发主数量 + bvo.setNshouldassistnum(skipNullNum(detailMap.get("nshouldassistnum"), bvo.getNshouldassistnum()));// 应发数量 + bvo.setNnum(skipNullNum(detailMap.get("nnum"), bvo.getNnum()));// 实发主数量 + bvo.setNassistnum(skipNullNum(detailMap.get("nassistnum"), bvo.getNassistnum()));// 实发数量 + // 如果物料不相等,则BIP物料替换为IMS物料 + String cmaterialvid = bvo.getCmaterialvid(); + String goodsCode = detailMap.get("cmaterialvid") + ""; + String whereSql = MaterialVO.CODE + " = '" + goodsCode + "'" + " and pk_org = '" + hvo.getPk_org() + "'"; + String goodsId = MyHelper.getStrValByCondition(MaterialVO.getDefaultTableName(), MaterialVO.PK_MATERIAL, + whereSql); + if (!cmaterialvid.equals(goodsId)) { + bvo.setCmaterialvid(goodsId); + } + } + } + } + IMaterialOutMaintainAPI materialOut = NCLocator.getInstance().lookup(IMaterialOutMaintainAPI.class); + MaterialOutVO[] resultvos = materialOut.insertBills(vos); + if (MMValueCheck.isEmpty(resultvos)) { + continue; + } + imsIdSet.add(cgeneralhid); + } catch (BusinessException e) { + Logger.error("MaterialOutGyImsPlugin Error: ", e); + NCCForUAPLogger.debug("MaterialOutGyImsPlugin Error: " + e.getMessage()); + String updateSql = "update BIPOutMainTab set err_msg = '[err_msg]' where cgeneralhid = '[cgeneralhid]'"; + updateSql = updateSql.replace("[err_msg]", e.getMessage()); + updateSql = updateSql.replace("[cgeneralhid]", cgeneralhid); + NCCForUAPLogger.debug("MaterialOutGyImsPlugin-updateSql = " + updateSql); + int rows = executeUpdate(updateSql, cgeneralhid); + NCCForUAPLogger.debug("MaterialOutGyImsPlugin-rows = " + rows); + } + } + if (!imsIdSet.isEmpty()) { + // 修改状态为 完成 + String inSql = SqlUtils.getInStr("cgeneralhid", imsIdSet.toArray(new String[0]), Boolean.TRUE); + String updateSql = "update BIPOutMainTab set status = '2',err_msg = null where " + inSql; + executeUpdate(updateSql, imsIdSet.toString()); + } + Logger.error("---end----任务结束运行--"); + } catch (Exception e) { + Logger.error("MaterialOutGyImsPlugin Error: ", e); + NCCForUAPLogger.debug("MaterialOutGyImsPlugin Error: " + e.getMessage()); + } + return null; + } + + private UFDouble skipNullNum(Object value, UFDouble num) { + if (value instanceof BigDecimal) { + return new UFDouble((BigDecimal) value); + } + if (num != null) { + return num; + } + return UFDouble.ZERO_DBL; + } + + private void setMaterialOutRowNum(MaterialOutVO[] vos) { + for (int i = 0; i < vos.length; i++) { + MaterialOutVO vo = vos[i]; + MaterialOutBodyVO[] bodys = vo.getBodys(); + if (bodys != null && bodys.length > 0) { + for (int j = 0; j < bodys.length; j++) { + MaterialOutBodyVO body = bodys[j]; + body.setCrowno(String.valueOf((j + 1) * 10)); + } + } + } + } + + private int executeUpdate(String sql, String targetId) throws BusinessException { + + // 2. 直接通过静态工厂方法获取 PersistenceManager + PersistenceManager pm = null; + JdbcSession jdbcSession = null; + Connection conn = null; + int rows = 0; + try { + // 直接调用 PersistenceManager 的静态方法 getInstance() + pm = PersistenceManager.getInstance("gyims"); + pm.setAddTimeStamp(false);// 不添加时间戳ts + + // 2.1 获取 JdbcSession 和 Connection + jdbcSession = pm.getJdbcSession(); + jdbcSession.setSQLTranslator(true); // 保持 SQL 转换 + conn = jdbcSession.getConnection(); + conn.setAutoCommit(false); + logger.info("直接获取PersistenceManager,手动事务开启,targetId:" + targetId); + + // 4. 执行主表+子表操作 (传入共享的 pm) + logger.info("事务内执行更新,targetId:" + targetId); + rows = pm.getJdbcSession().executeUpdate(sql); + logger.info("事务内执行更新,rows:" + rows); + logger.info("事务内操作全部成功,准备提交,targetId:" + targetId); + + } catch (DbException | SQLException e) { // 捕获 DbException 和 SQLException + logger.error("事务执行失败,触发回滚,targetId:" + targetId); + if (conn != null) { + try { + conn.rollback(); + logger.info("事务回滚完成,targetId:" + targetId); + } catch (SQLException rollbackE) { + logger.error("事务回滚异常,targetId:" + targetId); + } + } + throw new BusinessException("备料计划同步事务失败:" + e.getMessage(), e); + + } finally { + if (conn != null) { + try { + conn.commit(); + logger.info("事务提交成功,targetId:" + targetId); + // 恢复自动提交模式,确保不会影响其他操作 + conn.setAutoCommit(true); + } catch (SQLException commitE) { + logger.error("事务提交异常,targetId:" + targetId); + } + } + // 5. 释放 PersistenceManager (至关重要) + if (pm != null) { + try { + pm.release(); // 必须调用 release() 将连接归还给连接池 + logger.info("PersistenceManager 释放完成,targetId:" + targetId); + } catch (Exception releaseE) { + logger.error("PersistenceManager 释放异常", releaseE); + } + } + } + return rows; + } + + +} diff --git a/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToQmsListener.java b/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToQmsListener.java index 28020a25..e2403d88 100644 --- a/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToQmsListener.java +++ b/uapbd/src/private/nccloud/api/uapbd/material/listener/MaterialToQmsListener.java @@ -43,14 +43,8 @@ public class MaterialToQmsListener implements IBusinessListener { Object[] objs = e.getObjs(); // EventType是事件编码 1002-新增后 1004-修改后 1071-状态由停用变为启用后 1069-状态由启用变为停用后 - if ("1004".equals(eventType)) { - MaterialVO[] useVOs = ArrayClassConvertUtil.convert(objs, MaterialVO.class); - configParams = MyHelper.getConfigParams("xb-config", null); - if (configParams.isEmpty()) { - throw new BusinessException("箱变的QMS接口缺少配置"); - } - buildSyncData(useVOs, eventType); - } else if ("1071".equals(eventType) || "1069".equals(eventType)) { + if ("1002".equals(eventType) || "1004".equals(eventType) + || "1071".equals(eventType) || "1069".equals(eventType)) { MaterialVO[] useVOs = ArrayClassConvertUtil.convert(objs, MaterialVO.class); configParams = MyHelper.getConfigParams("xb-config", null); if (configParams.isEmpty()) {