gaoluyang
4 天以前 d39e4f7d839167c16425086dfa2f8747bccfdff9
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.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO;
@@ -32,8 +33,7 @@
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import jakarta.annotation.Resource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -55,6 +55,7 @@
 */
@Service
@Validated
@Slf4j
public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService {
    /**
@@ -201,9 +202,13 @@
    @Transactional(rollbackFor = Exception.class)
    public void submitReturnVendorApproval(Long id, String processDefinitionKey) {
        // 1. 校验存在 + 草稿状态 + 至少一条行
        validateReturnVendorExistsAndPrepare(id);
        MesWmReturnVendorDO returnVendor = validateReturnVendorExistsAndPrepare(id);
        if (CollUtil.isEmpty(returnVendorLineService.getReturnVendorLineListByReturnId(id))) {
            throw exception(WM_RETURN_VENDOR_NO_LINE);
        }
        // 1.1. 质量部发起退货必须上传附件(质检报告、不合格照片等),否则审批人无法判断退货依据
        if (CollUtil.isEmpty(storageAttachmentApi.listAttachments(RETURN_VENDOR_RECORD_TYPE, id))) {
            throw exception(WM_RETURN_VENDOR_ATTACHMENT_REQUIRED, returnVendor.getCode());
        }
        // 2. 全局免审批:直接置为「待拣货」,无需流程模型
@@ -471,16 +476,16 @@
     * 获取当前用户编号(BPM 流程发起人、财务人员)
     */
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof Long) {
            return (Long) authentication.getPrincipal();
        }
        return null;
        // 统一从安全框架取登录用户;Spring Security 的 principal 是 LoginUser 而非 Long,
        // 直接强转会取到 null,导致 BPM 流程实例的发起人为字符串 "null"
        return SecurityFrameworkUtils.getLoginUserId();
    }
    private void createTransactionList(MesWmReturnVendorDO returnVendor, List<MesWmReturnVendorDetailDO> details) {
        wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
                .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
                // 按拣货时选中的库存记录扣减:生产批次可能没有 vendor_id,仅靠 物料+库位+批次+供应商 组合键会找不到库存
                .setMaterialStockId(detail.getMaterialStockId())
                .setQuantity(detail.getQuantity().negate()) // 出库数量为负数
                .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
                .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
@@ -581,8 +586,11 @@
        }
        try {
            importPurchaseOrderItems(id);
        } catch (ServiceException ignore) {
            // 采购订单无明细 / 无可退物料等业务异常:单据主体仍正常保存,可在物料区另行处理
        } catch (ServiceException ex) {
            // 采购订单无明细 / 无可退物料等业务异常:单据主体仍正常保存,可在物料区点「重新带入订单物料」补带
            // 打日志便于排查(例如:保存后才入库,此时订单还没有可退数量)
            log.warn("[autoImportLinesFromLinkedOrder][退货单({}) 关联采购订单({}) 自动带入物料失败:{}]",
                    id, returnVendor.getPurchaseOrderId(), ex.getMessage());
        }
    }