From b2c249593819282b3aa355269b4822e9892a5b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Mon, 4 Aug 2025 18:45:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9A=E9=87=87=E8=B4=AD=E5=8D=95=E9=80=80=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OutPurchaseController.java | 62 +++++++++---- .../wms/common/pojo/dto/InventoryDTO.java | 36 ++++++++ .../pojo/dto/Zim001QueryResultItem1DTO.java | 1 + nflg-wms-repository/pom.xml | 5 +- .../service/IWmsInventoryService.java | 6 ++ .../service/impl/WmsInventoryServiceImpl.java | 90 ++++++++++++++++++- 6 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/InventoryDTO.java diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutPurchaseController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutPurchaseController.java index 61138392..e57dda81 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutPurchaseController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/OutPurchaseController.java @@ -1,10 +1,13 @@ package com.nflg.wms.admin.controller; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.nflg.wms.admin.service.BinService; import com.nflg.wms.admin.service.SapService; import com.nflg.wms.admin.util.NoUtil; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; +import com.nflg.wms.common.pojo.dto.InventoryDTO; import com.nflg.wms.common.pojo.dto.Zim001QueryResultDTO; import com.nflg.wms.common.pojo.dto.Zim001QueryResultItem1DTO; import com.nflg.wms.common.pojo.qo.OutPurchaseSearchQO; @@ -13,6 +16,7 @@ import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.WmsOutPurchase; import com.nflg.wms.repository.entity.WmsOutPurchaseItem; +import com.nflg.wms.repository.service.IWmsInventoryService; import com.nflg.wms.repository.service.IWmsOutPurchaseItemService; import com.nflg.wms.repository.service.IWmsOutPurchaseService; import com.nflg.wms.starter.BaseController; @@ -23,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -45,6 +50,9 @@ public class OutPurchaseController extends BaseController { @Resource private BinService binService; + @Resource + IWmsInventoryService inventoryService; + /** * 获取采购退库信息 * @param orderNo 采购单号 @@ -65,11 +73,11 @@ public class OutPurchaseController extends BaseController { */ @Transactional @PostMapping("save") - public ApiResult save(@Valid @RequestBody Zim001QueryResultDTO request){ - VUtil.trueThrowBusinessError(request.getItem1().stream().map(Zim001QueryResultItem1DTO::getEBELN).collect(Collectors.toSet()).size()>1) + public ApiResult save(@Valid @RequestBody Zim001QueryResultDTO request) { + VUtil.trueThrowBusinessError(request.getItem1().stream().map(Zim001QueryResultItem1DTO::getEBELN).collect(Collectors.toSet()).size() > 1) .throwMessage("采购单号不唯一"); - Zim001QueryResultItem1DTO item=request.getItem1().get(0); - WmsOutPurchase purchase=new WmsOutPurchase() + Zim001QueryResultItem1DTO item = request.getItem1().get(0); + WmsOutPurchase purchase = new WmsOutPurchase() .setNo(NoUtil.getOutPurchaseNo()) .setExternalOrderNo(item.getEBELN()) .setSupplierNo("") @@ -78,19 +86,39 @@ public class OutPurchaseController extends BaseController { .setCreateTime(LocalDateTime.now()); //TODO 设置供应商信息 outPurchaseService.save(purchase); - outPurchaseItemService.saveBatch(request.getItem1().parallelStream().map(it -> new WmsOutPurchaseItem() - .setPurchaseId(purchase.getId()) - .setRowNo(it.getEBELP()) - .setMaterialNo(it.getMATNR()) - .setMaterialDesc(it.getMAKTX()) - .setNum(it.getERFMG()) - .setUnit(it.getMEINS()) - .setBatchNo(it.getCHARG()) - .setFactoryNo(it.getWERKS()) - .setWarehouseNo(it.getLGORT()) - .set_101Year(it.getLFBJA()) - .set_101No(it.getLFBNR()) - .set_101Project(it.getLFPOS())).toList()); + List inventories = new ArrayList<>(); + List errors = new ArrayList<>(); + outPurchaseItemService.saveBatch(request.getItem1().parallelStream().map(it -> { + String batchNo = CollectionUtil.get(StrUtil.split(it.getQrCode(), ","), 7); + if (StrUtil.isBlank(batchNo) || !StrUtil.equals(batchNo, it.getCHARG())) { + errors.add(it.getMATNR()); + } + WmsOutPurchaseItem purchaseItem = new WmsOutPurchaseItem() + .setPurchaseId(purchase.getId()) + .setRowNo(it.getEBELP()) + .setMaterialNo(it.getMATNR()) + .setMaterialDesc(it.getMAKTX()) + .setNum(it.getERFMG()) + .setUnit(it.getMEINS()) + .setBatchNo(it.getCHARG()) + .setFactoryNo(it.getWERKS()) + .setWarehouseNo(it.getLGORT()) + .set_101Year(it.getLFBJA()) + .set_101No(it.getLFBNR()) + .set_101Project(it.getLFPOS()); + inventories.add(new InventoryDTO() + .setMaterialNo(it.getMATNR()) + .setFactoryNo(it.getWERKS()) + .setWarehouseNo(it.getLGORT()) + .setBatchNumber(it.getCHARG()) + .setNum(it.getERFMG().negate()) + ); + return purchaseItem; + }).toList() + ); + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(errors)).throwMessage("以下物料的批次号不符合要求:"+StrUtil.join(",",errors)); + //扣减库存 + inventoryService.out(inventories); sapService.zim001(request); return ApiResult.success(); } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/InventoryDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/InventoryDTO.java new file mode 100644 index 00000000..7fc46e37 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/InventoryDTO.java @@ -0,0 +1,36 @@ +package com.nflg.wms.common.pojo.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +public class InventoryDTO { + + /** + * 物料编号 + */ + private String materialNo; + + /** + * 工厂 + */ + private String factoryNo; + + /** + * 库位 + */ + private String warehouseNo; + + /** + * 批次号 + */ + private String batchNumber; + + /** + * 数量 + */ + private BigDecimal num; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/Zim001QueryResultItem1DTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/Zim001QueryResultItem1DTO.java index 94572c6b..7987643a 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/Zim001QueryResultItem1DTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/Zim001QueryResultItem1DTO.java @@ -78,6 +78,7 @@ public class Zim001QueryResultItem1DTO { /** * 二维码内容 */ + @NotBlank private String qrCode; /** diff --git a/nflg-wms-repository/pom.xml b/nflg-wms-repository/pom.xml index 407725fb..2c5fd037 100644 --- a/nflg-wms-repository/pom.xml +++ b/nflg-wms-repository/pom.xml @@ -43,7 +43,10 @@ freemarker test - + + org.springframework.retry + spring-retry + org.springframework.boot spring-boot-starter-test diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryService.java index 9482d0ff..208b2c54 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryService.java @@ -1,8 +1,11 @@ package com.nflg.wms.repository.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.wms.common.pojo.dto.InventoryDTO; import com.nflg.wms.repository.entity.WmsInventory; +import java.util.List; + /** *

* 服务类 @@ -13,4 +16,7 @@ import com.nflg.wms.repository.entity.WmsInventory; */ public interface IWmsInventoryService extends IService { + void out(List inventories); + + void in(List inventories); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryServiceImpl.java index a9d1dc78..65b1adf7 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryServiceImpl.java @@ -1,20 +1,106 @@ package com.nflg.wms.repository.service.impl; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.wms.common.exception.NflgException; +import com.nflg.wms.common.pojo.dto.InventoryDTO; +import com.nflg.wms.common.util.UserUtil; +import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.WmsInventory; import com.nflg.wms.repository.mapper.WmsInventoryMapper; import com.nflg.wms.repository.service.IWmsInventoryService; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; /** *

- * 服务实现类 + * 服务实现类 *

- * * @author 代码生成器生成 * @since 2025 */ @Service public class WmsInventoryServiceImpl extends ServiceImpl implements IWmsInventoryService { + @Transactional + @Retryable( + noRetryFor = NflgException.class, + maxAttempts = 10, // 最大重试次数(包括第一次调用) + backoff = @Backoff(delay = 500) + ) + @Override + public void out(List inventories) { + List errorMaterialNos = new ArrayList<>(); + List dbInventories = inventories.stream().map(inventory -> { + WmsInventory info = lambdaQuery() + .eq(WmsInventory::getMaterialNo, inventory.getMaterialNo()) + .eq(WmsInventory::getBatchNumber, inventory.getBatchNumber()) + .eq(WmsInventory::getFactoryNo, inventory.getFactoryNo()) + .eq(WmsInventory::getWarehouseNo, inventory.getWarehouseNo()) + .one(); + if (Objects.isNull(info) || info.getNum().compareTo(inventory.getNum()) < 0) { + errorMaterialNos.add(inventory.getMaterialNo()); + } else { + info.setNum(info.getNum().subtract(inventory.getNum())); + info.setUpdateBy(UserUtil.getUserName()); + info.setUpdateTime(LocalDateTime.now()); + } + return info; + } + ).toList(); + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(errorMaterialNos)) + .throwMessage("以下物料库存不足:"+StrUtil.join(",", errorMaterialNos)); + updateBatchById(dbInventories); + } + + @Transactional + @Retryable( + noRetryFor = NflgException.class, + maxAttempts = 10, // 最大重试次数(包括第一次调用) + backoff = @Backoff(delay = 500) + ) + @Override + public void in(List inventories) { + List forAdd = new ArrayList<>(); + List forUpdate = new ArrayList<>(); + inventories.forEach(inventory -> { + WmsInventory info = lambdaQuery() + .eq(WmsInventory::getMaterialNo, inventory.getMaterialNo()) + .eq(WmsInventory::getBatchNumber, inventory.getBatchNumber()) + .eq(WmsInventory::getFactoryNo, inventory.getFactoryNo()) + .eq(WmsInventory::getWarehouseNo, inventory.getWarehouseNo()) + .one(); + if (Objects.isNull(info)) { + info = new WmsInventory() + .setMaterialNo(inventory.getMaterialNo()) + .setBatchNumber(inventory.getBatchNumber()) + .setFactoryNo(inventory.getFactoryNo()) + .setWarehouseNo(inventory.getWarehouseNo()) + .setNum(inventory.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()); + forAdd.add(info); + } else { + info.setNum(info.getNum().add(inventory.getNum())); + info.setUpdateBy(UserUtil.getUserName()); + info.setUpdateTime(LocalDateTime.now()); + forUpdate.add(info); + } + } + ); + if (CollectionUtil.isNotEmpty(forAdd)) { + saveBatch(forAdd); + } + if (CollectionUtil.isNotEmpty(forUpdate)) { + updateBatchById(forUpdate); + } + } }