diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/SapService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/SapService.java index a4ebc4e0..15a74e7f 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/SapService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/SapService.java @@ -21,7 +21,6 @@ import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.*; -import java.util.stream.Collectors; @Slf4j @Component @@ -35,9 +34,10 @@ public class SapService { /** * 生产订单查询 + * * @param no 生产订单号 */ - public ZWM00MB007DTO zwm00Mb007(String no){ + public ZWM00MB007DTO zwm00Mb007(String no) { Map parameters = new HashMap<>(); parameters.put("I_AUFNR", no); @@ -62,12 +62,13 @@ public class SapService { /** * 生产订单收货 - * @param no 生产订单号 - * @param userName 用户名 + * + * @param no 生产订单号 + * @param userName 用户名 * @param materials 入库物料列表 - * @param sernrs 序列号列表 + * @param sernrs 序列号列表 */ - public Zwm00Mb107DTO zwm00_mb107(String no, String userName, List materials, List 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); @@ -75,7 +76,7 @@ public class SapService { Map>> tables = new HashMap<>(); List> list1 = new ArrayList<>(); materials.forEach(item -> { - Map map=new HashMap<>(); + Map map = new HashMap<>(); map.put("PWERK", item.getPWERK()); map.put("LGORT", item.getLGORT()); map.put("PSMNG", item.getPSMNG()); @@ -104,13 +105,14 @@ public class SapService { /** * 查询采购单退库信息 + * * @param orderNo 采购单号 */ public Zim001QueryResultDTO zim001query(String orderNo) { Map parameters = new HashMap<>(); parameters.put("EBELN", orderNo); - Zim001QueryResultDTO result=new Zim001QueryResultDTO(); + Zim001QueryResultDTO result = new Zim001QueryResultDTO(); JCoFunction function = exec("ZIM_001_QUERY", parameters, null); JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT"); @@ -156,7 +158,7 @@ public class SapService { return result; } - public void zim001(Zim001QueryResultDTO dto){ + public void zim001(Zim001QueryResultDTO dto) { Map>> tables = new HashMap<>(); List> list1 = new ArrayList<>(); dto.getItem1().forEach(item -> { @@ -189,7 +191,7 @@ public class SapService { tables.put("INPUT2", list2); JCoParameterList jparameters = execReturnParameter("ZIM_001", null, tables); - JCoStructure structure=jparameters.getStructure("OUTPUT"); + JCoStructure structure = jparameters.getStructure("OUTPUT"); VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S")) .throwMessage("SAP错误:" + structure.getString("MSG")); } @@ -303,6 +305,7 @@ public class SapService { /** * 获取库存信息 + * * @param factory 工厂编号 * @param warehouseNo 仓库编号 * @param materialNo 物料编号 @@ -442,7 +445,6 @@ public class SapService { JCoTable tOut = function.getTableParameterList().getTable("T_OUT"); log.info("SAP返回: {}", tOut); List result = new ArrayList<>(); - // if (out.getString("TYPE").equals("S")) { for (int i = 0; i < tOut.getNumRows(); i++) { tOut.setRow(i); result.add(new C_MaterialReturnQueryDTO() @@ -458,66 +460,233 @@ public class SapService { 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()); - List t_list1 = new ArrayList<>(); - List t_list2 = new ArrayList<>(); - for (C_MaterialReturnItemQO item : request.getItems()) { - if (CollectionUtil.isNotEmpty(item.getScanCodes())) { - List scanCodeList = item.getScanCodes(); - //合并批次数量 - Map batchSummary = scanCodeList.stream() - .collect(Collectors.groupingBy( - ScanCodeQO::getBatchNumber, - Collectors.reducing(BigDecimal.ZERO, ScanCodeQO::getCodeNum, BigDecimal::add) - )); - for (Map.Entry entry : batchSummary.entrySet()) { - t_list1.add(new C_MaterialReturnItemDTO() - .setMatnr(item.getResbMatnr()) - .setRspos(item.getResbRspos()) - .setLgort(item.getResbLgort()) - .setMeins(item.getResbMeins()) - .setWerks(item.getResbWerks()) - .setCharg(entry.getKey()) - .setErfmg(String.valueOf(entry.getValue())) - ); - } - for (ScanCodeQO scanCode : scanCodeList) { - t_list2.add(new C_MaterialReturnSerialItemDTO() - .setRspos(item.getResbRspos()) - .setSernr(scanCode.getSerialNumber()) - .setFlag("X") - ); - } + // 构造函数调用所需的输入表结构 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.getSerialNumber()); + 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); } - parameters.put("T_LIST1", t_list1); - parameters.put("T_LIST2", t_list2); - JCoFunction function = exec("ZWM00_MB112", parameters, null); - JCoTable tOut = function.getTableParameterList().getTable("T_OUT"); - log.info("SAP返回: {}", tOut); + // 调用 SAP RFC 函数 ZWM00_MB112 + JCoFunction function = exec("ZWM00_MB112", parameters, tables); + // 处理返回表 T_RETURN,判断执行是否成功 + JCoTable returnTable = function.getTableParameterList().getTable("T_RETURN"); + VUtil.trueThrowBusinessError(returnTable.getNumRows() <= 0).throwMessage("获取Type信息有误"); + + returnTable.setRow(0); + VUtil.trueThrowBusinessError(StrUtil.equals(returnTable.getString("E_TYPE"), "E")) + .throwMessage(returnTable.getString("E_MSG")); + log.info("SAP返回: {}", returnTable); + + // 获取导出参数,构造返回结果对象 + JCoParameterList exportParam = function.getExportParameterList(); + VUtil.trueThrowBusinessError(Objects.isNull(exportParam)).throwMessage("无法获取到有效的物料凭证信息"); C_MaterialReturnDTO result = new C_MaterialReturnDTO() - .setEMblnr(tOut.getString("E_MBLNR")) - .setEMJahr(tOut.getString("E_MJAHR")); + .setEMblnr(exportParam.getString("E_MBLNR")) + .setEMJahr(exportParam.getString("E_MJAHR")); - return null; + 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 领料查询结果数据传输对象,包含主信息和明细列表 + * @throws BusinessException 当参数为空或SAP返回数据异常时抛出业务异常 + */ //成本中心领料查询 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); - return 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; } + public C_MaterialOutboundDTO ZWM00_MB115(C_MaterialOutboundQO request) { - return null; + 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.getSerialNumber()); + 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"); + VUtil.trueThrowBusinessError(returnTable.getNumRows() <= 0).throwMessage("获取Type信息有误"); + + returnTable.setRow(0); + VUtil.trueThrowBusinessError(StrUtil.equals(returnTable.getString("E_TYPE"), "E")) + .throwMessage(returnTable.getString("E_MSG")); + log.info("SAP返回: {}", returnTable); + + // 获取导出参数,构造返回结果对象 + 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; } @@ -550,7 +719,7 @@ public class SapService { private JCoFunction exec(String functionName, Map parameters, Map>> tables) { try { - functionName=functionName.toUpperCase(); + functionName = functionName.toUpperCase(); log.info("SAP functionName:{}", functionName); JCoFunction function = repository.getFunction(functionName); @@ -581,16 +750,16 @@ public class SapService { public void printMeta(String functionName) { try { - functionName=functionName.toUpperCase(); + functionName = functionName.toUpperCase(); JCoFunction function = repository.getFunction(functionName); - VUtil.trueThrowBusinessError(Objects.isNull(function)).throwMessage("方法"+functionName+"不存在"); + VUtil.trueThrowBusinessError(Objects.isNull(function)).throwMessage("方法" + functionName + "不存在"); printMeta(function); - }catch (Exception e){ + } catch (Exception e) { log.error("打印方法参数信息异常", e); } } - private void printMeta(JCoFunction function){ + private void printMeta(JCoFunction function) { log.trace("-------------------------------------------------------"); log.trace("SAP {} 方法参数信息", function.getName()); log.trace("-- Import结构"); @@ -604,16 +773,16 @@ public class SapService { log.trace("-------------------------------------------------------"); } - private void printParameterField(JCoParameterList parameterList){ + private void printParameterField(JCoParameterList parameterList) { if (Objects.nonNull(parameterList)) { JCoParameterFieldIterator iterator = parameterList.getParameterFieldIterator(); if (Objects.nonNull(iterator)) { while (iterator.hasNextField()) { JCoParameterField field = iterator.nextParameterField(); - log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(),field.getDescription()); - if (field.isTable()){ + log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(), field.getDescription()); + if (field.isTable()) { printJCoTable(field.getTable()); - }else if (field.isStructure()){ + } else if (field.isStructure()) { printStructure(field.getStructure()); } } @@ -621,21 +790,21 @@ public class SapService { } } - private void printJCoTable(JCoTable table){ + private void printJCoTable(JCoTable table) { log.trace("Table结构"); - JCoRecordFieldIterator iterator=table.getRecordFieldIterator(); + JCoRecordFieldIterator iterator = table.getRecordFieldIterator(); while (iterator.hasNextField()) { JCoRecordField field = iterator.nextRecordField(); - log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(),field.getDescription()); + log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(), field.getDescription()); } } - private void printStructure(JCoStructure structure){ + private void printStructure(JCoStructure structure) { log.trace("Structure结构"); - JCoRecordFieldIterator iterator=structure.getRecordFieldIterator(); + JCoRecordFieldIterator iterator = structure.getRecordFieldIterator(); while (iterator.hasNextField()) { JCoRecordField field = iterator.nextRecordField(); - log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(),field.getDescription()); + log.trace("名称:{},类型:{},描述:{}", field.getName(), field.getTypeAsString(), field.getDescription()); } } } diff --git a/nflg-wms-admin/src/test/java/com/nflg/wms/admin/SapMetaPrintTest.java b/nflg-wms-admin/src/test/java/com/nflg/wms/admin/SapMetaPrintTest.java index 9c20c00a..13c5fac3 100644 --- a/nflg-wms-admin/src/test/java/com/nflg/wms/admin/SapMetaPrintTest.java +++ b/nflg-wms-admin/src/test/java/com/nflg/wms/admin/SapMetaPrintTest.java @@ -20,4 +20,38 @@ public class SapMetaPrintTest { public void ZWM00_MB107(){ sapService.printMeta("ZWM00_MB107"); } + + @Test + public void ZWM00_MB017() + { + sapService.printMeta("ZWM00_MB017"); + } + + @Test + public void execZwm00_MB017() + { + sapService.zwm00_MB017("1309976"); + } + + + @Test + public void ZWM00_MB112() + { + sapService.printMeta("ZWM00_MB112"); + } + @Test + public void ZWM00_MB026() + { + sapService.printMeta("ZWM00_MB026"); + } + + + @Test + public void ZWM00_MB115() + { + sapService.printMeta("ZWM00_MB115"); + } } + + + diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java index 65354595..4a18e182 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java @@ -8,10 +8,14 @@ import java.util.List; @Data @Accessors(chain = true) public class C_MaterialOutboundQueryDTO { + + /** + * 预留/相关需求的编号 + */ private String resbRsnum; - // 预留项目号 RKPF-WEMPF - private String rkpfWempf; + /*** 预留项目号 RKPF-WEMPF*/ + private String wempf; //领料明细 private List items; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java index 917e9931..779f643c 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java @@ -33,7 +33,7 @@ public class C_MaterialOutboundItemQO { */ private BigDecimal qty; - // 实际出库数量 + // 出库需求数量 private BigDecimal resbErfmg; //扫码信息 diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java index c671c6ac..95215593 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java @@ -10,9 +10,6 @@ import java.util.List; public class C_MaterialOutboundQO { //预留号 private String resbRsNum; - - // 工位 - private String rkpfWempf; // 预留单退料详情信息 private List items; }