gaoluyang
2026-10-29 23317ed94a5e2d9b19c16627a70f9c7b69c908a2
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -85,7 +85,7 @@
                throw new RuntimeException("发货信息不存在");
            }
            for (ShippingProductDetail shippingProductDetail : shippingProductDetails) {
                stockUtils.substractStock(shippingProductDetail.getProductModelId(), shippingProductDetail.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(), shippingProductDetail.getBatchNo());
                deductOrRecordStock(shippingProductDetail, req.getId());
            }
        }
        byId.setExpressNumber(req.getExpressNumber());
@@ -143,14 +143,29 @@
    @Override
    public boolean add(ShippingInfoDto req) {
        this.save(req);
        req.getBatchNoDetailList().forEach(item -> item.setShippingInfoId(req.getId()));
        shippingProductDetailMapper.insert(req.getBatchNoDetailList());
        for (ShippingProductDetail shippingProductDetail : req.getBatchNoDetailList()) {
            stockUtils.substractStock(shippingProductDetail.getProductModelId(), shippingProductDetail.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(), shippingProductDetail.getBatchNo());
        List<ShippingProductDetail> detailList = req.getBatchNoDetailList();
        if (CollectionUtils.isNotEmpty(detailList)) {
            detailList.forEach(item -> item.setShippingInfoId(req.getId()));
            shippingProductDetailMapper.insert(detailList);
            for (ShippingProductDetail shippingProductDetail : detailList) {
                deductOrRecordStock(shippingProductDetail, req.getId());
            }
        }
        // 保存文件
        fileUtil.saveStorageAttachment(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, req.getId(), req.getStorageBlobDTOs());
        return true;
    }
    /**
     * 有库存批号的发货扣减库存;没有库存批号(未启用仓储模块)的发货只登记出库流水。
     */
    private void deductOrRecordStock(ShippingProductDetail detail, Long shippingInfoId) {
        String recordType = StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode();
        if (detail.getStockInventoryId() == null) {
            stockUtils.recordStockOutWithoutInventory(detail.getProductModelId(), detail.getQuantity(), recordType, shippingInfoId, detail.getBatchNo());
        } else {
            stockUtils.substractStock(detail.getProductModelId(), detail.getQuantity(), recordType, shippingInfoId, detail.getBatchNo());
        }
    }
    @Override
@@ -172,6 +187,17 @@
    @Override
    public boolean addReq(ShippingInfoDto req) {
        // 校验该产品是否已有待审核/审核中的发货记录,防止重复提交
        Long salesLedgerProductId = req.getSalesLedgerProductId();
        if (salesLedgerProductId != null) {
            long pendingCount = this.count(new LambdaQueryWrapper<ShippingInfo>()
                    .eq(ShippingInfo::getSalesLedgerProductId, salesLedgerProductId)
                    .in(ShippingInfo::getStatus, "待审核", "审核中"));
            if (pendingCount > 0) {
                throw new RuntimeException("该产品已有待审核的发货记录,请勿重复提交");
            }
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH","shipping_no",req.getCreateTime());
        // 先保存发货单,再发起审批;无审核人自动通过时需要按发货编号回写发货状态。
@@ -179,9 +205,19 @@
        req.setStatus("待审核");
        boolean save = this.add(req);
        // 发货审批
        ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
                new LambdaQueryWrapper<ApprovalTemplate>()
                        .eq(ApprovalTemplate::getBusinessType, 7L)
                        .eq(ApprovalTemplate::getDeleted, 0)
                        .orderByDesc(ApprovalTemplate::getId)
                        .last("LIMIT 1")
        );
        if (approvalTemplate == null) {
            throw new RuntimeException("请先配置发货审批模板");
        }
        ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
        approvalInstance.setTemplateId(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,7L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getId());
        approvalInstance.setTemplateName(approvalTemplateMapper.selectOne(new LambdaQueryWrapper<ApprovalTemplate>().eq(ApprovalTemplate::getBusinessType,7L).orderByDesc(ApprovalTemplate::getId).last("LIMIT 1")).getTemplateName());
        approvalInstance.setTemplateId(approvalTemplate.getId());
        approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
        approvalInstance.setBusinessId(req.getId());
        approvalInstance.setBusinessType(7L);
        approvalInstance.setCurrentLevel(1);
@@ -190,6 +226,9 @@
        approvalInstance.setApplicantName(loginUser.getNickName());
        approvalInstance.setApplyTime(LocalDateTime.now());
        approvalInstanceService.add(approvalInstance);
        // 创建审批实例后,更新发货状态为"审核中",使前端正确显示审批状态
        req.setStatus("审核中");
        this.updateById(req);
        return true;
    }
}