fix(inventory): 解决库存查询和入库出库逻辑中的缺陷

- 在组件出库控制器中增加库位条件以确保准确匹配库存记录
- 修复生产订单控制器中的空指针异常处理逻辑
- 为库存出入库DTO类添加安全的getter方法防止空指针错误
- 修正库位调拨功能中的事务注解和验证逻辑
- 优化质检收货流程中的任务确认逻辑并添加不合格品检查
- 清理代码中的多余空行和注释以提高可读性
- 修复库存服务中查询条件顺序问题确保正确的库存检索
This commit is contained in:
曹鹏飞 2026-03-30 16:18:57 +08:00
parent f004f434a5
commit aa72f63f35
10 changed files with 86 additions and 36 deletions

View File

@ -600,7 +600,9 @@ public class ComponentOutboundController extends BaseController {
&& StrUtil.equals(it.getFactoryNo(), factoryNo)
&& StrUtil.equals(it.getWarehouseNo(), warehouseNo)
&& StrUtil.equals(it.getBatchNo(), batchNumber)
&& StrUtil.equals(it.getSerialNo(), serialNo))
&& StrUtil.equals(it.getSerialNo(), serialNo)
&& StrUtil.equals(it.getBinLocation(), binNo)
)
.findFirst()
.orElse(null);
if (Objects.isNull(inventory)) {

View File

@ -118,6 +118,7 @@ public class InProduceOrderController extends BaseController {
/**
* 从SAP查询生产订单信息
*
* @param no 生产订单号
* @return 订单信息
*/
@ -128,6 +129,7 @@ public class InProduceOrderController extends BaseController {
/**
* 保存
*
* @param request 请求参数
*/
@Transactional
@ -220,6 +222,7 @@ public class InProduceOrderController extends BaseController {
/**
* 搜索
*
* @param request 搜索参数
* @return 搜索结果
*/
@ -230,6 +233,7 @@ public class InProduceOrderController extends BaseController {
/**
* 获取订单的物料列表
*
* @param id 订单ID
* @return 列表
*/
@ -248,6 +252,7 @@ public class InProduceOrderController extends BaseController {
/**
* 删除
*
* @param id 订单ID
*/
@Transactional
@ -264,6 +269,7 @@ public class InProduceOrderController extends BaseController {
/**
* 导出物料条码pdf(逐个)
*
* @param id 订单ID
* @param type 1逐个2一页
*/
@ -294,6 +300,7 @@ public class InProduceOrderController extends BaseController {
/**
* 导出物料标签图片ZIP
*
* @param id 订单ID
*/
@GetMapping(value = "exportItemImageZip", produces = "application/zip")
@ -329,6 +336,7 @@ public class InProduceOrderController extends BaseController {
/**
* 导出报工单PDF单个
*
* @param id 订单id
*/
@GetMapping("exportOrderPdf")
@ -338,6 +346,7 @@ public class InProduceOrderController extends BaseController {
/**
* 导出报工单PDF批量
*
* @param ids 订单id列表
*/
@PostMapping("exportOrderPdf1")
@ -372,6 +381,7 @@ public class InProduceOrderController extends BaseController {
/**
* 获取订单信息PDA使用
*
* @param no 报工单号
*/
@GetMapping("getOrderInfo")
@ -411,6 +421,7 @@ public class InProduceOrderController extends BaseController {
/**
* 收货和入库PDA使用
*
* @param request 请求参数
*/
@Transactional
@ -451,9 +462,9 @@ public class InProduceOrderController extends BaseController {
List<WmsQrCodeMaster> qrCodeMasters = CollectionUtil.isEmpty(allQrCodes)
? Collections.emptyList()
: qrCodeMasterService.lambdaQuery()
.ne(WmsQrCodeMaster::getProcessStage, BarCodeProcessStage.InBound.getState())
.in(WmsQrCodeMaster::getBarcodeCode, allQrCodes)
.list();
.ne(WmsQrCodeMaster::getProcessStage, BarCodeProcessStage.InBound.getState())
.in(WmsQrCodeMaster::getBarcodeCode, allQrCodes)
.list();
datas.forEach(it -> {
InventoryIn1ItemQO qitem = request.getItems().stream()
.filter(item -> Objects.equals(item.getItemId(), it.getId()))
@ -483,7 +494,7 @@ public class InProduceOrderController extends BaseController {
VUtil.trueThrowBusinessError(Objects.isNull(qrCodeMaster)).throwMessage("无效的二维码:" + iit.getQrCode());
VUtil.trueThrowBusinessError(Objects.equals(qrCodeMaster.getProcessStage(), BarCodeProcessStage.InBound.getState()))
.throwMessage("二维码" + iit.getQrCode() + "已入库");
it.getNum().subtract(qrCodeMaster.getQuantity());
it.setNum(it.getNum().subtract(qrCodeMaster.getQuantity()));
qrCodeMaster.setProcessStage(BarCodeProcessStage.InBound.getState());
qrCodeMaster.setFactoryCode(it.getFactoryNo());
qrCodeMaster.setStorageLocation(qitem.getWarehouseNo());

View File

@ -21,6 +21,7 @@ import com.nflg.wms.starter.annotation.ApiMark;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -31,6 +32,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 储位调拨
*/
@ -52,18 +54,20 @@ public class LocationTransferController extends BaseController {
@Resource
private IWmsTransferOrdersService transferOrdersService;
/**
* 获取包装码信息
*/
@PostMapping("search")
@ApiMark(moduleName = "获取转储信息", apiName = "获取物料的转储信息")
public ApiResult<PageData<TransferOrderVO>> search(@Valid @RequestBody TransferOrderSearchQO request) {
return ApiResult.success( transferOrdersService.search(request));
return ApiResult.success(transferOrdersService.search(request));
}
/**
* 储位转储
*/
@Transactional
@PostMapping("pda/transfer")
@ApiMark(moduleName = "转储", apiName = "物料进行转储")
public ApiResult<Void> changeLocation(@Valid @RequestBody LocationTransferQO request) {
@ -117,24 +121,34 @@ public class LocationTransferController extends BaseController {
item -> item.getBinLocation().equals(request.getBinLocation()))
.collect(Collectors.toList()).size();
VUtil.trueThrowBusinessError(count > 0).throwMessage("存在相同储位的二维码");
VUtil.trueThrowBusinessError(
allQcMasters.stream().map(WmsQrCodeMaster::getFactoryCode).toList().size() !=
allQcMasters.stream().map(WmsQrCodeMaster::getFactoryCode).collect(Collectors.toSet()).size()
).throwMessage("二维码所在工厂不一致");
VUtil.trueThrowBusinessError(
allQcMasters.stream().map(WmsQrCodeMaster::getStorageLocation).toList().size() !=
allQcMasters.stream().map(WmsQrCodeMaster::getStorageLocation).collect(Collectors.toSet()).size()
).throwMessage("二维码所在仓库不一致");
WmsBin wmsBin = wmsBinService.lambdaQuery().eq(WmsBin::getNo, request.getBinLocation())
.one();
// WmsBin wmsBin = wmsBinService.lambdaQuery().eq(WmsBin::getNo, request.getBinLocation())
// .one();
// VUtil.trueThrowBusinessError(ObjectUtil.isNull(wmsBin)).throwMessage("无效的储位");
// WmsWarehouse wmsWarehouse = warehouseService.lambdaQuery().eq(WmsWarehouse::getId, wmsBin.getWarehouseId())
// .one();
// VUtil.trueThrowBusinessError(ObjectUtil.isNull(wmsWarehouse)).throwMessage("无效的储位【仓库无效】");
//
// DictionaryItem dictionaryItem = dictionaryItemService.lambdaQuery()
// .eq(DictionaryItem::getId, wmsWarehouse.getFactoryId())
// .one();
// VUtil.trueThrowBusinessError(ObjectUtil.isNull(dictionaryItem)).throwMessage("无效的储位【工厂无效】");
WmsBin wmsBin = wmsBinService.getByCode(allQcMasters.get(0).getFactoryCode(), allQcMasters.get(0).getStorageLocation(), request.getBinLocation());
VUtil.trueThrowBusinessError(ObjectUtil.isNull(wmsBin)).throwMessage("无效的储位");
WmsWarehouse wmsWarehouse = warehouseService.lambdaQuery().eq(WmsWarehouse::getId, wmsBin.getWarehouseId())
.one();
VUtil.trueThrowBusinessError(ObjectUtil.isNull(wmsWarehouse)).throwMessage("无效的储位【仓库无效】");
DictionaryItem dictionaryItem = dictionaryItemService.lambdaQuery()
.eq(DictionaryItem::getId, wmsWarehouse.getFactoryId())
.one();
VUtil.trueThrowBusinessError(ObjectUtil.isNull(dictionaryItem)).throwMessage("无效的储位【工厂无效】");
Integer count2 = allQcMasters.stream().filter(
item -> !item.getFactoryCode().equals(dictionaryItem.getCode())
&& !item.getStorageLocation().equals(wmsWarehouse.getNo()))
.collect(Collectors.toList()).size();
VUtil.trueThrowBusinessError(count2 > 0).throwMessage("存在不同仓库的二维码");
// Integer count2 = allQcMasters.stream().filter(
// item -> !item.getFactoryCode().equals(dictionaryItem.getCode())
// && !item.getStorageLocation().equals(wmsWarehouse.getNo()))
// .collect(Collectors.toList()).size();
// VUtil.trueThrowBusinessError(count2 > 0).throwMessage("存在不同仓库的二维码");
// boolean hasDuplicates1 = allQcMasters.stream()
// .map(WmsQrCodeMaster::getBarcodeCode)
@ -151,7 +165,7 @@ public class LocationTransferController extends BaseController {
smallQrCodeMaster.setLastScanTime(LocalDateTime.now());
smallQrCodeMaster.setLastScanByname(UserUtil.getUserName());
// 只有当储位发生变化的时候才会触发这个出库和入库的逻辑
if (!smallQrCodeMaster.getPackagingType().equals((short)0)) {
if (!smallQrCodeMaster.getPackagingType().equals((short) 0)) {
WmsTransferOrders transferOrder = new WmsTransferOrders();
transferOrder.setId(IdUtil.getSnowflakeNextId())
.setBarcodeCode(smallQrCodeMaster.getBarcodeCode())
@ -198,9 +212,10 @@ public class LocationTransferController extends BaseController {
* 扫码获取扫码信息
*
* @param request
* @return
* @author
* */
* @return
* @author
*
*/
@PostMapping("pda/scan")
@ApiMark(moduleName = "扫码", apiName = "扫码获取扫码信息")
public ApiResult<QrCodeVO> scan(@Valid @RequestBody PackingPDASearchQO request) {

View File

@ -1,7 +1,6 @@
package com.nflg.wms.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.wms.admin.pojo.dto.*;
@ -35,7 +34,6 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.NumberUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@ -370,6 +368,7 @@ public class NormalQMController extends BaseController {
* @param request 任务ID
* @return
*/
@Transactional
@PostMapping("unscan/task/confirm")
@ApiMark(moduleName = "质检物料管理", apiName = "无码质检任务上架确认")
public ApiResult<Void> confirmNoScan(@Valid @RequestBody ReceiveQO request) {
@ -377,7 +376,7 @@ public class NormalQMController extends BaseController {
.lambdaQuery()
.in(WmsQcReceive::getId, request.getIds())
.ne(WmsQcReceive::getIsCompleted, 2)
.eq(WmsQcReceive::getIsCheck, true)
.eq(WmsQcReceive::getIsCheck, 1)
.list();
@ -387,9 +386,20 @@ public class NormalQMController extends BaseController {
//VUtil.trueThrowBusinessError(!qcReceive.getSourceType().equals(1)).throwMessage("不属于无码收货的采购单");
//根据ID获取到任务单
List<QCReceiveTaskConfirmQO> taskConfirmQOS = new ArrayList<>();
List<InCostCenterBackSubmitItemQRQO> qrCodes=new ArrayList<>();
for (WmsQcReceive qcReceive : qcReceives) {
List<QCTaskItemVO> tasks = normalQMControllerService.getTaskItem(qcReceive.getId());
if (CollectionUtil.isNotEmpty(tasks)) {
VUtil.trueThrowBusinessError(tasks.stream()
.anyMatch(task -> task.getUnqualifiedQty().compareTo(BigDecimal.ZERO) > 0)
).throwMessage("含有质检不合格物料,请扫码入库!");
qrCodeMasterService.getByExtendIds(tasks.stream().map(QCTaskItemVO::getId).toList())
.forEach(code->{
qrCodes.add(new InCostCenterBackSubmitItemQRQO()
.setBinNo("")
.setQrCode(code.getBarcodeCode())
);
});
for (QCTaskItemVO item : tasks) {
QCReceiveTaskConfirmQO taskConfirmQO = new QCReceiveTaskConfirmQO();
taskConfirmQO.setId(item.getId())
@ -403,6 +413,7 @@ public class NormalQMController extends BaseController {
.map(QCTaskItemScanCodesVO::getId)
.collect(Collectors.toList());
taskConfirmQO.setQcIdList(qcIdList);
taskConfirmQO.setReceiveItems(qrCodes);
taskConfirmQOS.add(taskConfirmQO);
}
}

View File

@ -21,7 +21,6 @@ import java.util.List;
/**
* 质检物料入库单
* @param request
* @return
*/
@RestController

View File

@ -4,6 +4,7 @@ import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.Objects;
@Data
@Accessors(chain = true)
@ -29,11 +30,19 @@ public class InventoryInDTO {
*/
private String batchNo;
public String getBatchNo() {
return Objects.isNull(batchNo) ? "" : batchNo;
}
/**
* 序列号
*/
private String serialNo;
public String getSerialNo() {
return Objects.isNull(serialNo) ? "" : serialNo;
}
/**
* 数量
*/
@ -44,6 +53,10 @@ public class InventoryInDTO {
*/
private String binLocation;
public String getBinLocation() {
return Objects.isNull(binLocation) ? "" : binLocation;
}
/**
* 优先级数字大优先
*/

View File

@ -53,7 +53,7 @@ public class InventoryOutDTO {
*/
private String binLocation;
public String geBbinLocation() {
public String getBinLocation() {
return Objects.isNull(binLocation) ? "" : binLocation;
}

View File

@ -1,6 +1,5 @@
package com.nflg.wms.common.pojo.qo;
import cn.hutool.core.date.DateTime;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -57,10 +57,10 @@ public class WmsInventoryServiceImpl extends ServiceImpl<WmsInventoryMapper, Wms
item.setNum(inventory.stream().map(InventoryOutDTO::getNum).reduce(BigDecimal.ZERO, BigDecimal::add));
List<WmsInventory> list = lambdaQuery()
.eq(WmsInventory::getMaterialNo, item.getMaterialNo())
.eq(WmsInventory::getBatchNo, item.getBatchNo())
.eq(WmsInventory::getSerialNo, item.getSerialNo())
.eq(WmsInventory::getFactoryNo, item.getFactoryNo())
.eq(WmsInventory::getWarehouseNo, item.getWarehouseNo())
.eq(WmsInventory::getBatchNo, item.getBatchNo())
.eq(WmsInventory::getSerialNo, item.getSerialNo())
.eq(WmsInventory::getBinLocation, item.getBinLocation())
.gt(WmsInventory::getNum, 0)
.orderByDesc(WmsInventory::getSort)
@ -117,10 +117,10 @@ public class WmsInventoryServiceImpl extends ServiceImpl<WmsInventoryMapper, Wms
InventoryInDTO item = inventory.get(0);
WmsInventory info = lambdaQuery()
.eq(WmsInventory::getMaterialNo, item.getMaterialNo())
.eq(WmsInventory::getBatchNo, item.getBatchNo())
.eq(WmsInventory::getSerialNo, item.getSerialNo())
.eq(WmsInventory::getFactoryNo, item.getFactoryNo())
.eq(WmsInventory::getWarehouseNo, item.getWarehouseNo())
.eq(WmsInventory::getBatchNo, item.getBatchNo())
.eq(WmsInventory::getSerialNo, item.getSerialNo())
.eq(WmsInventory::getBinLocation, item.getBinLocation())
.eq(WmsInventory::getSort, item.getOrder())
.one();

View File

@ -54,7 +54,7 @@
<if test="request.supplierNum !=null and request.supplierNum !=''">
and b.supplier_num =#{request.supplierNum}
</if>
<if test="request.isCheck !=null and request.isCheck !=''">
<if test="request.isCheck !=null">
and a.is_check =#{request.isCheck}
</if>
<if test="request.poNumber !=null and request.poNumber !='' ">