diff --git a/nflg-wms-srm-receive/lib/libsapjco3.dylib b/nflg-wms-srm-receive/lib/libsapjco3.dylib new file mode 100644 index 00000000..beca27fa Binary files /dev/null and b/nflg-wms-srm-receive/lib/libsapjco3.dylib differ diff --git a/nflg-wms-srm-receive/lib/libsapjco3.so b/nflg-wms-srm-receive/lib/libsapjco3.so new file mode 100644 index 00000000..bc9b9b28 Binary files /dev/null and b/nflg-wms-srm-receive/lib/libsapjco3.so differ diff --git a/nflg-wms-srm-receive/lib/sapidoc3.jar b/nflg-wms-srm-receive/lib/sapidoc3.jar new file mode 100644 index 00000000..6b0b3021 Binary files /dev/null and b/nflg-wms-srm-receive/lib/sapidoc3.jar differ diff --git a/nflg-wms-srm-receive/lib/sapjco3.dll b/nflg-wms-srm-receive/lib/sapjco3.dll new file mode 100644 index 00000000..9f10d635 Binary files /dev/null and b/nflg-wms-srm-receive/lib/sapjco3.dll differ diff --git a/nflg-wms-srm-receive/lib/sapjco3.jar b/nflg-wms-srm-receive/lib/sapjco3.jar new file mode 100644 index 00000000..25645299 Binary files /dev/null and b/nflg-wms-srm-receive/lib/sapjco3.jar differ diff --git a/nflg-wms-srm-receive/lib/sapjcomanifest.mf b/nflg-wms-srm-receive/lib/sapjcomanifest.mf new file mode 100644 index 00000000..345a925c --- /dev/null +++ b/nflg-wms-srm-receive/lib/sapjcomanifest.mf @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 + +keyname: SAP JCO +keyvendor: sap.com +keylocation: SAP SE + +sapjco release: 3.1 +sapjco patch level: 12 +sapjco os: darwinarm64 diff --git a/nflg-wms-srm-receive/pom.xml b/nflg-wms-srm-receive/pom.xml index 6d30d596..8da2076c 100644 --- a/nflg-wms-srm-receive/pom.xml +++ b/nflg-wms-srm-receive/pom.xml @@ -38,6 +38,13 @@ org.springframework.boot spring-boot-starter-actuator + + com.sap.conn.jco + sapjco3 + 3.1.12 + system + ${project.basedir}/lib/sapjco3.jar + com.jcraft jsch @@ -55,6 +62,32 @@ true + + org.apache.maven.plugins + maven-resources-plugin + + + copy-external-libs + process-resources + + copy-resources + + + + + + ${project.basedir}/lib + false + + + + ${project.build.directory}/lib + + true + + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/config/SAPConfig.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/config/SAPConfig.java new file mode 100644 index 00000000..bb7571de --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/config/SAPConfig.java @@ -0,0 +1,119 @@ +package com.nflg.wms.srm.receive.config; + +import com.sap.conn.jco.JCoDestination; +import com.sap.conn.jco.JCoDestinationManager; +import com.sap.conn.jco.JCoException; +import com.sap.conn.jco.JCoRepository; +import com.sap.conn.jco.ext.DestinationDataEventListener; +import com.sap.conn.jco.ext.DestinationDataProvider; +import com.sap.conn.jco.ext.Environment; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +@Slf4j +@Configuration +public class SAPConfig { + + public static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL"; + private final String sapHost; + private final String sapSysnr; + private final String sapClient; + private final String sapUsername; + private final String sapPassword; + private final String sapLang; + private final String sapPool; + private String sapPeak; + + public SAPConfig( + @Value("${custom.sap.host}") String sapHost, + @Value("${custom.sap.sysnr}") String sapSysnr, + @Value("${custom.sap.client}") String sapClient, + @Value("${custom.sap.username}") String sapUsername, + @Value("${custom.sap.password}") String sapPassword, + @Value("${custom.sap.lang}") String sapLang, + @Value("${custom.sap.pool}") String sapPool, + @Value("${custom.sap.peak}") String sapPeak + ) { + this.sapHost = sapHost; + this.sapSysnr = sapSysnr; + this.sapClient = sapClient; + this.sapUsername = sapUsername; + this.sapPassword = sapPassword; + this.sapLang = sapLang; + this.sapPool = sapPool; + this.sapPeak = sapPeak; + } + + @PostConstruct + public void initDestination() { + try { + // 验证连接池配置有效性 + validatePoolConfig(); + // 直接注册到JCo内存环境(避免文件IO) + Environment.registerDestinationDataProvider(new SimpleDestinationDataProvider(ABAP_AS_POOLED, buildConnectionProperties())); + } catch (Exception e) { + log.error("SAP JCo目的地初始化失败", e); + throw new IllegalStateException("SAP JCo配置初始化失败", e); + } + } + + private Properties buildConnectionProperties() { + Properties props = new Properties(); + props.setProperty(DestinationDataProvider.JCO_ASHOST, sapHost); + props.setProperty(DestinationDataProvider.JCO_SYSNR, sapSysnr); + props.setProperty(DestinationDataProvider.JCO_CLIENT, sapClient); + props.setProperty(DestinationDataProvider.JCO_USER, sapUsername); + props.setProperty(DestinationDataProvider.JCO_PASSWD, sapPassword); + props.setProperty(DestinationDataProvider.JCO_LANG, sapLang); + props.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, sapPeak); + props.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapPool); + return props; + } + // 连接池配置验证 + private void validatePoolConfig() { + try { + int peak = Integer.parseInt(sapPeak); + int pool = Integer.parseInt(sapPool); + if (peak < pool) { + log.warn("JCO_PEAK_LIMIT({}) 不应小于 JCO_POOL_CAPACITY({}),已自动修正", peak, pool); + sapPeak = sapPool; + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException("SAP连接池配置必须是数字"); + } + } + + @Bean(destroyMethod = "") + public JCoDestination jcoDestination() throws JCoException { + return JCoDestinationManager.getDestination(ABAP_AS_POOLED); + } + + @Bean + public JCoRepository getJCoRepository() throws JCoException { + return jcoDestination().getRepository(); + } + + private static class SimpleDestinationDataProvider implements DestinationDataProvider { + private final Map destinations = new HashMap<>(); + public SimpleDestinationDataProvider(String destName, Properties props) { + destinations.put(destName, props); + } + @Override + public Properties getDestinationProperties(String destinationName) { + return destinations.get(destinationName); + } + @Override + public void setDestinationDataEventListener(DestinationDataEventListener listener) {} + @Override + public boolean supportsEvents() { + return false; + } + } +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/SAPMaterialInfoInOrderDTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/SAPMaterialInfoInOrderDTO.java new file mode 100644 index 00000000..4e518268 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/SAPMaterialInfoInOrderDTO.java @@ -0,0 +1,120 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.nflg.wms.common.util.BomUtil; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +public class SAPMaterialInfoInOrderDTO { + + /** + * 未收货数量 + */ + @JsonProperty("WSHSL") + private BigDecimal transportNum; + + /** + * 仓库编号 + */ + @JsonProperty("LGORT") + private String warehouseNo; + + /** + * 采购凭证号 + */ + private String ebeln; + + /** + * 采购凭证行项目 + */ + private String ebelp; + + public String getEbelp() { + return StrUtil.removeAllPrefix(ebelp, "0"); + } + + /** + * 物料号 + */ + private String matnr; + + /** + * 物料描述 + */ + private String maktx; + + /** + * 标志:关键部件(是否质检) + */ + private String kzkri; + + /** + * 采购订单数量 + */ + private BigDecimal menge; + + /** + * 收货数量 + */ + + private BigDecimal wemng; + + /** + * 单位 + */ + private String meins; + + public String getMeins() { + return BomUtil.changeMeins(meins); + } + + /** + * 物料组 + */ + private String matkl; + + /** + * 物料描述描述 + */ + private String wgbez; + + /** + * 工厂 + */ + private String werks; + + /** + * 标识:基于收获的发票验证 + */ + private String webre; + + /** + * 打印参数 + */ + private String lbprt; + + /** + * 特性值 + */ + private String atwrt; + + /** + * 采购组 + */ + private String ekgrp; + + /** + * 订单类型 + */ + private String bsart; + + /** + * 供应商账号 + */ + private String lifnr; +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17DTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17DTO.java new file mode 100644 index 00000000..e0c7aca9 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17DTO.java @@ -0,0 +1,26 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.List; + +@Data +@Accessors(chain = true) +public class ZWM3A17DTO { + + /** + * 采购凭证号 + */ + private String ebeln; + + /** + * 用户名 + */ + private String usnam; + + private List item1 = new ArrayList<>(); + + private List item2 = new ArrayList<>(); +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item1DTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item1DTO.java new file mode 100644 index 00000000..17894f30 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item1DTO.java @@ -0,0 +1,56 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import com.nflg.wms.common.util.BomUtil; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +public class ZWM3A17Item1DTO { + + /** + * 采购凭证的项目编号 + */ + private String EBELP; + + /** + * 物料号 + */ + private String MATNR; + + /** + * 以输入单位计的数量 + */ + private BigDecimal ERFMG; + + /** + * 基本计量单位 + */ + private String MEINS; + + public String getMeins() { + return BomUtil.changeMeins(MEINS); + } + + /** + * 批号 + */ + private String CHARG; + + /** + * 工厂 + */ + private String WERKS; + + /** + * 库存地点 + */ + private String LGORT; + + /** + * 标志:关键部件 + */ + private String KZKRI; +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item2DTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item2DTO.java new file mode 100644 index 00000000..00cbee2d --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A17Item2DTO.java @@ -0,0 +1,24 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class ZWM3A17Item2DTO { + + /** + * 采购凭证的项目编号 + */ + private String EBELP; + + /** + * 序列号 + */ + private String SERNR; + + /** + * 标志,X表示合格品,空表示不合格品 + */ + private String FLAG; +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18DTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18DTO.java new file mode 100644 index 00000000..c3f6c745 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18DTO.java @@ -0,0 +1,35 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +public class ZWM3A18DTO { + + /** + * 采购凭证号 + */ + private String ebeln; + + /** + * 用户名 + */ + private String usnam; + + /** + * 物料凭证编号 + */ + private String mblnr; + + /** + * 物料凭证年度 + */ + private String mjahr; + + private List item1; + + private List item2; +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18Item1DTO.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18Item1DTO.java new file mode 100644 index 00000000..7c541f55 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/pojo/dto/ZWM3A18Item1DTO.java @@ -0,0 +1,66 @@ +package com.nflg.wms.srm.receive.pojo.dto; + +import com.nflg.wms.common.util.BomUtil; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +public class ZWM3A18Item1DTO { + + /** + * 报检数量 + */ + private BigDecimal erfmg; + + /** + * 质检合格数量 + */ + private BigDecimal erfmg1; + + /** + * 质检不合格数量 + */ + private BigDecimal erfmg2; + + /** + * 采购凭证的项目编号 + */ + private String ebelp; + + /** + * 物料号 + */ + private String matnr; + + /** + * 单位 + */ + private String meins; + + public String getMeins() { + return BomUtil.changeMeins(meins); + } + + /** + * 批号 + */ + private String charg; + + /** + * 库存地点 + */ + private String lgort; + + /** + * 项目文本 + */ + private String sgtxt; + + /** + * 工厂 + */ + private String werks; +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/service/SapService.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/service/SapService.java new file mode 100644 index 00000000..41548974 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/service/SapService.java @@ -0,0 +1,1539 @@ +package com.nflg.wms.srm.receive.service; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Pair; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.nflg.wms.common.constant.STATE; +import com.nflg.wms.common.exception.SAPException; +import com.nflg.wms.common.pojo.dto.*; +import com.nflg.wms.common.pojo.qo.*; +import com.nflg.wms.common.pojo.vo.*; +import com.nflg.wms.common.util.DateTimeUtil; +import com.nflg.wms.common.util.UserUtil; +import com.nflg.wms.common.util.VUtil; +import com.nflg.wms.srm.receive.pojo.dto.SAPMaterialInfoInOrderDTO; +import com.nflg.wms.srm.receive.pojo.dto.ZWM3A17DTO; +import com.nflg.wms.srm.receive.pojo.dto.ZWM3A18DTO; +import com.nflg.wms.srm.receive.util.JCoUtil; +import com.sap.conn.jco.*; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Component +public class SapService { + + @Resource + private JCoDestination destination; + + @Resource + private JCoRepository repository; + + /** + * 生产订单副产品(拆解)入库过账 + */ + public Pair zwm3a22(ZWM3A22QO request) { + Map parameters = new HashMap<>(); + parameters.put("AUFNR", request.getAufnr()); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(request.getInput1())) { + if (CollectionUtil.isNotEmpty(request.getInput1())) { + tables.put("INPUT1", JCoUtil.toMapList(request.getInput1())); + } + } + if (CollectionUtil.isNotEmpty(request.getInput2())) { + if (CollectionUtil.isNotEmpty(request.getInput2())) { + tables.put("INPUT2", JCoUtil.toMapList(request.getInput2())); + } + } + + JCoFunction function = exec("ZWM3A22", parameters, tables); + + JCoStructure result = function.getExportParameterList().getStructure("OUTPUT1"); + VUtil.trueThrowBusinessError(!StrUtil.equals("S", result.getString("TYPE"))) + .throwMessage("SAP:" + result.getString("MSG")); + + return Pair.of(result.getString("MAT_DOC"), result.getString("DOC_YEAR")); + } + + /** + * 生产订单副产品(拆解)入库查询 + */ + public List zwm3a23(ZWM3A23QO request) { + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", request.getWerks()); + if (Objects.nonNull(request.getStartDate())) { + parameters.put("S_DATE", DateTimeUtil.format(request.getStartDate(), "yyyyMMdd")); + } + if (Objects.nonNull(request.getEndDate())) { + parameters.put("E_DATE", DateTimeUtil.format(request.getEndDate(), "yyyyMMdd")); + } + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(request.getArbpls())) { + List> list = new ArrayList<>(); + request.getArbpls().forEach(item -> { + list.add(Map.of("ARBPL", item)); + }); + tables.put("I_ARBPL", list); + } + if (CollectionUtil.isNotEmpty(request.getAufnrs())) { + List> list = new ArrayList<>(); + request.getAufnrs().forEach(item -> { + list.add(Map.of("AUFNR", item)); + }); + tables.put("I_AUFNR", list); + } + if (CollectionUtil.isNotEmpty(request.getWarehouseNos())) { + List> list = new ArrayList<>(); + request.getWarehouseNos().forEach(item -> { + list.add(Map.of("LGORT", item)); + }); + tables.put("I_LGORT", list); + } + + JCoFunction function = exec("ZWM3A23", parameters, tables); + + VUtil.trueThrowBusinessError(!StrUtil.equals("S", function.getExportParameterList().getString("E_TYPE"))) + .throwMessage("SAP:" + function.getExportParameterList().getString("E_MSG")); + + JCoTable table = function.getTableParameterList().getTable("OUTPUT1"); + return JCoUtil.toBeanList(table, ZWM3A23VO.class); + } + + public ZWM00_MB116VO zwm00_mb116(ZWM00_MB116QO request) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", request.getEbeln()); + parameters.put("I_USNAM", request.getUsnam()); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(request.getList1())) { + tables.put("T_LIST1", JCoUtil.toMapList(request.getList1())); + } + if (CollectionUtil.isNotEmpty(request.getList2())) { + tables.put("T_LIST2", JCoUtil.toMapList(request.getList2())); + } + + JCoFunction function = exec("ZWM00_MB116", parameters, tables); + + JCoTable jtr = function.getTableParameterList().getTable("T_RETURN"); + List lrs = JCoUtil.toBeanList(jtr, ZWM00_MB116ReturnVO.class); + List errors = lrs.stream().filter(lr -> !StrUtil.equals(lr.getType(), "S")) + .map(ZWM00_MB116ReturnVO::getMessage) + .toList(); + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(errors)).throwMessage("SAP:" + StrUtil.join(",", errors)); + + return new ZWM00_MB116VO() + .setMblnr(function.getExportParameterList().getString("E_MBLNR")) + .setMjahr(function.getExportParameterList().getString("E_MJAHR")); + } + + /** + * 生产订单查询 + * @param no 生产订单号 + */ + public ZWM00MB007DTO zwm00Mb007(String no) { + Map parameters = new HashMap<>(); + parameters.put("I_AUFNR", no); + + JCoFunction function = exec("ZWM00_MB007", parameters); + + JCoStructure eReturn = function.getExportParameterList().getStructure("E_RETURN"); + print("E_RETURN", eReturn); + JCoStructure eOutput = function.getExportParameterList().getStructure("E_OUTPUT"); + print("E_OUTPUT", eOutput); + + ZWM00MB007DTO dto = JCoUtil.toBean(eOutput, ZWM00MB007DTO.class); + if (StrUtil.isBlank(dto.getAufnr())) { + VUtil.trueThrowBusinessError(!StrUtil.equals(eReturn.getString("TYPE"), "S")) + .throwMessage("SAP:" + eReturn.getString("MESSAGE")); + return null; + } + return dto; + } + + /** + * 生产订单收货 + * @param no 生产订单号 + * @param userName 用户名 + * @param materials 入库物料列表 + * @param sernrs 序列号列表 + */ + public Zwm00Mb107DTO zwm00_mb107(String no, String userName, List materials, List sernrs) { + Map parameters = new HashMap<>(); + parameters.put("I_AUFNR", no); + parameters.put("I_USNAM", userName); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(materials)) { + tables.put("T_LIST1", JCoUtil.toMapList(materials)); + } + + if (CollectionUtil.isNotEmpty(sernrs)) { + List> list2 = new ArrayList<>(); + sernrs.forEach(item -> { + list2.add(Map.of("SERNR", item)); + }); + tables.put("T_LIST2", list2); + } + + JCoFunction function = exec("ZWM00_MB107", parameters, tables); + + JCoParameterList pl = function.getExportParameterList(); + log.info("E_MBLNR:{}", pl.getString("E_MBLNR")); + VUtil.trueThrowBusinessError(StrUtil.isBlank(pl.getString("E_MBLNR"))) + .throwMessage("SAP"); + VUtil.trueHandle(StrUtil.isBlank(pl.getString("E_MBLNR"))).trueHandle(() -> { + JCoTable table = function.getTableParameterList().getTable("T_RETURN"); + log.error("SAP错误信息:{}", table); + }); + + return JCoUtil.toBean(pl, Zwm00Mb107DTO.class); + } + + /** + * 查询采购单退库信息 + */ + public ZWM3A05VO zwm3A05(zwm3A05QO qo) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", qo.getEbeln()); + parameters.put("I_LIFNR", qo.getLifnr()); + parameters.put("I_MATNR", qo.getMatnr()); + + JCoFunction function = exec("ZWM3A05", parameters, null); + + JCoStructure structure = function.getExportParameterList().getStructure("E_RETURN"); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("MSG")); + + JCoTable ot1 = function.getTableParameterList().getTable("OUTPUT1"); + VUtil.trueThrowBusinessError(ot1.getNumRows() == 0).throwMessage("没有订单数据"); + ot1.setRow(0); + ZWM3A05VO vo = new ZWM3A05VO() + .setEbeln(ot1.getString("EBELN")) + .setLifnr(ot1.getString("LIFNR")) + .setWerks(ot1.getString("WERKS")); + vo.setItems(JCoUtil.toBeanList(ot1, ZWM3A05ItemVO.class)); + + JCoTable ot2 = function.getTableParameterList().getTable("OUTPUT2"); + while (ot2.nextRow()) { + ZWM3A05ItemVO item = vo.getItems().stream() + .filter(it -> StrUtil.equals(it.getEbelp(), ot2.getString("EBELP")) && StrUtil.equals(it.getLfpos(), ot2.getString("LFPOS"))) + .findFirst() + .get(); + item.getSernrs().add(ot2.getString("SERNR")); + } + if (StrUtil.isNotBlank(qo.getEbelp())) { + vo.getItems().removeIf(it -> !StrUtil.equals(it.getEbelp(), qo.getEbelp())); + } + + log.debug("数据:{}", JSONUtil.toJsonStr(vo)); + return vo; + } + + public Pair zwm3A06(String ebeln, List input1, List input2) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", ebeln); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(input1)) { + tables.put("INPUT1", JCoUtil.toMapList(input1)); + } + if (CollectionUtil.isNotEmpty(input2)) { + tables.put("INPUT2", JCoUtil.toMapList(input2)); + } + + JCoParameterList jparameters = execReturnParameter("ZWM3A06", parameters, tables); + JCoStructure structure = jparameters.getStructure("OUTPUT"); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("MSG")); + + return Pair.of(structure.getString("MAT_DOC"), structure.getString("DOC_YEAR")); + } + + /** + * 扫码质检入库 + * @param dto 数据 + */ + public Pair zwm3a18(ZWM3A18DTO dto) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", dto.getEbeln()); + parameters.put("I_MBLNR", dto.getMblnr()); + parameters.put("I_MJAHR", dto.getMjahr()); + parameters.put("I_USNAM", dto.getUsnam()); + + Map>> tables = new HashMap<>(); + tables.put("T_LIST1", JCoUtil.toMapList(dto.getItem1())); + + if (CollectionUtil.isNotEmpty(dto.getItem2())) { + tables.put("T_LIST2", JCoUtil.toMapList(dto.getItem2())); + } + + JCoFunction function = exec("ZWM3A18", parameters, tables); + JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT1"); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("MSG")); + return Pair.of(structure.getString("MAT_DOC"), structure.getString("DOC_YEAR")); + } + + /** + * 扫码入库 + * @param dto 数据 + */ + public Pair, Pair> zwm3a17(ZWM3A17DTO dto) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", dto.getEbeln()); + parameters.put("I_USNAM", dto.getUsnam()); + + Map>> tables = new HashMap<>(); + tables.put("T_LIST1", JCoUtil.toMapList(dto.getItem1())); + + if (CollectionUtil.isNotEmpty(dto.getItem2())) { + tables.put("T_LIST2", JCoUtil.toMapList(dto.getItem2())); + } + + JCoFunction function = exec("ZWM3A17", parameters, tables); + JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT1"); + print("OUTPUT1", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("MSG")); + + return Pair.of(Pair.of(structure.getString("MAT_DOC_101"), structure.getString("DOC_YEAR_101")) + , Pair.of(structure.getString("MAT_DOC_103"), structure.getString("DOC_YEAR_103"))); + } + +// /** +// * 保存库位 +// * @param factory 工厂编号 +// * @param materialNo 物料编号 +// * @param warehouseNo 仓库编号 +// * @param binNos 储位编号列表 +// */ +// public void zwm3A02(String factory, String materialNo, String warehouseNo, Collection binNos) { +// Map>> tables = new HashMap<>(); +// Map item = new HashMap<>(); +// item.put("WERKS", factory); +// item.put("MATNR", materialNo); +// item.put("LGORT", warehouseNo); +// item.put("LGPBE", StrUtil.join("/", binNos)); +// tables.put("T_OUT", List.of(item)); +// +// JCoFunction function = exec("ZWM3A02", null, tables); +// +// JCoTable table = function.getTableParameterList().getTable("T_OUT"); +// List> tOut = JCoUtil.toMapList(table); +// VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(tOut)).throwMessage("SAP未返回结果"); +// VUtil.trueThrowBusinessError(!StrUtil.equals(tOut.get(0).get("E_TYPE").toString(), "S")) +// .throwMessage("SAP:" + tOut.get(0).get("E_MSG")); +// } + +// /** +// * 获取库存信息 +// * @param factory 工厂编号 +// * @param warehouseNo 仓库编号 +// * @param materialNo 物料编号 +// */ +// public SAPSyncFromDTO zwm3A01(String factory, String warehouseNo, String materialNo) { +// return zwm3A01(factory, Collections.singletonList(warehouseNo), Collections.singletonList(materialNo), null, null) +// .stream().findFirst().orElse(null); +// } + +// /** +// * 获取库存信息 +// * @param factory 工厂编号 +// * @param warehouseNos 仓库编号列表 +// * @param beginTime 开始时间,格式yyyyMMdd +// * @param endTime 结束时间,格式yyyyMMdd +// */ +// public List zwm3A01(String factory, List warehouseNos, List materialNos, String beginTime, String endTime) { +// Map parameters = new HashMap<>(); +// parameters.put("I_WERKS", factory); +// parameters.put("I_TYPE", Objects.nonNull(beginTime) || Objects.nonNull(endTime) ? "I" : "A"); +// if (Objects.nonNull(beginTime)) { +// parameters.put("S_DATE", beginTime); +// } +// if (Objects.nonNull(endTime)) { +// parameters.put("E_DATE", endTime); +// } +// +// Map>> tables = new HashMap<>(); +// List> warehouses = new ArrayList<>(); +// warehouseNos.forEach(warehouseNo -> { +// warehouses.add(Map.of("LGORT", warehouseNo)); +// }); +// tables.put("IT_LGORT", warehouses); +// List> materials = new ArrayList<>(); +// materialNos.forEach(materialNo -> { +// materials.add(Map.of("MATNR", materialNo)); +// }); +// tables.put("IT_MATNR", materials); +// +// JCoTable tOut = execReturnTable("ZWM3A01", parameters, tables); +// +// List result = JCoUtil.toBeanList(tOut, SAPSyncFromDTO.class); +// log.debug("数据:{}", JSONUtil.toJsonStr(result)); +// return result; +// } + + /** + * 获取订单信息 + * @param orderNo 采购单号 + * @param supplierNo 供应商编号 + * @param materialNo 物料编号 + */ + public List zim004(String orderNo, String supplierNo, String materialNo) { + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", orderNo); + parameters.put("I_LIFNR", supplierNo); + parameters.put("I_MATNR", materialNo); + + JCoFunction function = exec("ZIM_004", parameters); + + JCoStructure structure = function.getExportParameterList().getStructure("E_RETURN"); + VUtil.trueThrow(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage(STATE.SAPErr, "SAP:" + structure.getString("MSG")); + + JCoTable table = function.getTableParameterList().getTable("T_OUT"); + log.trace("SAP返回: {}", table); + List datas = JCoUtil.toBeanList(table, SAPMaterialInfoInOrderDTO.class); + log.debug("数据:{}", JSONUtil.toJsonStr(datas)); + return datas; + } + +// /** +// * 搜索订单 +// * +// * @param supplierNo 供应商编码 +// */ +// public List searchOrder(String supplierNo) { +// Map parameters = new HashMap<>(); +// parameters.put("I_LIFNR", supplierNo); +// +// JCoTable tOut = execReturnTable("ZRFC_MM_SMXT", parameters, null, "T_SMXTOUT"); +// List result = JCoUtil.toBeanList(tOut, SAPOrderDTO.class); +// log.debug("数据:{}", JSONUtil.toJsonStr(result)); +// return result; +// } + + /** + * 成本中心退库查询 + * 根据退库单号查询物料退库信息 + * @param resebRsNum 退库单号 + * @return 预留单号 + */ + public List zwm00_MB017(String resebRsNum) { + Map parameters = new HashMap<>(); + parameters.put("I_RSNUM", resebRsNum); + JCoFunction function = exec("ZWM00_MB017", parameters, null); + JCoTable tOut = function.getTableParameterList().getTable("T_OUT"); + List result = JCoUtil.toBeanList(tOut, C_MaterialReturnQueryDTO.class); + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 成本中心退库确认接口 + *

