liyong
昨天 bd02d873d7bbcae36a2a1262d921f2fc6b0cce09
feat(sales): 新增发货台账详情功能并优化库存管理

- 添加了 ShippingProductDetail 实体、控制器、映射器和服务
- 在 SalesLedgerProduct 中新增 noQuantity 字段用于库存数量计算
- 修改数据库连接配置,更新模块名称为 sales
- 重构发货库存扣减逻辑,支持按批次扣减库存
- 更新发货状态判断逻辑,基于实际发货数量计算
- 新增销售相关库存出入库类型枚举值
- 添加根据产品型号ID获取库存记录的接口
- 实现发货明细数据的批量插入和删除功能
- 优化发货单查询SQL,增加发货状态和未发货数量字段
- 添加退货管理相关字段和查询逻辑
- 完善库存工具类,支持按批次扣减库存功能
已添加7个文件
已修改17个文件
296 ■■■■■ 文件已修改
src/main/java/com/ruoyi/CodeGenerator.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/bean/dto/ApproveNodeDto.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingProductDetailController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/ShippingProductDetailMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/ShippingProductDetail.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ShippingProductDetailService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingProductDetailServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/StockInventoryService.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingInfoMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingProductDetailMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/CodeGenerator.java
@@ -20,11 +20,11 @@
// æ¼”示例子,执行 main æ–¹æ³•控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {
    public static String database_url = "jdbc:mysql://localhost:3306/product-inventory-management-new-pro";
    public static String database_url = "jdbc:mysql://localhost:3300/product-inventory-management-new-pro";
    public static String database_username = "root";
    public static String database_password= "123456";
    public static String database_password= "root";
    public static String author = "芯导软件(江苏)有限公司";
    public static String model = "technology"; // æ¨¡å—
    public static String model = "sales"; // æ¨¡å—
    public static String setParent = "com.ruoyi."+ model; // åŒ…路径
    public static String tablePrefix = ""; // è®¾ç½®è¿‡æ»¤è¡¨å‰ç¼€
    public static void main(String[] args) {
src/main/java/com/ruoyi/approve/bean/dto/ApproveNodeDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.approve.bean.dto;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.basic.dto.StorageBlobDTO;
import lombok.Data;
import java.util.List;
@Data
public class ApproveNodeDto extends ApproveNode {
}
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java
@@ -130,6 +130,6 @@
    @TableField(fill = FieldFill.INSERT)
    private Long deptId;
    @TableField(fill = FieldFill.INSERT)
    @TableField(exist = false)
    private List<StorageBlobDTO> storageBlobDTOS;
}
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
@@ -8,12 +8,25 @@
    CUSTOMIZATION_STOCK_IN("0", "合格自定义入库"),
    CUSTOMIZATION_STOCK_OUT("1", "合格自定义出库"),
    PRODUCTION_REPORT_STOCK_IN("2", "生产报工-入库"),
    PURCHASE_STOCK_IN("7", "采购-入库"),
    PRODUCTION_REPORT_STOCK_OUT("3", "生产报工-出库"),
    DEFECTIVE_SCRAP("4", "不合格处理-报废"),
    PRODUCTION_SCRAP("5", "生产报工-报废"),
    QUALITYINSPECT_STOCK_IN("6", "质检-合格入库"),
    PURCHASE_STOCK_IN("7", "采购-入库"),
    SALE_STOCK_OUT("8", "销售-出库"),
    CUSTOMIZATION_UNSTOCK_IN("9", "不合格自定义入库"),
    CUSTOMIZATION_UNSTOCK_OUT("10", "不合格自定义出库"),
    DEFECTIVE_PASS("11", "不合格-让步放行"),
    QUALITYINSPECT_UNSTOCK_IN("12", "质检-不合格入库"),
    SALE_SHIP_STOCK_OUT("13", "销售-发货出库"),
    RETURN_HE_IN("14", "销售退货-合格入库"),
    PICK_RETURN_IN("20", "销售退货-合格入库");
    RETURN_UNSTOCK_IN("15", "销售退货-不合格入库"),
    PICK_RETURN_IN("20", "销售退货-合格入库"),
    PURCHASE_RETURN_STOCK_OUT("21", "采购退货");
    private final String code;
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -97,6 +97,16 @@
        stockInventoryService.subtractStockInventory(stockInventoryDto);
    }
    public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo) {
        StockInventoryDto stockInventoryDto = new StockInventoryDto();
        stockInventoryDto.setRecordId(recordId);
        stockInventoryDto.setRecordType(String.valueOf(recordType));
        stockInventoryDto.setQualitity(quantity);
        stockInventoryDto.setProductModelId(productModelId);
        stockInventoryDto.setBatchNo(batchNo);
        stockInventoryService.subtractStockInventory(stockInventoryDto);
    }
    //不合格库存删除
    public void deleteStockInRecord(Long recordId, String recordType) {
        StockInRecord one = stockInRecordService.getOne(new QueryWrapper<StockInRecord>()
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -68,7 +68,7 @@
        // æ·»åŠ å‘è´§æ¶ˆæ¯
        req.setShippingNo(sh);
        req.setStatus("待审核");
        boolean save = shippingInfoService.save(req);
        boolean save = shippingInfoService.add(req);
        return save ? AjaxResult.success() : AjaxResult.error();
    }
src/main/java/com/ruoyi/sales/controller/ShippingProductDetailController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.sales.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * å‘货台账详情表 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-06 10:02:10
 */
@RestController
@RequestMapping("/shippingProductDetail")
public class ShippingProductDetailController {
}
src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
@@ -5,6 +5,7 @@
import com.ruoyi.basic.dto.StorageBlobVO;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import lombok.Data;
import java.util.List;
@@ -36,4 +37,9 @@
    private List<StorageBlobDTO> storageBlobDTOs;
    private List<StorageBlobVO> storageBlobVOs;
    private List<Long> batchNo;
    private List<ShippingProductDetail> batchNoDetailList;
}
src/main/java/com/ruoyi/sales/mapper/ShippingProductDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * å‘货台账详情表 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-06 10:02:10
 */
