liyong
2026-05-14 4336d99906953517399187638925817d969c4e10
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -3,7 +3,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.ReviewStatusEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.ServiceException;
@@ -23,8 +22,8 @@
import com.ruoyi.stock.pojo.StockInRecord;
import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.stock.pojo.StockOutRecord;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockOutRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -96,7 +95,7 @@
            baseMapper.insert(orderPick);
            // 先新增出库申请,再审批通过,完成库存扣减。
            subtractInventory(orderPick.getId(), resolvedDto.getProductModelId(), storedBatchNo, resolvedDto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE);
//            subtractInventory(orderPick.getId(), resolvedDto.getProductModelId(), storedBatchNo, resolvedDto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE);
            // 记录本次领料流水(before=0,after=本次领料量)。
            insertPickRecord(orderPick.getId(),
@@ -216,7 +215,7 @@
            }
            String oldBatchNo = resolveInventoryBatchNoFromStored(existingPick.getBatchNo());
            BigDecimal oldQuantity = defaultDecimal(existingPick.getQuantity());
            addInventory(existingPick.getId(), existingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
//            addInventory(existingPick.getId(), existingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
            // 删除关联领料流水,避免遗留无主记录。
            productionOrderPickRecordMapper.delete(
                    Wrappers.<ProductionOrderPickRecord>lambdaQuery()
@@ -260,7 +259,7 @@
        for (ProductionOrderPick missingPick : missingPickList) {
            String oldBatchNo = resolveInventoryBatchNoFromStored(missingPick.getBatchNo());
            BigDecimal oldQuantity = defaultDecimal(missingPick.getQuantity());
            addInventory(missingPick.getId(), missingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
//            addInventory(missingPick.getId(), missingPick.getProductModelId(), oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
            // 删除关联领料流水,避免遗留无主记录。
            productionOrderPickRecordMapper.delete(
                    Wrappers.<ProductionOrderPickRecord>lambdaQuery()
@@ -306,7 +305,7 @@
        baseMapper.insert(orderPick);
        // 先新增出库申请,再审批通过,完成库存扣减。
        subtractInventory(orderPick.getId(), dto.getProductModelId(), storedBatchNo, dto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE);
//        subtractInventory(orderPick.getId(), dto.getProductModelId(), storedBatchNo, dto.getPickQuantity(), rowNo, PICK_STOCK_OUT_RECORD_TYPE);
        insertPickRecord(orderPick.getId(),
                dto.getProductionOrderId(),
@@ -365,7 +364,7 @@
                : formatBatchNoStorage(batchNoList);
        BigDecimal feedingQuantity = dto.getFeedingQuantity();
        subtractInventory(oldPick.getId(), productModelId, inventoryBatchNo, feedingQuantity, rowNo, FEED_STOCK_OUT_RECORD_TYPE);
//        subtractInventory(oldPick.getId(), productModelId, inventoryBatchNo, feedingQuantity, rowNo, FEED_STOCK_OUT_RECORD_TYPE);
        // 计算补料前后数量并写补料流水。
        BigDecimal beforeFeedingQty = sumFeedingQuantity(dto.getProductionOrderId(), oldPick.getId());
@@ -430,7 +429,7 @@
        BigDecimal totalReturnQty = oldReturnQty.add(currentReturnQty);
        if (currentReturnQty.compareTo(BigDecimal.ZERO) > 0) {
            String returnBatchNo = resolveInventoryBatchNoFromStored(oldPick.getBatchNo());
            addInventory(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE);
//            addInventoryRecordOnly(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE);
        }
        BigDecimal actualQty = defaultDecimal(oldPick.getQuantity())
@@ -487,15 +486,15 @@
            BigDecimal deltaQuantity = newQuantity.subtract(oldQuantity);
            if (deltaQuantity.compareTo(BigDecimal.ZERO) > 0) {
                // 数量增加,只扣减新增部分。
                subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, deltaQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE);
//                subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, deltaQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE);
            } else if (deltaQuantity.compareTo(BigDecimal.ZERO) < 0) {
                // 数量减少,只回退差值部分。
                addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, deltaQuantity.abs(), PICK_RETURN_IN_RECORD_TYPE);
//                addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, deltaQuantity.abs(), PICK_RETURN_IN_RECORD_TYPE);
            }
        } else {
            // 规格或批次变化:先全量回退旧领料,再全量扣减新领料。
            addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
            subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, newQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE);
//            addInventory(oldPick.getId(), oldProductModelId, oldBatchNo, oldQuantity, PICK_RETURN_IN_RECORD_TYPE);
//            subtractInventory(oldPick.getId(), newProductModelId, newStoredBatchNo, newQuantity, rowNo, PICK_STOCK_OUT_RECORD_TYPE);
        }
        if (needReissuePickRecord) {
            // 正常领料流水按“最新领料量”重建,避免保留历史旧值。
@@ -635,7 +634,7 @@
                continue;
            }
            BigDecimal currentDeductQuantity = remainingQuantity.min(availableQuantity);
            createAndApproveStockOutRecord(recordId, productModelId, entry.getKey(), currentDeductQuantity, rowNo, stockOutRecordType);
//            createAndApproveStockOutRecord(recordId, productModelId, entry.getKey(), currentDeductQuantity, rowNo, stockOutRecordType);
            remainingQuantity = remainingQuantity.subtract(currentDeductQuantity);
        }
@@ -674,14 +673,14 @@
            } else {
                recordWrapper.eq(StockOutRecord::getBatchNo, batchNo);
            }
            StockOutRecord stockOutRecord = stockOutRecordService.getOne(recordWrapper, false);
            if (stockOutRecord == null || stockOutRecord.getId() == null) {
                throw new ServiceException("第" + rowNo + "行扣减库存失败:未找到对应出库申请记录");
            }
            stockOutRecordService.batchApprove(
                    Collections.singletonList(stockOutRecord.getId()),
                    ReviewStatusEnum.APPROVED.getCode()
            );