+ * 该方法用于调用 SAP 的 RFC 函数 ZWM00_MB112,执行成本中心物料退库操作。 + * 根据传入的请求参数构造输入表和字段,并处理返回结果。 + * @param request 请求参数对象,包含退库单据号、用户信息及物料明细等 + * @return C_MaterialReturnDTO 返回结果对象,包含生成的物料凭证号(MBLNR)和年度(MJAHR) + */ + public C_MaterialReturnDTO zwm00_MB112(C_MaterialReturnQO request) { + // 参数校验 + VUtil.trueThrowBusinessError(Objects.isNull(request)).throwMessage("请求参数不能为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getItems())).throwMessage("物料明细不能为空"); + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_RSNUM", request.getResbRsNum()); + parameters.put("I_USNAM", UserUtil.getUserName()); + + // 构造函数调用所需的输入表结构 T_LIST1 和 T_LIST2 + List> t_list1 = new ArrayList<>(); + List> t_list2 = new ArrayList<>(); + + // 遍历请求中的物料明细项,填充表数据 + request.getItems().forEach(item -> { + if (Objects.nonNull(item.getScanCodes()) && CollectionUtil.isNotEmpty(item.getScanCodes())) { + // 如果存在扫码信息,则按扫码记录逐条构造表数据 + item.getScanCodes().forEach(scanCode -> { + Map map = buildMb112TList1Map(item, scanCode.getCodeNum(), scanCode.getBatchNumber()); + t_list1.add(map); + Map map1 = buildMb112TList2Map(item.getResbRspos(), scanCode.getSerialNumbers()); + t_list2.add(map1); + }); + } else { + // 无扫码信息时,使用默认值构造表数据 + Map map = buildMb112TList1Map(item, item.getErfmg(), ""); + t_list1.add(map); + } + }); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(t_list1)) { + tables.put("T_LIST1", t_list1); + } + if (CollectionUtil.isNotEmpty(t_list2)) { + tables.put("T_LIST2", t_list2); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM00_MB112", parameters, tables); + + JCoParameterList parameterList = function.getExportParameterList(); + if (StrUtil.isBlank(parameterList.getString("E_MBLNR"))) { + JCoTable returnTable = function.getTableParameterList().getTable("T_RETURN"); + VUtil.trueThrowBusinessError(returnTable.getNumRows() <= 0).throwMessage("SAP未返回结果状态"); + returnTable.setRow(0); + VUtil.trueThrowBusinessError(StrUtil.equals(returnTable.getString("TYPE"), "E")) + .throwMessage(returnTable.getString("MESSAGE")); + return null; + } else { + C_MaterialReturnDTO result = new C_MaterialReturnDTO() + .setEMblnr(parameterList.getString("E_MBLNR")) + .setEMJahr(parameterList.getString("E_MJAHR")); + + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", result.getEMblnr(), result.getEMJahr()); + return result; + } + } + + + // 提取构造 T_LIST1 表项的方法 + private Map buildMb112TList1Map(C_MaterialReturnItemQO item, BigDecimal erFmg, String charg) { + Map map = new HashMap<>(8); // 预设容量避免频繁扩容 + map.put("RSPOS", item.getResbRspos()); + map.put("MATNR", item.getResbMatnr()); + map.put("ERFMG", erFmg); + map.put("MEINS", item.getResbMeins()); + map.put("WERKS", item.getResbWerks()); + map.put("LGORT", item.getResbLgort()); + map.put("CHARG", charg); + return map; + } + + // 提取构造 T_LIST2 表项的方法 + private Map buildMb112TList2Map(String rspos, String sernr) { + Map map = new HashMap<>(4); + map.put("RSPOS", rspos); + map.put("SERNR", sernr); + map.put("FLAG", "X"); + return map; + } + + /** + * 成本中心领料查询接口 + *

+ * 根据预留单号(resebRsNum)调用SAP的RFC函数ZWM00_MB026,查询对应的成本中心领料信息, + * 包括领料主记录和明细清单,并封装为C_MaterialOutboundQueryDTO对象返回。 + * @param resebRsNum 预留单号,不能为空 + * @return C_MaterialOutboundQueryDTO 领料查询结果数据传输对象,包含主信息和明细列表 + */ + public C_MaterialOutboundQueryDTO zwm00_MB026(String resebRsNum) { + // 参数校验 + VUtil.trueThrowBusinessError(resebRsNum == null || resebRsNum.isEmpty()).throwMessage("请求参数不能为空"); + Map parameters = new HashMap<>(); + parameters.put("I_KOSTL", resebRsNum); + JCoFunction function = exec("ZWM00_MB026", parameters, null); + + // 获取主信息表 T_OUT 并校验 + JCoTable tOut = function.getTableParameterList().getTable("T_OUT"); + VUtil.trueThrowBusinessError(tOut == null || tOut.getRow() <= 0).throwMessage("预留单号获取失败"); + tOut.setRow(0); + C_MaterialOutboundQueryDTO result = new C_MaterialOutboundQueryDTO() + .setResbRsnum(tOut.getString("RSNUM")) + .setWempf(tOut.getString("WEMPF")); + + // 获取领料清单表 T_LIST 并校验 + JCoTable tList = function.getTableParameterList().getTable("T_LIST"); + VUtil.trueThrowBusinessError(tList == null || tList.getRow() <= 0).throwMessage("领料清单获取失败"); + log.info("SAP返回领料清单: {}", tList); + + // 封装领料明细项列表 + List outboundItems = new ArrayList<>(); + for (int i = 0; i < tList.getNumRows(); i++) { + tList.setRow(i); + C_MaterialOutboundItemQueryDTO item = new C_MaterialOutboundItemQueryDTO() + .setResbRsnum(tList.getString("RSNUM")) + .setResbRspos(tList.getString("RSPOS")) + .setMaktx(tList.getString("MAKTX")) + .setResbMatnr(tList.getString("MATNR")) + .setWqyls(tList.getBigDecimal("WQYLS")) + .setResbWerks(tList.getString("WERKS")) + .setResbLgort(tList.getString("LGORT")) + .setResbMeins(tList.getString("MEINS")); + outboundItems.add(item); + } + + result.setItems(outboundItems); + return result; + } + + + /** + * 成本中心预留出库过账接口 + * 调用SAP RFC函数 ZWM00_MB115 执行物料出库操作。 + *

+ * 该方法首先校验请求参数中的物料明细是否为空,然后构造调用SAP所需的输入参数和表结构, + * 包括 T_LIST1 和 T_LIST2。根据是否存在扫码信息决定数据填充方式。 + * 最后调用SAP函数并处理返回结果,构造并返回出库凭证信息。 + * @param request 物料出库请求对象,包含预留号、用户信息及物料明细列表 + * @return C_MaterialOutboundDTO 出库操作成功后返回的物料凭证信息,包括物料凭证号(MBLNR)和年度(MJAHR) + */ + public C_MaterialOutboundDTO ZWM00_MB115(C_MaterialOutboundQO request) { + + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getItems())).throwMessage("物料明细不能为空"); + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_RSNUM", request.getResbRsNum()); + parameters.put("I_USNAM", UserUtil.getUserName()); + + // 构造函数调用所需的输入表结构 T_LIST1 和 T_LIST2 + List> t_list1 = new ArrayList<>(); + List> t_list2 = new ArrayList<>(); + + // 遍历请求中的物料明细项,填充表数据 + request.getItems().forEach(item -> { + if (Objects.nonNull(item.getScanCodes()) && CollectionUtil.isNotEmpty(item.getScanCodes())) { + // 如果存在扫码信息,则按扫码记录逐条构造表数据 + item.getScanCodes().forEach(scanCode -> { + Map map = buildMb115TList1Map(item, scanCode.getCodeNum(), scanCode.getBatchNumber()); + t_list1.add(map); + Map map1 = buildMb115TList2Map(item.getResbRspos(), scanCode.getSerialNumbers()); + t_list2.add(map1); + }); + } else { + // 无扫码信息时,使用默认值构造表数据 + Map map = buildMb115TList1Map(item, item.getQty(), ""); + t_list1.add(map); + } + }); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(t_list1)) { + tables.put("T_LIST1", t_list1); + } + if (CollectionUtil.isNotEmpty(t_list2)) { + tables.put("T_LIST2", t_list2); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM00_MB115", parameters, tables); + + // 处理返回表 T_RETURN,判断执行是否成功 + JCoTable returnTable = function.getTableParameterList().getTable("T_RETURN"); + log.info("SAP返回: {}", returnTable); + if (returnTable.getNumRows() > 0) { + returnTable.setRow(0); + VUtil.trueThrowBusinessError(!StrUtil.equals(returnTable.getString("TYPE"), "S")) + .throwMessage(returnTable.getString("MESSAGE")); + } + // 获取导出参数,构造返回结果对象 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + C_MaterialOutboundDTO result = new C_MaterialOutboundDTO() + .setEMblnr(exportParam.getString("E_MBLNR")) + .setEMJahr(exportParam.getString("E_MJAHR")); + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", result.getEMblnr(), result.getEMJahr()); + return result; + } + + + // 提取构造 T_LIST1 表项的方法 + private Map buildMb115TList1Map(C_MaterialOutboundItemQO item, BigDecimal erFmg, String charg) { + Map map = new HashMap<>(8); // 预设容量避免频繁扩容 + map.put("RSPOS", item.getResbRspos()); + map.put("MATNR", item.getResbMatnr()); + map.put("ERFMG", erFmg); + map.put("MEINS", item.getResbMeins()); + map.put("WERKS", item.getResbWerks()); + map.put("LGORT", item.getResbLgort()); + map.put("CHARG", charg); + return map; + } + + // 提取构造 T_LIST2 表项的方法 + private Map buildMb115TList2Map(String rspos, String sernr) { + Map map = new HashMap<>(4); + map.put("RSPOS", rspos); + map.put("SERNR", sernr); + map.put("FLAG", "X"); + return map; + } + + /** + * 生产领料单查询接口 + *

