2 天以前 81592a7a4822b10c592d1d46193cf8f3becfc5be
Merge remote-tracking branch 'origin/dev_New_pro' into dev_New_pro
已修改18个文件
192 ■■■■■ 文件已修改
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/StorageBlobVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/utils/FileUtil.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoStageHandleService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingInfoMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInRecordMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockOutRecordMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -15,6 +15,7 @@
import com.ruoyi.basic.utils.FileUtil;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -31,14 +32,8 @@
import com.ruoyi.quality.pojo.QualityInspectParam;
import com.ruoyi.quality.pojo.QualityTestStandard;
import com.ruoyi.quality.pojo.QualityTestStandardParam;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -64,6 +59,7 @@
    private final PurchaseLedgerMapper purchaseLedgerMapper;
    private final SalesQuotationMapper salesQuotationMapper;
    private final ShippingInfoMapper shippingInfoMapper;
    private final ShippingProductDetailMapper shippingProductDetailMapper;
    private final CommonFileServiceImpl commonFileService;
    private final StockUtils stockUtils;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
@@ -183,7 +179,7 @@
                            addQualityInspect(purchaseLedger, salesLedgerProduct);
                        } else {
                            //直接入库
                            stockUtils.addStockWithBatchNo(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), purchaseLedger.getId(),purchaseLedger.getPurchaseContractNumber()+"-"+salesLedgerProduct.getId());
                            stockUtils.addStockWithBatchNo(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), purchaseLedger.getId(), purchaseLedger.getPurchaseContractNumber() + "-" + salesLedgerProduct.getId());
                        }
                    }
                } else if (status.equals(3)) {
@@ -220,6 +216,8 @@
            if (shippingInfo != null) {
                if (status.equals(2)) {
                    shippingInfo.setStatus("审核通过");
                    //更改出库审核状态(待确认改成待审核)
                    stockUtils.shipmentStatus(StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), shippingInfo.getId());
                } else if (status.equals(3)) {
                    shippingInfo.setStatus("审核拒绝");
                } else if (status.equals(1)) {
@@ -227,7 +225,6 @@
                }
                shippingInfoMapper.updateById(shippingInfo);
            }
            //库存扣减
        }
        fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.APPROVE_NODE, approveNode.getId(), approveNode.getStorageBlobDTOS());
src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -148,8 +148,8 @@
     * 私海客户流回公海
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/back")
    public R back(Long id) {
    @PostMapping("/back/{id}")
    public R back(@PathVariable("id") Long id) {
        return R.ok(customerService.back(id));
    }
}
src/main/java/com/ruoyi/basic/dto/StorageBlobVO.java
@@ -10,6 +10,10 @@
     */
    private String previewURL;
    private String url;
    private String name;
    /**
     * 下载地址
     */
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -375,7 +375,7 @@
        //将客户的type改为1 且直接分配给当前用户
        Customer customer = customerMapper.selectById(id);
        customer.setType(1);
        customer.setIsAssigned(1);
        customer.setIsAssigned(0);
        return this.updateById(customer);
    }
