From e5c11240e956c3c3af31cae09332f46eaa625cd6 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Wed, 15 Oct 2025 14:02:18 +0800 Subject: [PATCH] =?UTF-8?q?IFS=E5=BA=93=E5=AD=98=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/api/service/IfsApiService.java | 2 +- .../api/service/impl/IfsApiServiceImpl.java | 7 +- .../impl/InventoryMoveServiceImpl.java | 210 +++++++++--------- 3 files changed, 113 insertions(+), 106 deletions(-) diff --git a/src/main/java/com/gaotao/modules/api/service/IfsApiService.java b/src/main/java/com/gaotao/modules/api/service/IfsApiService.java index 7e239a9..a4261f5 100644 --- a/src/main/java/com/gaotao/modules/api/service/IfsApiService.java +++ b/src/main/java/com/gaotao/modules/api/service/IfsApiService.java @@ -25,7 +25,7 @@ public interface IfsApiService { * @return 库存在库信息列表 * @throws JsonProcessingException JSON处理异常 */ - List getInventoryPartInStock(String site) throws JsonProcessingException; + List getInventoryPartInStock(String site,String partNo) throws JsonProcessingException; } diff --git a/src/main/java/com/gaotao/modules/api/service/impl/IfsApiServiceImpl.java b/src/main/java/com/gaotao/modules/api/service/impl/IfsApiServiceImpl.java index b0e9896..b33d542 100644 --- a/src/main/java/com/gaotao/modules/api/service/impl/IfsApiServiceImpl.java +++ b/src/main/java/com/gaotao/modules/api/service/impl/IfsApiServiceImpl.java @@ -90,15 +90,16 @@ public class IfsApiServiceImpl implements IfsApiService { } @Override - public List getInventoryPartInStock(String site) throws JsonProcessingException { + public List getInventoryPartInStock(String site,String partNo) throws JsonProcessingException { Map params = Map.of( "ifsDBName", ifsDBName, "domainUserID", domainUserID, - "ifsSiteID", site + "ifsSiteID", site, + "ifsPartNo", partNo ); ObjectMapper objectMapper = new ObjectMapper(); String jsonBody = objectMapper.writeValueAsString(params); - String ifsResponse = HttpUtils.doGetWithBody(ifsUrl + "InventoryPartInStock", jsonBody, null); + String ifsResponse = HttpUtils.doGetWithBody(ifsUrl + "AnInventoryPartInStock", jsonBody, null); ObjectMapper mapper = new ObjectMapper(); List result = mapper.readValue(ifsResponse, new TypeReference>() { }); diff --git a/src/main/java/com/gaotao/modules/other/service/impl/InventoryMoveServiceImpl.java b/src/main/java/com/gaotao/modules/other/service/impl/InventoryMoveServiceImpl.java index 6c89b38..e7af0ef 100644 --- a/src/main/java/com/gaotao/modules/other/service/impl/InventoryMoveServiceImpl.java +++ b/src/main/java/com/gaotao/modules/other/service/impl/InventoryMoveServiceImpl.java @@ -247,34 +247,34 @@ public class InventoryMoveServiceImpl implements InventoryMoveService { /** * 批量同步到IFS - 按site、partNo、locationNo、lotBatchNo合并后调用 */ - private void syncToIFSBatch(InventoryMoveRequestDto dto, List handlingUnits) { - try { - // 按site、partNo、原库位、lotBatchNo、expiredDate分组合并数量 - Map moveGroups = new HashMap<>(); + private void syncToIFSBatch(InventoryMoveRequestDto dto, List handlingUnits) { + try { + // 按site、partNo、原库位、lotBatchNo、wdr分组合并数量 + Map moveGroups = new HashMap<>(); - for (HandlingUnit hu : handlingUnits) { - String expiredDateStr = hu.getExpiredDate() != null ? - new SimpleDateFormat("yyyy-MM-dd").format(hu.getExpiredDate()) : "null"; - String groupKey = String.format("%s|%s|%s|%s|%s", - hu.getSite(), hu.getPartNo(), hu.getLocationId(), hu.getBatchNo(), expiredDateStr); - - MoveGroup group = moveGroups.computeIfAbsent(groupKey, k -> { - MoveGroup newGroup = new MoveGroup(); - newGroup.site = hu.getSite(); - newGroup.partNo = hu.getPartNo(); - newGroup.sourceLocationNo = hu.getLocationId(); // 注意:这里使用的是更新前的原库位 - newGroup.destLocationNo = dto.getTargetLocationId(); - newGroup.lotBatchNo = hu.getBatchNo(); - newGroup.expiredDate = hu.getExpiredDate(); - newGroup.totalQty = BigDecimal.ZERO; - return newGroup; - }); - - group.totalQty = group.totalQty.add(hu.getQty()); - } + for (HandlingUnit hu : handlingUnits) { + String groupKey = String.format("%s|%s|%s|%s|%s", + hu.getSite(), hu.getPartNo(), hu.getLocationId(), hu.getBatchNo(), + hu.getWdr() != null ? hu.getWdr() : "*"); - // 校验所有分组的库存数量是否足够 - //validateInventoryStock(moveGroups); + MoveGroup group = moveGroups.computeIfAbsent(groupKey, k -> { + MoveGroup newGroup = new MoveGroup(); + newGroup.site = hu.getSite(); + newGroup.partNo = hu.getPartNo(); + newGroup.sourceLocationNo = hu.getLocationId(); // 注意:这里使用的是更新前的原库位 + newGroup.destLocationNo = dto.getTargetLocationId(); + newGroup.lotBatchNo = hu.getBatchNo(); + newGroup.wdr = hu.getWdr(); + newGroup.expiredDate = hu.getExpiredDate(); // 有效期值保留 + newGroup.totalQty = BigDecimal.ZERO; + return newGroup; + }); + + group.totalQty = group.totalQty.add(hu.getQty()); + } + + // 校验所有分组的库存数量是否足够 + validateInventoryStock(moveGroups); // 为每个分组调用IFS接口 for (MoveGroup group : moveGroups.values()) { @@ -295,36 +295,36 @@ public class InventoryMoveServiceImpl implements InventoryMoveService { * @author rqrq * @date 2025/10/08 */ - private void syncToIFSBatchForPallet(InventoryMoveRequestDto dto, List handlingUnits) { - try { - // 按site、partNo、原库位、lotBatchNo、expiredDate分组合并数量 - Map moveGroups = new HashMap<>(); - - for (HandlingUnit hu : handlingUnits) { - String expiredDateStr = hu.getExpiredDate() != null ? - new SimpleDateFormat("yyyy-MM-dd").format(hu.getExpiredDate()) : "null"; - String groupKey = String.format("%s|%s|%s|%s|%s", - hu.getSite(), hu.getPartNo(), hu.getLocationId(), hu.getBatchNo(), expiredDateStr); - - MoveGroup group = moveGroups.computeIfAbsent(groupKey, k -> { - MoveGroup newGroup = new MoveGroup(); - newGroup.site = hu.getSite(); - newGroup.partNo = hu.getPartNo(); - newGroup.sourceLocationNo = hu.getLocationId(); // 注意:这里使用的是更新前的原库位 - newGroup.destLocationNo = dto.getTargetLocationId(); - newGroup.lotBatchNo = hu.getBatchNo(); - newGroup.expiredDate = hu.getExpiredDate(); - newGroup.totalQty = BigDecimal.ZERO; - return newGroup; - }); - - group.totalQty = group.totalQty.add(hu.getQty()); - } - - // 为每个分组调用IFS接口 - rqrq - for (MoveGroup group : moveGroups.values()) { - syncSingleGroupToIFSForPallet(group); - } + private void syncToIFSBatchForPallet(InventoryMoveRequestDto dto, List handlingUnits) { + try { + // 按site、partNo、原库位、lotBatchNo、wdr分组合并数量 + Map moveGroups = new HashMap<>(); + + for (HandlingUnit hu : handlingUnits) { + String groupKey = String.format("%s|%s|%s|%s|%s", + hu.getSite(), hu.getPartNo(), hu.getLocationId(), hu.getBatchNo(), + hu.getWdr() != null ? hu.getWdr() : "*"); + + MoveGroup group = moveGroups.computeIfAbsent(groupKey, k -> { + MoveGroup newGroup = new MoveGroup(); + newGroup.site = hu.getSite(); + newGroup.partNo = hu.getPartNo(); + newGroup.sourceLocationNo = hu.getLocationId(); // 注意:这里使用的是更新前的原库位 + newGroup.destLocationNo = dto.getTargetLocationId(); + newGroup.lotBatchNo = hu.getBatchNo(); + newGroup.wdr = hu.getWdr(); + newGroup.expiredDate = hu.getExpiredDate(); // 有效期值保留 + newGroup.totalQty = BigDecimal.ZERO; + return newGroup; + }); + + group.totalQty = group.totalQty.add(hu.getQty()); + } + + // 为每个分组调用IFS接口 - rqrq + for (MoveGroup group : moveGroups.values()) { + syncSingleGroupToIFSForPallet(group); + } log.info("IFS批量移库同步完成,共{}个分组", moveGroups.size()); @@ -343,27 +343,28 @@ public class InventoryMoveServiceImpl implements InventoryMoveService { try { log.info("开始校验库存数量,共{}个分组需要校验", moveGroups.size()); - // 按站点分组获取库存信息,减少API调用次数 - Map> siteInventoryMap = new HashMap<>(); + // 按站点+物料分组获取库存信息,减少API调用次数 + Map> inventoryMap = new HashMap<>(); - for (MoveGroup group : moveGroups.values()) { - String site = group.site; - if (!siteInventoryMap.containsKey(site)) { - // 获取该站点的所有库存信息 - List inventoryList = ifsApiService.getInventoryPartInStock(site); - siteInventoryMap.put(site, inventoryList); - log.info("获取站点{}的库存信息,共{}条记录", site, inventoryList.size()); - } - } + for (MoveGroup group : moveGroups.values()) { + String key = group.site + "-" + group.partNo; // 使用site+partNo作为复合key + if (!inventoryMap.containsKey(key)) { + // 获取该站点指定物料的库存信息 + List inventoryList = ifsApiService.getInventoryPartInStock(group.site, group.partNo); + inventoryMap.put(key, inventoryList); + log.info("获取站点{}物料{}的库存信息,共{}条记录", group.site, group.partNo, inventoryList.size()); + } + } - // 校验每个分组的库存是否足够 - List insufficientStockErrors = new ArrayList<>(); + // 校验每个分组的库存是否足够 + List insufficientStockErrors = new ArrayList<>(); - for (MoveGroup group : moveGroups.values()) { - List siteInventory = siteInventoryMap.get(group.site); + for (MoveGroup group : moveGroups.values()) { + String key = group.site + "-" + group.partNo; + List inventoryList = inventoryMap.get(key); - // 查找匹配的库存记录 - IfsInventoryPartInStock matchedStock = findMatchingStock(siteInventory, group); + // 查找匹配的库存记录 + IfsInventoryPartInStock matchedStock = findMatchingStock(inventoryList, group); if (matchedStock == null) { insufficientStockErrors.add(String.format( @@ -403,23 +404,27 @@ public class InventoryMoveServiceImpl implements InventoryMoveService { } } - /** - * 查找匹配的库存记录 - * @param inventoryList 库存列表 - * @param group 移库分组 - * @return 匹配的库存记录,未找到返回null - */ - private IfsInventoryPartInStock findMatchingStock(List inventoryList, MoveGroup group) { - for (IfsInventoryPartInStock stock : inventoryList) { - // 匹配条件:物料号、批次号、库位号 - if (group.partNo.equals(stock.getPartNo()) && - group.lotBatchNo.equals(stock.getLotBatchNo()) && - group.sourceLocationNo.equals(stock.getLocationNo())) { - return stock; - } - } - return null; - } + /** + * 查找匹配的库存记录 + * @param inventoryList 库存列表 + * @param group 移库分组 + * @return 匹配的库存记录,未找到返回null + */ + private IfsInventoryPartInStock findMatchingStock(List inventoryList, MoveGroup group) { + for (IfsInventoryPartInStock stock : inventoryList) { + // 匹配条件:物料号、批次号、库位号、WDR + boolean partNoMatch = group.partNo.equals(stock.getPartNo()); + boolean lotBatchNoMatch = group.lotBatchNo.equals(stock.getLotBatchNo()); + boolean locationNoMatch = group.sourceLocationNo.equals(stock.getLocationNo()); + boolean wdrMatch = (group.wdr == null && stock.getWaivDevRejNo() == null) || + (group.wdr != null && group.wdr.equals(stock.getWaivDevRejNo())); + + if (partNoMatch && lotBatchNoMatch && locationNoMatch && wdrMatch) { + return stock; + } + } + return null; + } /** * 同步单个分组到IFS @@ -659,18 +664,19 @@ public class InventoryMoveServiceImpl implements InventoryMoveService { return inventoryGroups; } - /** - * 移库分组内部类 - */ - private static class MoveGroup { - String site; - String partNo; - String sourceLocationNo; - String destLocationNo; - String lotBatchNo; - BigDecimal totalQty; - Date expiredDate; - } + /** + * 移库分组内部类 + */ + private static class MoveGroup { + String site; + String partNo; + String sourceLocationNo; + String destLocationNo; + String lotBatchNo; + String wdr; + BigDecimal totalQty; + Date expiredDate; + } /** * 库存分组内部类 - 按库存主键字段分组