+ * 该方法用于调用SAP的RFC函数ZWM3A07,根据传入的查询条件获取生产领料单信息。 + * 查询条件包括工厂代码、工序、生产订单号和库存地点等。 + * 返回结果包含主表信息和明细项列表。 + * @param query 查询参数对象,包含工厂代码(必填)、工序列表、生产订单号列表、库存地点列表等 + * @return Zwm3a07VO 包含查询结果的VO对象,包括主表字段和明细项列表 + */ + //生产领料单查询接口 + public List zwm3a07(Zwm3a07QO query) { + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getI_werks()); + + Map>> tables = new HashMap<>(); + + // 构造工序参数表 I_ARBPL + if (CollectionUtil.isNotEmpty(query.getArbpl())) { + tables.put("I_ARBPL", query.getArbpl().stream().map(arbpl -> Map.of("ARBPL", (Object) arbpl)).toList()); + } + + // 构造生产订单号参数表 I_AUFNR + if (CollectionUtil.isNotEmpty(query.getAufnr())) { + tables.put("I_AUFNR", query.getAufnr().stream().map(aufnr -> Map.of("AUFNR", (Object) aufnr)).toList()); + } + + // 构造库存地点参数表 I_LGORT + if (CollectionUtil.isNotEmpty(query.getLgort())) { + tables.put("I_LGORT", query.getLgort().stream().map(lgort -> Map.of("LGORT", (Object) lgort)).toList()); + } + + // 调用SAP RFC函数 ZWM3A07 + JCoFunction function = exec("ZWM3A07", parameters, tables); + + // 获取输出表 OUTPUT1 并解析数据 + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + List result = JCoUtil.toBeanList(tOut, Zwm3a07VO.class); + + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + + /** + * 生成领料出库接口 + *