src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -98,8 +98,11 @@
        }
        // 删除旧附件信息
        if (application == null) {
        if (application == null || application.trim().isEmpty()) {
            for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
                if (storageBlobDTO.getApplication() == null || storageBlobDTO.getApplication().trim().isEmpty()) {
                    throw new RuntimeException("文件用途不能为空");
                }
                deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.getByType(storageBlobDTO.getApplication()), recordType, recordId);
            }
        } else {
@@ -344,6 +347,8 @@
            StorageBlobVO storageBlobVO = new StorageBlobVO();
            BeanUtils.copyProperties(storageBlob, storageBlobVO);
            storageBlobVO.setPreviewURL(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setUrl(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setName(storageBlob.getOriginalFilename());
            storageBlobVO.setDownloadURL(buildSignedDownloadUrl(storageBlobVO));
            storageBlobVO.setStorageAttachmentId(blobIdToAttachmentIdMap.get(storageBlob.getId()));
            storageBlobDTOS.add(storageBlobVO);
@@ -392,6 +397,8 @@
            StorageBlobVO storageBlobVO = new StorageBlobVO();
            BeanUtils.copyProperties(storageBlob, storageBlobVO);
            storageBlobVO.setPreviewURL(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setUrl(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setName(storageBlob.getOriginalFilename());
            storageBlobVO.setDownloadURL(buildSignedDownloadUrl(storageBlobVO));
            storageBlobVO.setStorageAttachmentId(blobIdToAttachmentIdMap.get(storageBlob.getId()));
            storageBlobDTOS.add(storageBlobVO);
@@ -417,6 +424,8 @@
            StorageBlobVO storageBlobVO = new StorageBlobVO();
            BeanUtils.copyProperties(storageBlob, storageBlobVO);
            storageBlobVO.setPreviewURL(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setUrl(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setName(storageBlob.getOriginalFilename());
            storageBlobVO.setDownloadURL(buildSignedDownloadUrl(storageBlobVO));
            storageBlobDTOS.add(storageBlobVO);
        }
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -1,5 +1,6 @@
package com.ruoyi.procurementrecord.utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
@@ -66,8 +67,6 @@
    /**
     * 合格入库
     * @param productModelId
     * @param quantity
     * @param recordType
     * @param recordId
     */
@@ -105,15 +104,6 @@
     * @param recordType
     * @param recordId
     */
    public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setRecordId(recordId);
        stockInventoryDto.setRecordType(String.valueOf(recordType));
        stockInventoryDto.setQualitity(quantity);
        stockInventoryDto.setProductModelId(productModelId);
        stockInventoryService.subtractStockInventory(stockInventoryDto);
    }
    public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo) {
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setRecordId(recordId);
@@ -121,7 +111,20 @@
        stockInventoryDto.setQualitity(quantity);
        stockInventoryDto.setProductModelId(productModelId);
        stockInventoryDto.setBatchNo(batchNo);
        stockInventoryService.subtractStockInventory(stockInventoryDto);
        stockInventoryService.addStockOutRecordOnly(stockInventoryDto);
    }
    /**
     * 发货审批状态更改
     * @param recordType
     * @param recordId
     */
    public void shipmentStatus(String recordType, Long recordId) {
        LambdaQueryWrapper<StockOutRecord> queryWrapper = new LambdaQueryWrapper<StockOutRecord>().eq(StockOutRecord::getRecordType, recordType)
                .eq(StockOutRecord::getRecordId, recordId);
        StockOutRecord stockOutRecord = stockOutRecordService.getOne(queryWrapper);
        stockOutRecord.setApprovalStatus(0);
        stockOutRecordService.updateById(stockOutRecord);
    }
    //不合格库存删除
src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java
@@ -54,7 +54,7 @@
    public void savePlan(SavePlanVo savePlanVo) {
        Plan plan = BeanUtil.copyProperties(savePlanVo, Plan.class);
        // 附件处理
        fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("", RecordTypeEnum.PLAN, savePlanVo.getId(), savePlanVo.getStorageBlobDTOs());
        fileUtil.saveStorageAttachmentByRecordTypeAndRecordId(null, RecordTypeEnum.PLAN, savePlanVo.getId(), savePlanVo.getStorageBlobDTOs());
        if (savePlanVo.getId() == null) {
            planMapper.insert(plan);
        } else {
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoStageHandleService.java
@@ -52,7 +52,7 @@
        String attachmentIds = StrUtil.join(",", Optional.ofNullable(saveInfoStageVo.getAttachmentIds()).orElse(Collections.emptyList()));
        infoStage.setAttachment(attachmentIds);
        fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("", RecordTypeEnum.INFO_STAGE, infoStage.getProjectManagementInfoId(), saveInfoStageVo.getStorageBlobDTOs());
        fileUtil.saveStorageAttachmentByRecordTypeAndRecordId(null, RecordTypeEnum.INFO_STAGE, infoStage.getProjectManagementInfoId(), saveInfoStageVo.getStorageBlobDTOs());
        if (infoStage.getId() == null) {
            infoStageMapper.insert(infoStage);
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -55,7 +55,7 @@
    @Override
    public IPage<ShippingInfoDto> listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfoDto> listPage = shippingInfoMapper.listPage(page, req);
        listPage.getRecords().forEach(item ->{
        listPage.getRecords().forEach(item -> {
            item.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, item.getId()));
        });
        return listPage;
@@ -68,7 +68,7 @@
            throw new RuntimeException("发货信息不存在");
        }
        //扣减库存
        if(!"已发货".equals(byId.getStatus())){
        if (!"已发货".equals(byId.getStatus())) {
            List<ShippingProductDetail> shippingProductDetails = shippingProductDetailMapper.selectList(new LambdaQueryWrapper<ShippingProductDetail>().eq(ShippingProductDetail::getShippingInfoId, req.getId()));
            if (CollectionUtils.isEmpty(shippingProductDetails)) {
                throw new RuntimeException("发货信息不存在");
@@ -85,28 +85,28 @@
        boolean update = this.updateById(byId);
        // 保存文件
        fileUtil.saveStorageAttachment(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, req.getId(), req.getStorageBlobDTOs());
        return update ;
        return update;
    }
    @Override
    public boolean delete(List<Long> ids) {
        List<ShippingInfo> shippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>()
                .in(ShippingInfo::getId, ids));
        if(CollectionUtils.isEmpty(shippingInfos)) return false;
        if (CollectionUtils.isEmpty(shippingInfos)) return false;
        // 删除附件
        commonFileService.deleteByBusinessIds(ids, FileNameType.SHIP.getValue());
        // 扣已发货库存
        for (ShippingInfo shippingInfo : shippingInfos) {
            if("已发货".equals(shippingInfo.getStatus())) {
            if ("已发货".equals(shippingInfo.getStatus())) {
                stockUtils.deleteStockOutRecord(shippingInfo.getId(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
            }
        }
        // 删除发货审批
        if(CollectionUtils.isNotEmpty(shippingInfos)){
            for (ShippingInfo shippingInfo : shippingInfos){
        if (CollectionUtils.isNotEmpty(shippingInfos)) {
            for (ShippingInfo shippingInfo : shippingInfos) {
                List<ApproveProcess> one = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>()
                        .like(ApproveProcess::getApproveReason, shippingInfo.getShippingNo()));
                if(one != null){
                if (one != null) {
                    List<Long> list = one.stream().map(ApproveProcess::getId).toList();
                    approveProcessService.delByIds(list);
                }
@@ -120,7 +120,7 @@
    @Override
    public List<SalesLedgerProductDto> getReturnManagementDtoById(Long shippingId) {
        return shippingInfoMapper.getReturnManagementDtoById(shippingId );
        return shippingInfoMapper.getReturnManagementDtoById(shippingId);
    }
@@ -131,9 +131,14 @@
    @Override
    public boolean add(ShippingInfoDto req) {
        this.save( 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());
        }
        // 保存文件
        fileUtil.saveStorageAttachment(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, req.getId(), req.getStorageBlobDTOs());
        return true;
    }
@@ -147,7 +152,7 @@
        ShippingApproveDto shippingApproveDto = new ShippingApproveDto();
        ShippingInfo shippingInfo = new ShippingInfo();
        shippingInfo.setShippingNo(shippingNo);
        shippingApproveDto.setShippingInfo(shippingInfoMapper.listPage(new Page(1, -1),shippingInfo).getRecords().get(0));
        shippingApproveDto.setShippingInfo(shippingInfoMapper.listPage(new Page(1, -1), shippingInfo).getRecords().get(0));
        List<ShippingProductDetailDto> dateilByShippingNo = shippingProductDetailMapper.getDateilByShippingNo(shippingNo);
        shippingApproveDto.setShippingProductDetailDtoList(dateilByShippingNo);
        return shippingApproveDto;
src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
@@ -75,7 +75,7 @@
    @Schema(description = "类型  0合格入库 1不合格入库")
    private String type;
    @Schema(description = "审批状态  0-待审批 1-通过 2-驳回", implementation = ReviewStatusEnum.class)
    @Schema(description = "审批状态  0-待审批 1-通过 2-驳回 3-销售出库待确认", implementation = ReviewStatusEnum.class)
    private Integer approvalStatus;
    @TableField(fill = FieldFill.INSERT)
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -20,7 +20,6 @@
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.mapper.StockOutRecordMapper;
import com.ruoyi.stock.mapper.StockUninventoryMapper;
import com.ruoyi.stock.pojo.StockInRecord;
import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.stock.pojo.StockOutRecord;
import com.ruoyi.stock.pojo.StockUninventory;
@@ -57,8 +56,9 @@
    public int add(StockOutRecordDto stockOutRecordDto) {
        String no = OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK","outbound_batches");
        stockOutRecordDto.setOutboundBatches(no);
        StockInRecord stockInRecord = new StockInRecord();
        BeanUtils.copyProperties(stockOutRecordDto, stockInRecord);
        if (StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode().equals(stockOutRecordDto.getRecordType())){
            stockOutRecordDto.setApprovalStatus(3);
        }
        return stockOutRecordMapper.insert(stockOutRecordDto);
    }
src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml
@@ -18,9 +18,9 @@
    <select id="pageSalesRefundAmountOrderDto" resultType="com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto">
        select sl.sales_contract_no,
        sl.customer_contract_no,
        slp.specification_model,
        slp.product_category as product_name,
        slp.unit,
        pm.model as specification_model,
        p.product_name ,
        pm.unit,
        sl.customer_name,
        rm.return_no as return_management_no,
        srao.*
@@ -28,6 +28,8 @@
        left join return_management rm on srao.return_management_id = rm.id
        left join return_sale_product rs on rm.id = rs.return_management_id
        left join sales_ledger_product slp on rs.return_sales_ledger_product_id = slp.id
        left join product_model pm on slp.product_model_id = pm.id
            left join product p on pm.product_id = p.id
        left join sales_ledger sl on slp.sales_ledger_id = sl.id
        <where>
            <if test="ew.salesContractNo != null and ew.salesContractNo !=''">
src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
@@ -11,9 +11,9 @@
        <result column="status" property="status" />
    </resultMap>
    <select id="listReturnSaleProductDto" resultType="com.ruoyi.procurementrecord.dto.ReturnSaleProductDto">
        SELECT slp.product_category                                         as product_name,
               slp.specification_model                                      as model,
               slp.unit                                      as unit,
        SELECT p.product_name                                         as product_name,
               pm.model                                     as model,
               pm.unit                                      as unit,
               rsp.*,
               GREATEST(slp.quantity - COALESCE(rs.total_return_num, 0), 0) AS un_quantity,
               COALESCE(rs.total_return_num, 0)                             AS total_return_num
@@ -21,6 +21,8 @@
                 LEFT JOIN return_management rm ON rm.id = rsp.return_management_id
                 LEFT JOIN shipping_info si ON si.id = rm.shipping_id
                 LEFT JOIN sales_ledger_product slp ON si.sales_ledger_product_id = slp.id and slp.type = 1
                left join product_model pm on slp.product_model_id = pm.id
                  LEFT JOIN product p on pm.product_id = p.id
                 LEFT JOIN (SELECT return_sales_ledger_product_id,
                                   SUM(num) AS total_return_num
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -6,7 +6,42 @@
    <select id="selectSalesLedgerProductList" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct">
        SELECT
        T1.*,
        T1.id,
        T1.sales_ledger_id,
        T1.warn_num,
        T1.speculative_trading_name,
        T1.quantity,
        T1.min_stock,
        T1.tax_rate,
        T1.tax_inclusive_unit_price,
        T1.tax_inclusive_total_price,
        T1.tax_exclusive_total_price,
        T1.invoice_type,
        T1.type,
        T1.tickets_num,
        T1.tickets_amount,
        T1.future_tickets,
        T1.future_tickets_amount,
        T1.invoice_num,
        T1.no_invoice_num,
        T1.invoice_amount,
        T1.no_invoice_amount,
        T1.product_id,
        T1.product_model_id,
        T1.register,
        T1.register_date,
        T1.approve_status,
        T1.pending_invoice_total,
        T1.invoice_total,
        T1.pending_tickets_total,
        T1.tickets_total,
        T1.is_checked,
        T1.is_production,
        T1.create_user,
        T1.dept_id,
        p.product_name as product_category,
        pm.model as specification_model,
        pm.unit as unit,
        CASE
        WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >0 THEN 1
        ELSE 0
@@ -29,6 +64,8 @@
        LEFT JOIN shipping_product_detail spd ON si.id = spd.shipping_info_id
        GROUP BY sales_ledger_product_id
        ) t3 ON t3.sales_ledger_product_id = T1.id
        left join product_model pm ON T1.product_model_id = pm.id
        left join product p ON pm.product_id = p.id
        <where>
            <if test="salesLedgerProduct.salesLedgerId != null">
                AND T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -19,7 +19,8 @@
        s.update_user,
        s.tenant_id,
        sl.sales_contract_no,
        slp.specification_model,
        pm.model as specification_model,
        pm.unit,
        p.product_name,
        sl.customer_name
        FROM shipping_info s
src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -77,7 +77,7 @@
            pl.supplier_name,
            DATE(sir.create_time) AS inboundDate,
            p.product_name,
            slp.specification_model,
            pm.model as specification_model,
            sor.stock_in_num * slp.tax_inclusive_unit_price AS InboundAmount,
            pl.purchase_contract_number
            FROM stock_in_record sir
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -436,7 +436,7 @@
        WHERE sor.product_model_id = #{productModelId}
          AND (sor.batch_no = #{batchNo} OR (#{batchNo} IS NULL AND sor.batch_no IS NULL))
          AND sor.type = #{type}
          AND sor.approval_status = 0
          AND sor.approval_status IN (0, 3)
    </select>
    <select id="listSelectableBatchNoByProductModelIds" resultType="com.ruoyi.stock.pojo.StockInventory">
@@ -453,12 +453,24 @@
        order by si.product_model_id, si.batch_no
    </select>
    <select id="getByModelId" resultType="com.ruoyi.stock.pojo.StockInventory">
        select spd.id, spd.batch_no, spd.locked_quantity, (spd.qualitity - IFNULL(sd.qualitity, 0)) as qualitity
        from stock_inventory spd
                 left join (select stock_inventory_id, sum(quantity) as qualitity
                            from shipping_product_detail
                            group by stock_inventory_id) as sd on sd.stock_inventory_id = spd.id
        where product_model_id = #{productModelId}
        select si.id, si.batch_no, si.locked_quantity, (si.qualitity - IFNULL(sd.qualitity, 0)) as qualitity
        from stock_inventory si
                 left join (
                    select spd.stock_inventory_id, sum(spd.quantity) as qualitity
                    from shipping_product_detail spd
                    where exists (
                        select 1
                        from stock_out_record sor
                        where sor.record_id = spd.shipping_info_id
                          and sor.record_type = '13'
                          and sor.type = '0'
                          and sor.approval_status in (0, 3)
                          and sor.product_model_id = spd.product_model_id
                          and (sor.batch_no = spd.batch_no or (sor.batch_no is null and spd.batch_no is null))
                    )
                    group by spd.stock_inventory_id
                 ) as sd on sd.stock_inventory_id = si.id
        where si.product_model_id = #{productModelId}
    </select>
</mapper>
src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -93,7 +93,7 @@
        sl.customer_name,
        s.shipping_date,
        p.product_name,
        slp.specification_model,
        pm.model as specification_model,
        sor.stock_out_num * slp.tax_inclusive_unit_price as outboundAmount,
        s.shipping_no,
        sl.sales_contract_no