//            StockOutRecord stockOutRecord = stockOutRecordService.getOne(recordWrapper, false);
//            if (stockOutRecord == null || stockOutRecord.getId() == null) {
//                throw new ServiceException("第" + rowNo + "行扣减库存失败:未找到对应出库申请记录");
//            }
//            stockOutRecordService.batchApprove(
//                    Collections.singletonList(stockOutRecord.getId()),
//                    ReviewStatusEnum.APPROVED.getCode()
//            );
        } catch (ServiceException ex) {
            throw ex;
        } catch (Exception ex) {
@@ -726,10 +725,10 @@
            if (stockInRecord == null || stockInRecord.getId() == null) {
                throw new ServiceException("回补库存失败:未找到对应入库申请记录");
            }
            stockInRecordService.batchApprove(
                    Collections.singletonList(stockInRecord.getId()),
                    ReviewStatusEnum.APPROVED.getCode()
            );
//            stockInRecordService.batchApprove(
//                    Collections.singletonList(stockInRecord.getId()),
//                    ReviewStatusEnum.APPROVED.getCode(),stockInRecord.getWarehouseInfoId()
//            );
        } catch (ServiceException ex) {
            throw ex;
        } catch (Exception ex) {
@@ -737,6 +736,31 @@
        }
    }
    private void addInventoryRecordOnly(Long recordId,
                                        Long productModelId,
                                        String batchNo,
                                        BigDecimal quantity,
                                        String stockInRecordType) {
        // 仅记录入库申请,不做审核通过。
        BigDecimal addQuantity = defaultDecimal(quantity);
        if (addQuantity.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        try {
            StockInventoryDto stockInventoryDto = new StockInventoryDto();
            stockInventoryDto.setProductModelId(productModelId);
            stockInventoryDto.setBatchNo(batchNo);
            stockInventoryDto.setQualitity(addQuantity);
            stockInventoryDto.setRecordType(stockInRecordType);
            stockInventoryDto.setRecordId(recordId == null ? 0L : recordId);
            stockInventoryService.addStockInRecordOnly(stockInventoryDto);
        } catch (ServiceException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new ServiceException("退料入库记录保存失败:" + ex.getMessage());
        }
    }
    private List<ProductionOrderPickDto> resolvePickItems(ProductionOrderPickDto dto) {
        // 解析新增场景的领料明细集合。
        if (dto == null) {