+ * 该方法用于调用 SAP 的 RFC 函数 ZWM3A10,执行领料出库操作。首先校验输入参数, + * 然后构造函数所需的输入参数和表数据,调用 SAP 接口,并处理返回结果。 + *

+ * @param query 查询参数对象,包含领料出库所需的信息,如订单号、物料明细等。 + * 不能为空,且至少包含一个物料明细项。 + * @return Zwm3a10VO 返回结果对象,包含生成的物料凭证号(MAT_DOC)和凭证年度(DOC_YEAR) + */ + //生成领料出库接口 + public Zwm3a10VO zwm3A10(Zwm3a10QO query) { + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(query.getInput1())).throwMessage("物料明细不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("AUFNR", query.getAufnr()); + parameters.put("I_TYPE", query.getType()); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + + // 构造 INPUT1 表数据:包含物料相关明细信息 + if (CollectionUtil.isNotEmpty(query.getInput1())) { + tables.put("INPUT1", JCoUtil.toMapList(query.getInput1())); + } + + // 构造 INPUT2 表数据:包含序列号相关信息 + if (CollectionUtil.isNotEmpty(query.getInput2())) { + tables.put("INPUT2", JCoUtil.toMapList(query.getInput2())); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A10", parameters, tables); + + JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT1"); + print("OUTPUT1", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage(structure.getString("MSG")); + + Zwm3a10VO result = new Zwm3a10VO() + .setMat_doc(structure.getString("MAT_DOC")) + .setDocYear(structure.getString("DOC_YEAR")); + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", result.getMat_doc(), result.getDocYear()); + return result; + } + + /** + * 生成补料单接口 + *

