liu
13 小时以前 1eb432710b7a3a2e820be10b17c0138b377ee1b8
仓储物流-采购退货新增关联采购订单及带入物料功能
已修改7个文件
114 ■■■■■ 文件已修改
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorSaveReqVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
@@ -146,6 +146,14 @@
        return success(returnVendorService.checkReturnVendorQuantity(id));
    }
    @PostMapping("/import-purchase-order-items")
    @Operation(summary = "根据关联采购订单带入物料明细")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:update')")
    public CommonResult<Integer> importPurchaseOrderItems(@RequestParam("id") Long id) {
        return success(returnVendorService.importPurchaseOrderItems(id));
    }
    // ==================== 拼接 VO ====================
    private List<MesWmReturnVendorRespVO> buildRespVOList(List<MesWmReturnVendorDO> list) {
@@ -158,8 +166,10 @@
                .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, s -> s));
        // 2. 构建结果
        return BeanUtils.toBean(list, MesWmReturnVendorRespVO.class, vo ->
                MapUtils.findAndThen(vendorMap, vo.getVendorId(), vendor ->
                        vo.setVendorName(vendor.getName())));
                MapUtils.findAndThen(vendorMap, vo.getVendorId(), vendor -> {
                    vo.setVendorName(vendor.getName());
                    vo.setVendorCode(vendor.getCode());
                }));
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
@@ -18,6 +18,9 @@
    @Schema(description = "退货单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "供应商退货")
    private String name;
    @Schema(description = "采购订单编号", example = "1")
    private Long purchaseOrderId;
    @Schema(description = "采购订单编号", example = "PO20250226001")
    private String purchaseOrderCode;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorSaveReqVO.java
@@ -22,6 +22,9 @@
    @NotBlank(message = "退货单名称不能为空")
    private String name;
    @Schema(description = "采购订单编号", example = "1")
    private Long purchaseOrderId;
    @Schema(description = "采购订单编号", example = "PO20250226001")
    private String purchaseOrderCode;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
@@ -38,6 +38,12 @@
    private String name;
    /**
     * 采购订单编号
     *
     * 关联 ERP 采购订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO#getId()}
     */
    private Long purchaseOrderId;
    /**
     * 采购订单编码(冗余字段,用于显示)
     */
    private String purchaseOrderCode;
    /**
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -615,6 +615,8 @@
    ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "供应商退货单明细不存在");
    ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_711_201, "退货明细数量必须大于 0");
    ErrorCode WM_RETURN_VENDOR_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_711_202, "拣货明细不属于指定的供应商退货单");
    ErrorCode WM_RETURN_VENDOR_PURCHASE_ORDER_REQUIRED = new ErrorCode(1_040_711_008, "请先选择采购订单");
    ErrorCode WM_RETURN_VENDOR_PURCHASE_ORDER_NO_ITEM = new ErrorCode(1_040_711_009, "采购订单无明细数据,无法带入物料");
    // ========== MES 仓库管理-产品收货单(1-040-712-000) ==========
    ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "产品收货单不存在");
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
@@ -102,6 +102,14 @@
    Long getReturnVendorCountByVendorId(Long vendorId);
    /**
     * 根据关联的采购订单,带入物料明细到退货单行
     *
     * @param id 退货单编号
     * @return 带入的物料行数
     */
    int importPurchaseOrderItems(Long id);
    /**
     * 校验供应商退货单存在且为草稿状态
     *
     * @param id 编号
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
@@ -8,6 +8,7 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
@@ -15,6 +16,9 @@
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO;
import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
@@ -24,7 +28,9 @@
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -48,12 +54,16 @@
    private SrmSupplierApi srmSupplierApi;
    @Resource
    private MesWmTransactionService wmTransactionService;
    @Resource
    private ErpPurchaseOrderApi purchaseOrderApi;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createReturnVendor(MesWmReturnVendorSaveReqVO createReqVO) {
        // 1. 校验数据
        validateReturnVendorSaveData(createReqVO);
        // 1.1. 若采购订单号为空但关联了采购订单,则从 ERP 采购订单补齐订单号
        fillPurchaseOrderCode(createReqVO);
        // 2. 插入主表
        MesWmReturnVendorDO returnVendor = BeanUtils.toBean(createReqVO, MesWmReturnVendorDO.class);
@@ -67,10 +77,29 @@
    public void updateReturnVendor(MesWmReturnVendorSaveReqVO updateReqVO) {
        // 1. 校验数据
        validateReturnVendorSaveData(updateReqVO);
        // 1.1. 若采购订单号为空但关联了采购订单,则从 ERP 采购订单补齐订单号
        fillPurchaseOrderCode(updateReqVO);
        // 2. 更新主表
        MesWmReturnVendorDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnVendorDO.class);
        returnVendorMapper.updateById(updateObj);
    }
    /**
     * 当采购订单号为空、但关联了采购订单时,从 ERP 采购订单补齐采购订单号
     */
    private void fillPurchaseOrderCode(MesWmReturnVendorSaveReqVO reqVO) {
        if (reqVO == null || reqVO.getPurchaseOrderId() == null) {
            return;
        }
        if (cn.hutool.core.util.StrUtil.isNotBlank(reqVO.getPurchaseOrderCode())) {
            return;
        }
        ErpPurchaseOrderRespDTO purchaseOrder =
                purchaseOrderApi.getPurchaseOrder(reqVO.getPurchaseOrderId()).getCheckedData();
        if (purchaseOrder != null) {
            reqVO.setPurchaseOrderCode(purchaseOrder.getNo());
        }
    }
    @Override
@@ -240,4 +269,53 @@
        return returnVendorMapper.selectCountByVendorId(vendorId);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int importPurchaseOrderItems(Long id) {
        // 1. 校验退货单存在且为草稿状态
        MesWmReturnVendorDO returnVendor = validateReturnVendorExistsAndPrepare(id);
        if (returnVendor.getPurchaseOrderId() == null) {
            throw exception(WM_RETURN_VENDOR_PURCHASE_ORDER_REQUIRED);
        }
        // 2. 获取采购订单及明细
        ErpPurchaseOrderRespDTO purchaseOrder = purchaseOrderApi.getPurchaseOrder(returnVendor.getPurchaseOrderId()).getCheckedData();
        if (purchaseOrder == null) {
            throw exception(WM_PURCHASE_ORDER_NOT_EXISTS);
        }
        List<ErpPurchaseOrderItemRespDTO> items = purchaseOrderApi.getPurchaseOrderItemList(returnVendor.getPurchaseOrderId()).getCheckedData();
        if (CollUtil.isEmpty(items)) {
            throw exception(WM_RETURN_VENDOR_PURCHASE_ORDER_NO_ITEM);
        }
        // 3. 已存在的行物料集合(按物料去重,避免重复带入)
        Set<Long> existsItemIds = new HashSet<>();
        List<MesWmReturnVendorLineDO> existingLines = returnVendorLineService.getReturnVendorLineListByReturnId(id);
        if (CollUtil.isNotEmpty(existingLines)) {
            existsItemIds.addAll(convertList(existingLines, MesWmReturnVendorLineDO::getItemId));
        }
        // 4. 遍历采购订单明细,生成退货行(可退数量 = 已入库 - 已退货)
        int importedCount = 0;
        for (ErpPurchaseOrderItemRespDTO item : items) {
            if (item.getProductId() == null || existsItemIds.contains(item.getProductId())) {
                continue;
            }
            BigDecimal inCount = item.getInCount() != null ? item.getInCount() : BigDecimal.ZERO;
            BigDecimal returnCount = item.getReturnCount() != null ? item.getReturnCount() : BigDecimal.ZERO;
            BigDecimal quantity = inCount.subtract(returnCount);
            if (quantity.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            MesWmReturnVendorLineSaveReqVO lineReqVO = new MesWmReturnVendorLineSaveReqVO();
            lineReqVO.setReturnId(id);
            lineReqVO.setItemId(item.getProductId());
            lineReqVO.setQuantity(quantity);
            lineReqVO.setRemark(item.getRemark());
            returnVendorLineService.createReturnVendorLine(lineReqVO);
            importedCount++;
        }
        return importedCount;
    }
}