feat: 添加功能:采购单退库

This commit is contained in:
曹鹏飞 2025-08-04 18:45:38 +08:00
parent b1765b65a0
commit b2c2495938
6 changed files with 180 additions and 20 deletions

View File

@ -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<Void> save(@Valid @RequestBody Zim001QueryResultDTO request){
VUtil.trueThrowBusinessError(request.getItem1().stream().map(Zim001QueryResultItem1DTO::getEBELN).collect(Collectors.toSet()).size()>1)
public ApiResult<Void> 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<InventoryDTO> inventories = new ArrayList<>();
List<String> 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();
}

View File

@ -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;
}

View File

@ -78,6 +78,7 @@ public class Zim001QueryResultItem1DTO {
/**
* 二维码内容
*/
@NotBlank
private String qrCode;
/**

View File

@ -43,7 +43,10 @@
<artifactId>freemarker</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@ -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;
/**
* <p>
* 服务类
@ -13,4 +16,7 @@ import com.nflg.wms.repository.entity.WmsInventory;
*/
public interface IWmsInventoryService extends IService<WmsInventory> {
void out(List<InventoryDTO> inventories);
void in(List<InventoryDTO> inventories);
}

View File

@ -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;
/**
* <p>
* 服务实现类
* 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
@Service
public class WmsInventoryServiceImpl extends ServiceImpl<WmsInventoryMapper, WmsInventory> implements IWmsInventoryService {
@Transactional
@Retryable(
noRetryFor = NflgException.class,
maxAttempts = 10, // 最大重试次数包括第一次调用
backoff = @Backoff(delay = 500)
)
@Override
public void out(List<InventoryDTO> inventories) {
List<String> errorMaterialNos = new ArrayList<>();
List<WmsInventory> 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<InventoryDTO> inventories) {
List<WmsInventory> forAdd = new ArrayList<>();
List<WmsInventory> 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);
}
}
}