+ * 该方法用于调用 SAP 的 RFC 函数 ZWM3A08,根据传入的查询条件获取补料单数据。 + * 查询参数包括工厂代码、工序列表和生产订单号列表等。 + * @param query 查询参数对象,包含工厂代码(I_WERKS)、工序列表(I_ARBPL)和订单号列表(I_AUFNR)等字段 + * @return 返回封装后的补料单结果对象 Zwm3a08VO,包含主信息及明细项列表 + */ + public List zwm3a08(Zwm3a08QO query) { + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getI_werks()); + + Map>> tables = new HashMap<>(); + + // 封装工序列表参数 + if (CollectionUtil.isNotEmpty(query.getI_arbpl())) { + tables.put("I_ARBPL", query.getI_arbpl().stream().map(arbpl -> Map.of("ARBPL", (Object) arbpl)).toList()); + } + + // 封装订单号列表参数 + if (CollectionUtil.isNotEmpty(query.getI_aufnr())) { + tables.put("I_AUFNR", query.getI_aufnr().stream().map(aufnr -> Map.of("AUFNR", (Object) aufnr)).toList()); + } + + // 调用 SAP RFC 函数 + JCoFunction function = exec("ZWM3A08", parameters, tables); + + // 获取输出表 OUTPUT1 数据 + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + + // 构造并填充返回结果对象 + List result = JCoUtil.toBeanList(tOut, Zwm3a07VO.class); + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + + /** + * 生产退料单查询接口 + *

