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..762a39d0 --- /dev/null +++ b/uapbd/src/private/nc/bs/uapbd/task/MaterialOutGyImsPlugin.java @@ -0,0 +1,261 @@ +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); + } + if ("0".equals(bvo.getVbatchcode())) { + bvo.setVbatchcode(null); + } + } + } + } + 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; + } + + +}