gaoluyang
昨天 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskResultServiceImpl.java
@@ -1,13 +1,17 @@
package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskResultMapper;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -15,10 +19,14 @@
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_RESULT_LINE_INVALID;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_RESULT_DUPLICATE;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_TRANSACTION_BATCH_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_TRANSACTION_BATCH_REQUIRED;
/**
 * MES 盘点结果 Service 实现类
@@ -36,6 +44,10 @@
    private MesWmStockTakingTaskLineService stockTakingTaskLineService;
    @Resource
    private MesWmStockTakingTaskService stockTakingTaskService;
    @Resource
    private MesWmBatchService batchService;
    @Resource
    private MesMdmItemService mdmItemService;
    @Override
    public PageResult<MesWmStockTakingTaskResultDO> getStockTakingTaskResultPage(
@@ -58,10 +70,17 @@
        Long lineId = createReqVO.getLineId();
        MesWmStockTakingTaskLineDO existingLine = null;
        if (lineId == null) {
            resolveBatch(createReqVO);
            // 2.1 基于 taskId + itemId + areaId 查询已存在的 line
            existingLine = stockTakingTaskLineService.getStockTakingTaskLine(
                    createReqVO.getTaskId(), createReqVO.getItemId(), createReqVO.getAreaId());
                    createReqVO.getTaskId(), createReqVO.getItemId(), createReqVO.getWarehouseId(),
                    createReqVO.getLocationId(), createReqVO.getAreaId(), createReqVO.getBatchId());
            if (existingLine != null) {
                if ((createReqVO.getBatchId() != null && !Objects.equals(existingLine.getBatchId(), createReqVO.getBatchId()))
                        || (StrUtil.isNotBlank(createReqVO.getBatchCode())
                        && !Objects.equals(existingLine.getBatchCode(), createReqVO.getBatchCode()))) {
                    throw exception(WM_STOCK_TAKING_TASK_RESULT_LINE_INVALID);
                }
                lineId = existingLine.getId();
            } else {
                // 2.2 创建新的 line(注意:当盘点结果没有对应的盘点清单行时,会自动创建一个新的盘点任务行)
@@ -71,16 +90,26 @@
            // 2.3 如果传递了 lineId,从 line 中获取 quantity
            existingLine = stockTakingTaskLineService.validateStockTakingTaskLineExists(lineId);
        }
        if (existingLine != null
                && existingLine.getTakingQuantity() != null
                && existingLine.getTakingQuantity().compareTo(BigDecimal.ZERO) > 0) {
            throw exception(WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN);
        if (existingLine == null) {
            existingLine = stockTakingTaskLineService.validateStockTakingTaskLineExists(lineId);
        }
        BigDecimal quantity = existingLine != null ? existingLine.getQuantity() : BigDecimal.ZERO; // 账面数量
        if (!ObjUtil.equal(existingLine.getTaskId(), createReqVO.getTaskId())
                || createReqVO.getTakingQuantity() == null || createReqVO.getTakingQuantity().signum() < 0) {
            throw exception(WM_STOCK_TAKING_TASK_RESULT_LINE_INVALID);
        }
        Long resolvedLineId = lineId;
        if (stockTakingTaskResultMapper.selectListByTaskId(createReqVO.getTaskId()).stream()
                .anyMatch(result -> ObjUtil.equal(result.getLineId(), resolvedLineId))) {
            throw exception(WM_STOCK_TAKING_TASK_RESULT_DUPLICATE);
        }
        // 3. 插入 result 记录
        MesWmStockTakingTaskResultDO result = BeanUtils.toBean(createReqVO, MesWmStockTakingTaskResultDO.class)
                .setLineId(lineId).setQuantity(ObjUtil.defaultIfNull(quantity, createReqVO.getTakingQuantity()));
                .setLineId(lineId).setQuantity(existingLine.getQuantity())
                .setMaterialStockId(existingLine.getMaterialStockId()).setItemId(existingLine.getItemId())
                .setBatchId(existingLine.getBatchId()).setBatchCode(existingLine.getBatchCode())
                .setWarehouseId(existingLine.getWarehouseId()).setLocationId(existingLine.getLocationId())
                .setAreaId(existingLine.getAreaId());
        stockTakingTaskResultMapper.insert(result);
        // 4. 更新 line 的盘点数量和状态
@@ -91,14 +120,21 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStockTakingTaskResult(MesWmStockTakingTaskResultSaveReqVO updateReqVO) {
        updateReqVO.setLineId(null); // lineId 不能修改,避免误操作
        // 1.1 校验记录存在
        MesWmStockTakingTaskResultDO oldResult = validateStockTakingTaskResultExists(updateReqVO.getId());
        // 1.2 校验任务处于盘点中状态
        stockTakingTaskService.validateStockTakingTaskExistsAndApproving(oldResult.getTaskId());
        if (updateReqVO.getTakingQuantity() == null || updateReqVO.getTakingQuantity().signum() < 0) {
            throw exception(WM_STOCK_TAKING_TASK_RESULT_LINE_INVALID);
        }
        // 2. 更新 result 记录
        MesWmStockTakingTaskResultDO result = BeanUtils.toBean(updateReqVO, MesWmStockTakingTaskResultDO.class);
        result.setTaskId(oldResult.getTaskId()).setLineId(oldResult.getLineId())
                .setMaterialStockId(oldResult.getMaterialStockId()).setItemId(oldResult.getItemId())
                .setBatchId(oldResult.getBatchId()).setBatchCode(oldResult.getBatchCode())
                .setWarehouseId(oldResult.getWarehouseId()).setLocationId(oldResult.getLocationId())
                .setAreaId(oldResult.getAreaId()).setQuantity(oldResult.getQuantity());
        stockTakingTaskResultMapper.updateById(result);
        // 3. 关联更新 line 的盘点数量(覆盖式更新)
@@ -119,7 +155,30 @@
        // 3. 更新对应 line 的盘点数量和状态
        stockTakingTaskLineService.updateStockTakingTaskLineTakingQuantity(
                result.getLineId(), result.getTakingQuantity().negate());
                result.getLineId(), BigDecimal.ZERO);
        stockTakingTaskLineService.deleteAutoGeneratedLine(result.getLineId());
    }
    private void resolveBatch(MesWmStockTakingTaskResultSaveReqVO reqVO) {
        MesWmBatchDO batch = null;
        if (reqVO.getBatchId() != null) {
            batch = batchService.getBatch(reqVO.getBatchId());
        } else if (StrUtil.isNotBlank(reqVO.getBatchCode())) {
            batch = batchService.getBatchByCode(reqVO.getBatchCode());
        }
        if (batch != null) {
            if (!Objects.equals(batch.getItemId(), reqVO.getItemId())
                    || (StrUtil.isNotBlank(reqVO.getBatchCode())
                    && !Objects.equals(batch.getCode(), reqVO.getBatchCode()))) {
                throw exception(WM_STOCK_TAKING_TASK_RESULT_LINE_INVALID);
            }
            reqVO.setBatchId(batch.getId());
            reqVO.setBatchCode(batch.getCode());
        } else if (reqVO.getBatchId() != null || StrUtil.isNotBlank(reqVO.getBatchCode())) {
            throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
        } else if (Boolean.TRUE.equals(mdmItemService.validateItemExists(reqVO.getItemId()).getIsBatchManaged())) {
            throw exception(WM_TRANSACTION_BATCH_REQUIRED);
        }
    }
    @Override