@Mapper
public interface ShippingProductDetailMapper extends BaseMapper<ShippingProductDetail> {
}
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -256,4 +256,6 @@
    //针对销售台账,是否生产
    private Boolean isProduction;
    @TableField(exist = false)
    private BigDecimal noQuantity;
}
src/main/java/com/ruoyi/sales/pojo/ShippingProductDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * <p>
 * å‘货台账详情表
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-06 10:02:10
 */
@Getter
@Setter
@ToString
@TableName("shipping_product_detail")
@ApiModel(value = "ShippingProductDetail对象", description = "发货台账详情表")
public class ShippingProductDetail implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®id
     */
    @ApiModelProperty("主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * åº“存表id
     */
    @ApiModelProperty("库存表id")
    private Long stockInventoryId;
    /**
     * æ‰¹æ¬¡å·
     */
    @ApiModelProperty("批次号")
    private String batchNo;
    /**
     * å‘货的数量
     */
    @ApiModelProperty("发货的数量")
    private BigDecimal quantity;
    /**
     * å‘货台账id
     */
    @ApiModelProperty("发货台账id")
    private Long shippingInfoId;
    @ApiModelProperty("产品型号id")
    private Long productModelId;
}
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java
@@ -23,4 +23,6 @@
    List<SalesLedgerProductDto> getReturnManagementDtoById( Long shippingId);
    List<ShippingInfo> getShippingInfoByCustomerName(String customerName);
    boolean add(ShippingInfoDto req);
}
src/main/java/com/ruoyi/sales/service/ShippingProductDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.sales.service;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å‘货台账详情表 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-06 10:02:10
 */
public interface ShippingProductDetailService extends IService<ShippingProductDetail> {
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -30,7 +30,6 @@
import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
import com.ruoyi.technology.pojo.TechnologyRouting;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -116,7 +115,6 @@
                if(shippingInfo != null){
                    item.setShippingDate(shippingInfo.getShippingDate());
                    item.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                    item.setShippingStatus(shippingInfo.getStatus());
                    item.setExpressCompany(shippingInfo.getExpressCompany());
                    item.setExpressNumber(shippingInfo.getExpressNumber());
                }
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -16,15 +16,15 @@
import com.ruoyi.sales.dto.ShippingInfoDto;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import com.ruoyi.sales.service.ShippingInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
@@ -48,6 +48,7 @@
    private final ApproveProcessServiceImpl approveProcessService;
    private final FileUtil fileUtil;
    private final ShippingProductDetailMapper shippingProductDetailMapper;
    @Override
    public IPage<ShippingInfoDto> listPage(Page page, ShippingInfo req) {
@@ -66,8 +67,14 @@
        }
        //扣减库存
        if(!"已发货".equals(byId.getStatus())){
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId());
            stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
//            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId());
            List<ShippingProductDetail> shippingProductDetails = shippingProductDetailMapper.selectList(new LambdaQueryWrapper<ShippingProductDetail>().eq(ShippingProductDetail::getShippingInfoId, req.getId()));
            if (CollectionUtils.isEmpty(shippingProductDetails)) {
                throw new RuntimeException("发货信息不存在");
            }
            for (ShippingProductDetail shippingProductDetail : shippingProductDetails) {
                stockUtils.substractStock(shippingProductDetail.getProductModelId(), shippingProductDetail.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(), shippingProductDetail.getBatchNo());
            }
        }
        byId.setExpressNumber(req.getExpressNumber());
        byId.setExpressCompany(req.getExpressCompany());