+ * 该方法用于调用SAP的RFC函数ZWM3A09,根据传入的查询条件获取生产退料单信息。 + * 查询条件包括工厂代码、工序列表和订单号列表等。 + * 返回结果包含主表信息和明细项列表。 + * @param query 查询参数对象,包含以下必填字段: + * - I_WERKS:工厂代码(不能为空) + * - I_ARBPL:工序列表(可选) + * - I_AUFNR:订单号列表(可选) + * @return Zwm3a09VO 查询结果对象,包含主表字段和明细项列表 + */ + public List zwm3a09(Zwm3a09QO query) { + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(query.getI_werks().isEmpty()).throwMessage("工厂代码不可以为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getI_werks()); + + Map>> tables = new HashMap<>(); + + // 构造工序列表参数 + if (CollectionUtil.isNotEmpty(query.getI_arbpl())) { + List> t_list1 = new ArrayList<>(); + query.getI_arbpl().forEach(arbpl -> { + t_list1.add(Map.of("ARBPL", arbpl)); + }); + tables.put("I_ARBPL", t_list1); + } + + // 构造订单号列表参数 + if (CollectionUtil.isNotEmpty(query.getI_aufnr())) { + List> t_list2 = new ArrayList<>(); + query.getI_aufnr().forEach(aufnr -> { + t_list2.add(Map.of("AUFNR", aufnr)); + }); + tables.put("I_AUFNR", t_list2); + } + + // 调用SAP RFC函数 + JCoFunction function = exec("ZWM3A09", parameters, tables); + + VUtil.trueThrowBusinessError(!StrUtil.equals(function.getExportParameterList().getString("E_TYPE"), "S")) + .throwMessage(function.getExportParameterList().getString("E_MSG")); + + // 处理返回的OUTPUT1表数据 + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + + List result = JCoUtil.toBeanList(tOut, Zwm3a09VO.class); + + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + + /** + * 生产退料单出库接口 + *

+ * 该方法用于调用 SAP 的 RFC 函数 ZWM3A11,执行生产退料单的出库操作。 + * 输入参数包括订单号、物料明细等信息,并根据 SAP 返回结果构造返回对象。 + *

+ * @param query 查询参数对象,包含订单号(AUFNR)及物料明细列表(INPUT1 和 INPUT2) + * @return Zwm3a11VO 包含物料凭证号(MAT_DOC)和凭证年度(DOC_YEAR)的结果对象 + */ + //生产退料单出库接口 + public Zwm3a11VO zwm3a11(Zwm3a11QO query) { + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(query.getInput1())).throwMessage("物料明细不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("AUFNR", query.getAufnr()); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getInput1())) { + tables.put("INPUT1", JCoUtil.toMapList(query.getInput1())); + } + + if (CollectionUtil.isNotEmpty(query.getInput2())) { + tables.put("INPUT2", JCoUtil.toMapList(query.getInput2())); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A11", parameters, tables); + + JCoStructure output1 = function.getExportParameterList().getStructure("OUTPUT1"); + VUtil.trueThrowBusinessError(!StrUtil.equals(output1.getString("TYPE"), "S")) + .throwMessage(output1.getString("MSG")); + + Zwm3a11VO result = new Zwm3a11VO() + .setMat_doc(output1.getString("MAT_DOC")) + .setDocYear(output1.getString("DOC_YEAR")); + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", result.getMat_doc(), result.getDocYear()); + return result; + } + + /** + * 委外订单发料查询 + * @param query 委外订单查询参数对象,包含工厂代码和物料明细等查询条件 + * @return 委外订单发料查询结果列表 + */ + public List zwm3a12(SubcontractedOrderQO query) { + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getWerks()); + parameters.put("R1", query.getR1()); + parameters.put("R2", query.getR2()); + parameters.put("R3", query.getR3()); + parameters.put("S_DATE", DateTimeUtil.format(query.getStartDate(), "yyyyMMdd")); + parameters.put("E_DATE", DateTimeUtil.format(query.getEndDate(), "yyyyMMdd")); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getEbeln())) { + tables.put("I_EBELN", query.getEbeln().stream().map(ebeln -> Map.of("EBELN", (Object) ebeln)).toList()); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A12", parameters, tables); + + // 处理返回表 T_RETURN,判断执行是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + + // 将SAP返回的表数据转换为DTO对象列表 + List result = JCoUtil.toBeanList(tOut, SubcontractedOrderDTO.class); + + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 委外订单确认接口,调用SAP的RFC函数ZWM3A04处理委外订单确认逻辑。 + *

+ * 该方法会校验输入参数是否合法,构造SAP所需的输入参数和表数据, + * 调用SAP RFC函数执行业务逻辑,并解析返回结果。 + *

+ * @param query 委外订单确认的查询参数对象,包含订单号和物料明细等信息 + * @return 返回委外订单确认的结果信息,包括物料凭证号和凭证年度 + */ + public SubcontractedOrderConfirmDTO zwm3a04(SubcontractedOrderConfirmQO query) { + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(query.getIItems())).throwMessage("物料明细不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_EBELN", query.getIEbeln()); + parameters.put("I_TYPE", "A"); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + + // 构造 INPUT1 表数据:包含物料相关明细信息 + tables.put("INPUT1", JCoUtil.toMapList(query.getIItems())); + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A04", parameters, tables); + + // 处理返回表 T_RETURN,判断执行是否成功 + JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT"); + print("OUTPUT", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage(structure.getString("MSG")); + SubcontractedOrderConfirmDTO result = new SubcontractedOrderConfirmDTO() + .setMatDoc(structure.getString("MAT_DOC")) + .setDocYear(structure.getString("DOC_YEAR")); + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", result.getMatDoc(), result.getDocYear()); + return result; + } + + + /** + * 转储清单查询 + * 通过调用SAP RFC函数ZWM3A15查询转储清单信息 + * @param query 查询条件对象,包含工厂、日期范围等查询参数 + * @return AllocationOrderDTO对象列表,包含查询到的转储清单信息 + */ + public List zwm3a15(AllocationOrderQO query) { + VUtil.trueThrowBusinessError(StrUtil.isBlank(query.getEbeln()) + && (StrUtil.isBlank(query.getWerks()) || Objects.isNull(query.getEndDate()))) + .throwMessage("单号为空时,工厂和需求日期不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getWerks()); + parameters.put("R1", query.getR1()); + parameters.put("R2", query.getR2()); + parameters.put("R3", query.getR3()); + parameters.put("S_DATE", DateTimeUtil.format(query.getStartDate(), "yyyyMMdd")); + parameters.put("E_DATE", DateTimeUtil.format(query.getEndDate(), "yyyyMMdd")); + + Map>> tables = new HashMap<>(); + if (StrUtil.isNotBlank(query.getEbeln())) { + tables.put("S_EBELN", List.of(Map.of("EBELN", query.getEbeln()))); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A15", parameters, tables); + // 处理返回表 T_RETURN,判断执行是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + // 将SAP返回的表数据转换为DTO对象列表 + List result = JCoUtil.toBeanList(tOut, AllocationOrderDTO.class); + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 场内调拨清单查询 + * 通过调用SAP RFC函数ZWM3A16查询场内调拨清单信息 + * @param query 查询条件对象,包含工厂、日期范围等查询参数 + * @return 调拨订单DTO列表,包含查询到的调拨清单信息 + */ + public List zwm3a16(TransferOrderQO query) { + VUtil.trueThrowBusinessError(StrUtil.isBlank(query.getRsnum()) + && (StrUtil.isBlank(query.getWerks()) || Objects.isNull(query.getEndDate()))) + .throwMessage("单号为空时,工厂和需求日期不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getWerks()); + parameters.put("R1", query.getR1()); + parameters.put("R2", query.getR2()); + parameters.put("R3", query.getR3()); + parameters.put("S_DATE", DateTimeUtil.format(query.getStartDate(), "yyyyMMdd")); + parameters.put("E_DATE", DateTimeUtil.format(query.getEndDate(), "yyyyMMdd")); + + Map>> tables = new HashMap<>(); + if (StrUtil.isNotBlank(query.getRsnum())) { + tables.put("S_RSNUM", List.of(Map.of("RSNUM", query.getRsnum()))); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A16", parameters, tables); + + // 处理返回表 T_RETURN,判断执行是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + // 将SAP返回的表数据转换为DTO对象列表 + List result = JCoUtil.toBeanList(tOut, TransferOrderDTO.class); + log.debug("数据OUTPUT1:{}", JSONUtil.toJsonStr(result)); + log.info("SAP原始数据OUTPUT1: {}", tOut); + return result; + } + + /** + * 成本中心领料清单查询 + * 通过调用SAP RFC函数ZWM3A13查询成本中心的物料领用清单信息 + * @param query 查询参数对象,包含工厂代码等查询条件,不可为空 + * @return 返回成本中心物料领料清单的DTO对象列表 + */ + //成本中心领料清单查询 + public List zwm3a13(DepartmentMaterialRequisitionQO query) { + // 参数校验:检查查询对象和物料明细是否为空 + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getWerks()); + parameters.put("R1", query.getR1()); + parameters.put("R2", query.getR2()); + parameters.put("R3", query.getR3()); + parameters.put("S_DATE", DateTimeUtil.format(query.getStartDate(), "yyyyMMdd")); + parameters.put("E_DATE", DateTimeUtil.format(query.getEndDate(), "yyyyMMdd")); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getKostl())) { + tables.put("S_KOSTL", query.getKostl().stream().map(kostl -> { + Map map = new HashMap<>(); + map.put("KOSTL", kostl); + return map; + }).collect(Collectors.toList())); + } + if (CollectionUtil.isNotEmpty(query.getRsnum())) { + tables.put("S_RSNUM", query.getRsnum().stream().map(rsnum -> { + Map map = new HashMap<>(); + map.put("RSNUM", rsnum); + return map; + }).collect(Collectors.toList())); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A13", parameters, tables); + + // 处理返回表 T_RETURN,判断执行是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + + // 将SAP返回的表数据转换为DTO对象列表 + List result = JCoUtil.toBeanList(tOut, DepartmentMaterialRequisitionDTO.class); + + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + + /** + * 成本中心退料清单查询 + * @param query 查询条件对象,包含工厂等查询参数 + * @return 部门物料退料单DTO列表 + */ +//成本中心退料清单查询 + public List zwm3a14(DepartmentMaterialReturnSlipQO query) { + // 参数校验:检查查询对象和物料明细是否为空 + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getWerks()); + parameters.put("S_DATE", DateTimeUtil.format(query.getStartDate(), "yyyyMMdd")); + parameters.put("E_DATE", DateTimeUtil.format(query.getEndDate(), "yyyyMMdd")); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getKostl())) { + tables.put("S_KOSTL", query.getKostl().stream().map(kostl -> { + Map map = new HashMap<>(); + map.put("KOSTL", kostl); + return map; + }).collect(Collectors.toList())); + } + if (CollectionUtil.isNotEmpty(query.getRsnum())) { + tables.put("S_RSNUM", query.getRsnum().stream().map(rsnum -> { + Map map = new HashMap<>(); + map.put("RSNUM", rsnum); + return map; + }).collect(Collectors.toList())); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM3A14", parameters, tables); + // 处理返回表 T_RETURN,判断执行是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + JCoTable tOut = function.getTableParameterList().getTable("OUTPUT1"); + log.info("SAP返回: {}", tOut); + // 将SAP返回的表数据转换为DTO对象列表 + List result = JCoUtil.toBeanList(tOut, DepartmentMaterialReturnSlipDTO.class); + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 厂内调库过账接口 + *

+ * 该方法用于调用 SAP 的 RFC 函数 ZWM00_MB113,完成厂内调库的过账操作。 + *

+ * @param query 查询参数对象,包含过账所需的输入信息和物料明细列表 + * @return 返回包含物料凭证号(MBLNR)和年度(MJAHR)的结果对象 + */ +// 厂内调库过账接口 + public ZWM00MB113DTO zwm00_mb113(ZWM00MB113QO query) { + // 校验查询参数及物料明细是否为空 + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(query.getT_list1())).throwMessage("物料明细不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_RSNUM", query.getIRsnum()); + parameters.put("I_UMLGO", query.getIUmlgo()); + parameters.put("I_USNAM", UserUtil.getUserName()); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getT_list1())) { + tables.put("T_LIST1", JCoUtil.toMapList(query.getT_list1())); + } + + if (CollectionUtil.isNotEmpty(query.getT_list2())) { + tables.put("T_LIST2", JCoUtil.toMapList(query.getT_list2())); + } + + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM00_MB113", parameters, tables); + + // 获取导出参数,构造返回结果对象 + JCoParameterList exportParam = function.getExportParameterList(); + if (StrUtil.isNotBlank(exportParam.getString("E_MJAHR"))) { + log.info("SAP返回物料凭证信息: MBLNR={}, MJAHR={}", exportParam.getString("E_MBLNR"), exportParam.getString("E_MJAHR")); + return new ZWM00MB113DTO() + .setEMjahr(exportParam.getString("E_MJAHR")) + .setEMblnr(exportParam.getString("E_MBLNR")); + } else { + JCoTable returnTable = function.getTableParameterList().getTable("T_RETURN"); + log.info("SAP返回: {}", returnTable); + returnTable.setRow(0); + throw new SAPException(returnTable.getString("MESSAGE")); + } + } + + /** + * 获取物料的属性信息(仓库、库位、批次管理、序号管理,是否质检) + * @param query 查询条件封装对象,包含工厂、仓库、物料等信息 + * @return 物料属性信息列表,每个元素为 {@link ZWM3A21ResultDTO} 类型 + */ + public List zwm3a21(ZWM3A21QueryDTO query) { + // 校验查询参数及物料明细是否为空 + VUtil.trueThrowBusinessError(Objects.isNull(query)).throwMessage("查询内容不可以为空"); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(query.getIt_matnr())).throwMessage("物料明细不能为空"); + + // 构造函数调用所需的输入参数 + Map parameters = new HashMap<>(); + parameters.put("I_WERKS", query.getI_werks()); + + // 将构造好的表数据放入输入参数中 + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(query.getIt_lgort())) { + tables.put("IT_LGORT", JCoUtil.toMapList(query.getIt_lgort())); + } + + if (CollectionUtil.isNotEmpty(query.getIt_matnr())) { + tables.put("IT_MATNR", JCoUtil.toMapList(query.getIt_matnr())); + } + + // 调用 SAP RFC 函数 ZWM3A21 + JCoFunction function = exec("ZWM3A21", parameters, tables); + + // 获取并校验导出参数,判断调用是否成功 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料信息"); + VUtil.trueThrowBusinessError(!StrUtil.equals(exportParam.getString("E_TYPE"), "S")) + .throwMessage(exportParam.getString("E_MSG")); + + // 处理返回表数据,转换为结果对象列表 + JCoTable returnTable = function.getTableParameterList().getTable("T_OUT"); + VUtil.trueThrowBusinessError(returnTable.getNumRows() <= 0).throwMessage("获取物料信息有误"); + log.info("SAP返回: {}", returnTable); + if (returnTable.getNumRows() > 0) { + return JCoUtil.toBeanList(returnTable, ZWM3A21ResultDTO.class); + } else { + return Collections.emptyList(); + } + } + + /** + * 获取物料的批次信息 + * @param iVbelv 交货单 + * @param iWerks 工厂 + * @return 获取零部件出库单的订单信息,每个元素为 {@link ZWM3A19DTO} 类型 + */ + public ZWM3A19DTO zwm3a19(String iVbelv, String iWerks) { + Map parameters = new HashMap<>(); + parameters.put("I_VBELV", iVbelv); + parameters.put("I_WERKS", iWerks); + ZWM3A19DTO result = new ZWM3A19DTO(); + JCoFunction function = exec("ZWM3A19", parameters, null); + JCoParameterList structure = function.getExportParameterList(); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("E_TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("E_MSG")); + + JCoTable ot1 = function.getTableParameterList().getTable("HEAD"); + + + List headDTOList = JCoUtil.toBeanList(ot1, ZWM3A19HEADDTO.class); + VUtil.trueThrowBusinessError(CollUtil.isEmpty(headDTOList)) + .throwMessage("SAP返回结果为空"); + + result.setHeadDTO(headDTOList.get(0)); + + JCoTable ot2 = function.getTableParameterList().getTable("ITEM"); + result.setItemDTOList(JCoUtil.toBeanList(ot2, ZWM3A19ITEMDTO.class)); + + log.debug("数据:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 退换货 + * @param head 批次信息头 + * @param itemList 批次信息列表 + * @return 批次信息返回结果,每个元素为 {@link ZWM3A24ReturnDTO} 类型 + */ + public ZWM3A24ReturnDTO ZWM3A24(ZWM3A24HeadDTO head, List itemList) { + Map parameters = new HashMap<>(); + parameters.put("LIFNR", head.getLifnr()); + parameters.put("EKGRP", head.getEkgrp()); + parameters.put("RETURN_TYPE", head.getReturnType()); + parameters.put("BSTKD_OLD", head.getBstkdOld()); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(itemList)) { + tables.put("ITEM", JCoUtil.toMapList(itemList)); + } + JCoFunction function = exec("ZWM3A24", "HEAD", parameters, tables); + JCoStructure structure = function.getExportParameterList().getStructure("ET_RETURN"); + print("OUTPUT", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage(structure.getString("MSG")); + ZWM3A24ReturnDTO returnDto = new ZWM3A24ReturnDTO(); + ZWM3A24HeadReturnDTO result = new ZWM3A24HeadReturnDTO() + .setEbeln(structure.getString("EBELN")) + .setMsg(structure.getString("MSG")) + .setType(structure.getString("TYPE")); + returnDto.setHeadReturnDTO(result); +//获取行的返回值 + JCoTable jtr = function.getTableParameterList().getTable("RETURN"); + List lrs = JCoUtil.toBeanList(jtr, ZWM3A24ItemReturnDTO.class); + returnDto.setItemReturnDTOList(lrs); + return returnDto; + } + + /** + * 采购物料退货(仅退货) + * @param + * @return + */ + public ZWM3A25ReturnDTO ZWM3A25(ZWM3A25HeadDTO head, List itemList) { + Map parameters = new HashMap<>(); + parameters.put("LIFNR", head.getLifnr()); + parameters.put("EKGRP", head.getEkgrp()); + parameters.put("RETURN_TYPE", head.getReturnType()); + parameters.put("BSTKD_OLD", head.getBstkdOld()); + + Map>> tables = new HashMap<>(); + if (CollectionUtil.isNotEmpty(itemList)) { + tables.put("ITEM", JCoUtil.toMapList(itemList)); + } + JCoFunction function = exec("ZWM3A25", "HEAD",parameters, tables); + JCoStructure structure = function.getExportParameterList().getStructure("ET_RETURN"); + print("OUTPUT", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage(structure.getString("MSG")); + ZWM3A25ReturnDTO returnDto = new ZWM3A25ReturnDTO(); + ZWM3A25HeadReturnDTO result = new ZWM3A25HeadReturnDTO() + .setEbeln(structure.getString("EBELN")) + .setMsg(structure.getString("MSG")) + .setType(structure.getString("TYPE")); + returnDto.setHeadReturnDTO(result); +//获取行的返回值 + JCoTable jtr = function.getTableParameterList().getTable("RETURN"); + List lrs = JCoUtil.toBeanList(jtr, ZWM3A25ItemReturnDTO.class); + returnDto.setItemReturnDTOList(lrs); + return returnDto; + } + + /** + * 零部件出库单 过账信息 + * @param dto + * @return + */ + public Pair zwm3a20(ZWM3A20DTO dto) { + // return Pair.of("Test", "TestYear"); + Map parameters = new HashMap<>(); + parameters.put("IV_DELIVERY", dto.getIvDelivery()); + parameters.put("I_TYPE", dto.getIType()); + + Map>> tables = new HashMap<>(); + + if (CollectionUtil.isNotEmpty(dto.getItem())) { + tables.put("ITEM", JCoUtil.toMapList(dto.getItem())); + } + if (CollectionUtil.isNotEmpty(dto.getItLipsItem())) { + tables.put("IT_LIPS_ITEM", JCoUtil.toMapList(dto.getItLipsItem())); + } + if (CollectionUtil.isNotEmpty(dto.getItSernr())) { + tables.put("IT_SERNR", JCoUtil.toMapList(dto.getItSernr())); + } + if (CollectionUtil.isNotEmpty(dto.getItSernrPatch())) { + tables.put("IT_SERNR_PATCH", JCoUtil.toMapList(dto.getItSernrPatch())); + } + log.info("输入表数据: {}", JSONUtil.toJsonStr(tables)); + JCoFunction function = exec("ZWM3A20", parameters, tables); + + JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT"); + print("输出参数OUTPUT", structure); + VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) + .throwMessage("SAP:" + structure.getString("MSG")); + return Pair.of(structure.getString("MAT_DOC"), structure.getString("DOC_YEAR")); + } + +// /** +// * 获取库存信息 +// * @param factory 工厂编号 +// * @param warehouseNos 仓库编号列表 +// * @param beginTime 开始时间,格式yyyyMMdd +// * @param endTime 结束时间,格式yyyyMMdd +// */ +// public List getStorage(String factory, List warehouseNos, String beginTime, String endTime) { +// Map parameters = new HashMap<>(); +// parameters.put("I_WERKS", factory); +// parameters.put("I_TYPE", Objects.nonNull(beginTime) || Objects.nonNull(endTime) ? "I" : "A"); +// if (Objects.nonNull(beginTime)) { +// parameters.put("S_DATE", beginTime); +// } +// if (Objects.nonNull(endTime)) { +// parameters.put("E_DATE", endTime); +// } +// +// Map>> tables = new HashMap<>(); +// List> warehouses = new ArrayList<>(); +// warehouseNos.forEach(warehouseNo -> { +// warehouses.add(Map.of("LGORT", warehouseNo)); +// }); +// tables.put("IT_LGORT", warehouses); +// +// JCoTable tOut = execReturnTable("ZWM3A01", parameters, tables); +// +// List result = new ArrayList<>(); +// for (int i = 0; i < tOut.getNumRows(); i++) { +// tOut.setRow(i); +// result.add(new SAPSyncFromDTO() +// .setFactoryNo(tOut.getString("WERKS")) +// .setMaterialNo(tOut.getString("MATNR")) +// .setMaterialDesc(tOut.getString("MAKTX")) +// .setWarehouseNo(tOut.getString("LGORT")) +// .setWarehouseName(tOut.getString("LGOBE")) +// .setBinNos(tOut.getString("LGPBE"))) +// ; +// } +// log.debug("数据:{}", JSONUtil.toJsonStr(result)); +// return result; +// } + + private JCoTable execReturnTable(String functionName, Map parameters) { + return execReturnTable(functionName, parameters, null, "T_OUT"); + } + + private JCoTable execReturnTable(String functionName, Map parameters, Map>> tables) { + return execReturnTable(functionName, parameters, tables, "T_OUT"); + } + + private JCoTable execReturnTable(String functionName, Map parameters, Map>> tables, String outName) { + JCoFunction function = exec(functionName, parameters, tables); + JCoTable out = function.getTableParameterList().getTable(outName); + log.info("SAP返回: {}", out); + return out; + } + + private JCoParameterList execReturnParameter(String functionName, Map parameters, Map>> tables) { + JCoFunction function = exec(functionName, parameters, tables); + JCoParameterList out = function.getExportParameterList(); + log.info("SAP返回: {}", out); + return out; + } + + private JCoFunction exec(String functionName, Map parameters) { + return exec(functionName, parameters, null); + } + + private JCoFunction exec(String functionName, String structureName, Map parameters, Map>> tables) { + try { + functionName = functionName.toUpperCase(); + log.info("SAP functionName:{}", functionName); + JCoFunction function = repository.getFunction(functionName); + + log.info("SAP ImportParameter:{}", JSONUtil.toJsonStr(parameters)); + + if (CollectionUtil.isNotEmpty(parameters)) { + JCoStructure inputStruct = function.getImportParameterList().getStructure(structureName); + parameters.forEach((name, value) -> inputStruct.setValue(name, value)); + } + if (CollectionUtil.isNotEmpty(tables)) { + tables.forEach((tableName, list) -> { + log.info("SAP TableParameter:{}", tableName); + log.info(JSONUtil.toJsonStr(list)); + JCoTable jt = function.getTableParameterList().getTable(tableName); + list.forEach(vl -> { + jt.appendRow(); + vl.forEach(jt::setValue); + }); + }); + } + function.execute(destination); + return function; + } catch (JCoException e) { + log.error("SAP调用异常", e); + throw new SAPException(e.getMessage()); + } + } + + private JCoFunction exec(String functionName, Map parameters, Map>> tables) { + try { + functionName = functionName.toUpperCase(); + log.info("SAP functionName:{}", functionName); + JCoFunction function = repository.getFunction(functionName); + + log.info("SAP ImportParameter:{}", JSONUtil.toJsonStr(parameters)); + + if (CollectionUtil.isNotEmpty(parameters)) { + parameters.forEach((name, value) -> function.getImportParameterList().setValue(name, value)); + } + if (CollectionUtil.isNotEmpty(tables)) { + tables.forEach((tableName, list) -> { + log.info("SAP TableParameter:{}", tableName); + log.info(JSONUtil.toJsonStr(list)); + JCoTable jt = function.getTableParameterList().getTable(tableName); + list.forEach(vl -> { + jt.appendRow(); + vl.forEach(jt::setValue); + }); + }); + } + function.execute(destination); + return function; + } catch (JCoException e) { + log.error("SAP调用异常", e); + throw new SAPException(e.getMessage()); + } + } + + private void print(String name, JCoStructure structure) { + log.info(name); + if (Objects.nonNull(structure)) { + JCoRecordFieldIterator iterator = structure.getRecordFieldIterator(); + if (Objects.nonNull(iterator)) { + JSONObject json = new JSONObject(); + while (iterator.hasNextField()) { + JCoField field = iterator.nextField(); + json.put(field.getName(), field.getValue()); + } + log.info(json.toString()); + } + } + } +} diff --git a/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/util/JCoUtil.java b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/util/JCoUtil.java new file mode 100644 index 00000000..bd7b7c93 --- /dev/null +++ b/nflg-wms-srm-receive/src/main/java/com/nflg/wms/srm/receive/util/JCoUtil.java @@ -0,0 +1,103 @@ +package com.nflg.wms.srm.receive.util; + +import cn.hutool.core.collection.CollectionUtil; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.nflg.wms.common.util.BeanUtil; +import com.sap.conn.jco.*; + +import java.util.*; +import java.util.stream.Collectors; + +public class JCoUtil { + + private static final ObjectMapper MAPPER = JsonMapper.builder() + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build(); + + /** + * 将 JCoTable 转换为 Java Bean 列表 + * @param table JCoTable 对象 + * @param clazz 目标实体类 + * @param 泛型 + * @return List 列表 + */ + public static List toBeanList(JCoTable table, Class clazz) { + List> mapList = toMapList(table); + List resultList = new ArrayList<>(mapList.size()); + for (Map map : mapList) { + resultList.add(MAPPER.convertValue(map, clazz)); + } + return resultList; + } + + public static List> toMapList(JCoTable table) { + if (CollectionUtil.isEmpty(table) || table.isEmpty()) { + return Collections.emptyList(); + } + List> mapList = new ArrayList<>(); + JCoRecordMetaData meta = table.getRecordMetaData(); + table.firstRow(); + do { + Map rowMap = new HashMap<>(); + for (int i = 0; i < meta.getFieldCount(); i++) { + rowMap.put(meta.getName(i), table.getField(i).getValue()); + } + mapList.add(rowMap); + } while (table.nextRow()); + return mapList; + } + + public static List> toMapList(List datas) { + return datas.stream().map(BeanUtil::toMap) + .map(list -> list.entrySet().stream() + .collect(Collectors.toMap(entry -> entry.getKey().toUpperCase(), + Map.Entry::getValue))) + .toList(); + } + + public static List> toMapList(T data) { + return Collections.singletonList(BeanUtil.toMap(data)); + } + + /** + * 将 JCoStructure 转换为 Java Bean + * @param structure JCoStructure 对象 + * @param clazz 目标实体类 + * @param 泛型 + * @return T 实体对象 + */ + public static T toBean(JCoStructure structure, Class clazz) { + if (Objects.isNull(structure)) { + return null; + } + JCoRecordMetaData meta = structure.getRecordMetaData(); + Map rowMap = new HashMap<>(); + for (int i = 0; i < meta.getFieldCount(); i++) { + rowMap.put(meta.getName(i), structure.getField(i).getValue()); + } + return MAPPER.convertValue(rowMap, clazz); + } + + /** + * 将 JCoParameterList 转换为 Java Bean + * @param parameters JCoParameterList 对象 + * @param clazz 目标实体类 + * @param 泛型 + * @return T 实体对象 + */ + public static T toBean(JCoParameterList parameters, Class clazz) { + if (Objects.isNull(parameters)) { + return null; + } + JCoListMetaData meta = parameters.getListMetaData(); + Map rowMap = new HashMap<>(); + for (int i = 0; i < meta.getFieldCount(); i++) { + rowMap.put(meta.getName(i), parameters.getField(i).getValue()); + } + return MAPPER.convertValue(rowMap, clazz); + } +} diff --git a/nflg-wms-srm-receive/src/test/java/com/nflg/wms/srm/receive/SapMetaPrintTest.java b/nflg-wms-srm-receive/src/test/java/com/nflg/wms/srm/receive/SapMetaPrintTest.java new file mode 100644 index 00000000..d4dd8837 --- /dev/null +++ b/nflg-wms-srm-receive/src/test/java/com/nflg/wms/srm/receive/SapMetaPrintTest.java @@ -0,0 +1,410 @@ +package com.nflg.wms.srm.receive; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.sap.conn.jco.*; +import com.sap.conn.jco.ext.DestinationDataEventListener; +import com.sap.conn.jco.ext.DestinationDataProvider; +import com.sap.conn.jco.ext.Environment; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.*; + +public class SapMetaPrintTest { + + @Test + public void ZWM3A22() throws JCoException { + printMeta("ZWM3A22"); + } + + @Test + public void ZWM3A23() throws JCoException { + printMeta("ZWM3A23"); + } + + @Test + public void ZIM_004() throws JCoException { + printMeta("ZIM_004"); + } + + @Test + public void ZWM3A02() throws JCoException { + printMeta("ZWM3A02"); + } + + @Test + public void ZRFC_MM_SMXT() throws JCoException { + printMeta("ZRFC_MM_SMXT"); + } + + @Test + public void ZWM3A17() throws JCoException { + printMeta("ZWM3A17"); + } + + @Test + public void ZWM3A18() throws JCoException { + printMeta("ZWM3A18"); + } + + @Test + public void ZWM00_MB007() throws JCoException { + printMeta("ZWM00_MB007"); + } + + @Test + public void ZWM00_MB107() throws JCoException { + printMeta("ZWM00_MB107"); + } + + @Test + public void ZIM_001_QUERY() throws JCoException { + printMeta("ZIM_001_QUERY"); + } + + @Test + public void ZWM3A05() throws JCoException { + printMeta("ZWM3A05"); + } + + @Test + public void ZIM_001() throws JCoException { + printMeta("ZIM_001"); + } + + @Test + public void ZWM3A06() throws JCoException { + printMeta("ZWM3A06"); + } + + @Test + public void ZWM00_MB017() throws JCoException { + printMeta("ZWM00_MB017"); + } + + @Test + public void ZWM00_MB112() throws JCoException { + printMeta("ZWM00_MB112"); + } + + @Test + public void ZWM00_MB026() throws JCoException { + printMeta("ZWM00_MB026"); + } + + @Test + public void ZWM00_MB115() throws JCoException { + printMeta("ZWM00_MB115"); + } + + @Test + public void ZWM3A03() throws JCoException { + printMeta("ZWM3A03"); + } + + @Test + public void ZWM3A04() throws JCoException { + printMeta("ZWM3A04"); + } + + @Test + public void ZWM3A07() throws JCoException { + printMeta("ZWM3A07"); + } + + @Test + public void ZWM3A10() throws JCoException { + printMeta("ZWM3A10"); + } + + @Test + public void ZWM3A08() throws JCoException { + printMeta("ZWM3A08"); + } + + @Test + public void ZWM3A09() throws JCoException { + printMeta("ZWM3A09"); + } + + @Test + public void ZWM3A11() throws JCoException { + printMeta("ZWM3A11"); + } + + @Test + public void ZWM3A12() throws JCoException { + printMeta("ZWM3A12"); + } + + @Test + public void ZWM3A13() throws JCoException { + printMeta("ZWM3A13"); + } + + @Test + public void ZWM3A14() throws JCoException { + printMeta("ZWM3A14"); + } + + @Test + public void ZWM3A15() throws JCoException { + printMeta("ZWM3A15"); + } + + @Test + public void ZWM3A16() throws JCoException { + printMeta("ZWM3A16"); + } + + @Test + public void ZWM00_MB113() throws JCoException { + printMeta("ZWM00_MB113"); + } + + @Test + public void ZWM00_MB116() throws JCoException { + printMeta("ZWM00_MB116"); + } + + @Test + public void ZWM3A21() throws JCoException { + printMeta("ZWM3A21"); + } + + + @Test + public void ZWM3A19() throws JCoException { + printMeta("ZWM3A19"); + } + + + @Test + public void ZWM3A20() throws JCoException { + printMeta("ZWM3A20"); + } + + @Test + public void ZWM3A24() throws JCoException { + printMeta("ZWM3A24"); + } + + @Test + public void ZWM3A25() throws JCoException { + printMeta("ZWM3A25"); + } + + + public void printMeta(String functionName) throws JCoException { + functionName = functionName.toUpperCase(); + JCoFunction function = repository.getFunction(functionName); + if (Objects.isNull(function)) { + print("方法" + functionName + "不存在"); + } else { + printMeta(function); + } + } + + private void printMeta(JCoFunction function) { + print("SAP {} 方法参数信息", function.getName()); + printParameterField("Import", function.getImportParameterList()); + printParameterField("Changing", function.getChangingParameterList()); + printParameterField("Export", function.getExportParameterList()); + printParameterField("Table", function.getTableParameterList()); + } + + private void printParameterField(String name, JCoParameterList parameterList) { + print("▶ " + name); + if (Objects.nonNull(parameterList)) { + JCoParameterFieldIterator iterator = parameterList.getParameterFieldIterator(); + if (Objects.nonNull(iterator)) { + List fields = new ArrayList<>(); + List data = new ArrayList<>(); + JSONObject jo = new JSONObject(); + while (iterator.hasNextField()) { + JCoParameterField field = iterator.nextParameterField(); + data.add(new String[]{field.getName(), field.getTypeAsString(), field.getDescription()}); + if (field.isTable() || field.isStructure()) { + fields.add(field); + } + jo.putOnce(field.getName(), field.getDescription()); + } + printTable(data); + printJson(jo); + fields.forEach(this::print); + } + } + } + + private void print(JCoParameterField field) { + print("★★ {}({}) 参数", field.getName(), field.getDescription()); + if (field.isTable()) { + print(field.getTable().getRecordFieldIterator()); + } else if (field.isStructure()) { + print(field.getStructure().getRecordFieldIterator()); + } + } + + private void print(JCoRecordFieldIterator iterator) { + List data = new ArrayList<>(); + JSONObject jo = new JSONObject(); + while (iterator.hasNextField()) { + JCoRecordField field = iterator.nextRecordField(); + data.add(new String[]{field.getName(), field.getTypeAsString(), field.getDescription()}); + jo.putOnce(field.getName(), field.getDescription()); + } + printTable(data); + printJson(jo); + } + + private void printJson(JSONObject jo) { + print("JSON形式:"); + print(JSONUtil.toJsonPrettyStr(jo).toLowerCase()); + } + + private void printTable(List datas) { + print("表格形式:"); + SimpleTable table = new SimpleTable(); + table.addHeader("序号", "名称", "类型", "描述"); + for (int i = 0; i < datas.size(); i++) { + table.addRow(String.valueOf(i + 1), datas.get(i)[0], datas.get(i)[1], datas.get(i)[2]); + } + table.print(); + } + + private void print(String content) { + System.out.println(content); + } + + private void print(String template, Object... args) { + System.out.println(StrUtil.format(template, args)); + } + + // 简单实现示例 + private static class SimpleTable { + private final List rows = new ArrayList<>(); + private final List headers = new ArrayList<>(); + + public void addHeader(String... headers) { + this.headers.addAll(Arrays.asList(headers)); + } + + public void addRow(String... values) { + rows.add(values); + } + + public void print() { + // 计算每列最大宽度 + int[] maxWidths = new int[headers.size()]; + for (int i = 0; i < headers.size(); i++) { + maxWidths[i] = getWeightedLength(headers.get(i)); + } + + for (String[] row : rows) { + for (int i = 0; i < row.length && i < maxWidths.length; i++) { + maxWidths[i] = Math.max(maxWidths[i], getWeightedLength(row[i])); + } + } + + // 打印表格 + printLine(maxWidths); + printRow(headers.toArray(new String[0]), maxWidths); + printLine(maxWidths); + + for (String[] row : rows) { + printRow(row, maxWidths); + } + printLine(maxWidths); + } + + private void printLine(int[] widths) { + System.out.print("+"); + for (int width : widths) { + for (int i = 0; i < width + 2; i++) { + System.out.print("-"); + } + System.out.print("+"); + } + System.out.println(); + } + + private void printRow(String[] row, int[] widths) { + System.out.print("|"); + for (int i = 0; i < widths.length; i++) { + String value = i < row.length ? row[i] : ""; + System.out.printf(" %-" + (widths[i] - getChineseNum(value) / 2) + "s |", value); + } + System.out.println(); + } + + private static final String CHINESE_REGEX = "[\\u4e00-\\u9fff]"; + + public static int getWeightedLength(String str) { + if (str == null || str.isEmpty()) { + return 0; + } + return str.chars() + .map(c -> String.valueOf((char) c).matches(CHINESE_REGEX) ? 2 : 1) + .sum(); + } + + public static int getChineseNum(String str) { + if (str == null || str.isEmpty()) { + return 0; + } + return str.chars() + .map(c -> String.valueOf((char) c).matches(CHINESE_REGEX) ? 1 : 0) + .sum(); + } + } + + private static JCoRepository repository; + + @BeforeAll + static void initOnce() throws JCoException { + Environment.registerDestinationDataProvider(new SimpleDestinationDataProvider(ABAP_AS_POOLED, buildConnectionProperties())); + repository = JCoDestinationManager.getDestination(ABAP_AS_POOLED).getRepository(); + } + + private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL"; + + private static Properties buildConnectionProperties() { + Properties props = new Properties(); + props.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.0.24"); + props.setProperty(DestinationDataProvider.JCO_SYSNR, "03"); + props.setProperty(DestinationDataProvider.JCO_CLIENT, "800"); + props.setProperty(DestinationDataProvider.JCO_USER, "mdm_back"); + props.setProperty(DestinationDataProvider.JCO_PASSWD, "sap-mdm"); + props.setProperty(DestinationDataProvider.JCO_LANG, "ZH"); + props.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10"); + props.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "20"); + return props; + } + + private static class SimpleDestinationDataProvider implements DestinationDataProvider { + private final Map destinations = new HashMap<>(); + + public SimpleDestinationDataProvider(String destName, Properties props) { + destinations.put(destName, props); + } + + @Override + public Properties getDestinationProperties(String destinationName) { + return destinations.get(destinationName); + } + + @Override + public void setDestinationDataEventListener(DestinationDataEventListener listener) { + } + + @Override + public boolean supportsEvents() { + return false; + } + } +} + + +