@@ -96,15 +103,18 @@
        // åˆ é™¤å‘货审批
        if(CollectionUtils.isNotEmpty(shippingInfos)){
            for (ShippingInfo shippingInfo : shippingInfos){
                ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
                List<ApproveProcess> one = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>()
                        .like(ApproveProcess::getApproveReason, shippingInfo.getShippingNo()));
                if(one != null){
                    approveProcessService.delByIds(Collections.singletonList(one.getId()));
                    List<Long> list = one.stream().map(ApproveProcess::getId).toList();
                    approveProcessService.delByIds(list);
                }
            }
        }
        //删除发货明细
        shippingProductDetailMapper.delete(new LambdaQueryWrapper<ShippingProductDetail>().in(ShippingProductDetail::getShippingInfoId, ids));
        return this.removeBatchByIds(ids);
        return this.removeByIds(ids);
    }
    @Override
@@ -117,4 +127,12 @@
    public List<ShippingInfo> getShippingInfoByCustomerName(String customerName) {
        return shippingInfoMapper.getShippingInfoByCustomerName(customerName);
    }
    @Override
    public boolean add(ShippingInfoDto req) {
        this.save( req);
        req.getBatchNoDetailList().forEach(item -> item.setShippingInfoId(req.getId()));
        shippingProductDetailMapper.insert(req.getBatchNoDetailList());
        return true;
    }
}
src/main/java/com/ruoyi/sales/service/impl/ShippingProductDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.sales.service.impl;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
import com.ruoyi.sales.service.ShippingProductDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å‘货台账详情表 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-06 10:02:10
 */
@Service
public class ShippingProductDetailServiceImpl extends ServiceImpl<ShippingProductDetailMapper, ShippingProductDetail> implements ShippingProductDetailService {
}
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -128,4 +128,11 @@
    public R thawStock(@RequestBody StockInventoryDto stockInventoryDto) {
        return R.ok(stockInventoryService.thawStock(stockInventoryDto));
    }
    @GetMapping("/getByModelId")
    @Operation(summary = "根据产品规格ID获取入库记录")
    public R getByModelId(Long productModelId) {
        return R.ok(stockInventoryService.getByModelId(productModelId));
    }
}
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -54,4 +54,6 @@
    BigDecimal selectPendingOutQuantity(@Param("productModelId") Long productModelId, @Param("batchNo") String batchNo, @Param("type") String type);
    List<StockInventory> listSelectableBatchNoByProductModelIds(@Param("productModelIds") List<Long> productModelIds);
    List<StockInventory> getByModelId(@Param("productModelId") Long productModelId);
}
src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -7,9 +7,10 @@
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.pojo.StockInventory;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
@@ -44,4 +45,6 @@
    Boolean frozenStock(StockInventoryDto stockInventoryDto);
    Boolean thawStock(StockInventoryDto stockInventoryDto);
    List<StockInventory> getByModelId(Long modelId);
}
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -429,4 +429,9 @@
        stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
        return this.updateById(stockInventory);
    }
    @Override
    public List<StockInventory> getByModelId(Long modelId) {
        return stockInventoryMapper.getByModelId(modelId);
    }
}
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -8,12 +8,27 @@
        SELECT
        T1.*,
        CASE
        WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >= IFNULL(T1.quantity, 0) THEN 1
        WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >0 THEN 1
        ELSE 0
        END as has_sufficient_stock
        END as has_sufficient_stock,
        (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) as no_quantity,
        CASE
        WHEN (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN '待发货'
        ELSE '已发货'
        END as shippingStatus
        FROM
        sales_ledger_product T1
        LEFT JOIN stock_inventory t2 ON T1.product_model_id = t2.product_model_id
        LEFT JOIN (
        SELECT product_model_id, SUM(qualitity) as qualitity, SUM(locked_quantity) as locked_quantity
        FROM stock_inventory
        GROUP BY product_model_id
        ) t2 ON T1.product_model_id = t2.product_model_id
        LEFT JOIN (
        SELECT sales_ledger_product_id, IFNULL(SUM(spd.quantity), 0) as shipped_quantity
        FROM shipping_info si
        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
        <where>
            <if test="salesLedgerProduct.salesLedgerId != null">
                AND T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -61,6 +61,7 @@
    <select id="getReturnManagementDtoById" resultType="com.ruoyi.sales.dto.SalesLedgerProductDto">
        SELECT
        slp.*,
        si.shipping_no,
        GREATEST(slp.quantity - COALESCE(rs.total_return_num, 0), 0) AS un_quantity,
        COALESCE(rs.total_return_num, 0) AS total_return_num
        FROM shipping_info si
src/main/resources/mapper/sales/ShippingProductDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.ShippingProductDetailMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.sales.pojo.ShippingProductDetail">
        <id column="id" property="id" />
        <result column="stock_inventory_id" property="stockInventoryId" />
        <result column="batch_no" property="batchNo" />
        <result column="quantity" property="quantity" />
        <result column="shipping_info_id" property="shippingInfoId" />
    </resultMap>
</mapper>
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -452,5 +452,13 @@
          and (si.qualitity - ifnull(si.locked_quantity, 0)) > 0
        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>
</mapper>