gongchunyi
11 小时以前 93b93bacbe43fcd2f13884ec02782baf77193d35
feat: 销售台账增加一个宽高搜索,页面加面积、数量的字段展示
已添加1个文件
已修改8个文件
277 ■■■■■ 文件已修改
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesInvoicesDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductTotalsDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -1,8 +1,6 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -14,8 +12,6 @@
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.sales.dto.*;
import com.ruoyi.sales.mapper.InvoiceLedgerMapper;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProcessRoute;
import com.ruoyi.sales.service.ICommonFileService;
@@ -59,9 +55,6 @@
    @Autowired
    private InvoiceLedgerMapper invoiceLedgerMapper;
    @Autowired
    private ReceiptPaymentMapper receiptPaymentMapper;
    /**
     * å¯¼å…¥é”€å”®å°è´¦
@@ -118,7 +111,7 @@
     * æŸ¥è¯¢é”€å”®å°è´¦åˆ—表
     */
    @GetMapping("/list")
    public TableDataInfo list(Page page, SalesLedgerDto salesLedgerDto) {
    public TableDataInfo list(Page<?> page, SalesLedgerDto salesLedgerDto) {
        startPage();
        List<SalesLedger> list = salesLedgerService.selectSalesLedgerList(salesLedgerDto);
        // è®¡ç®—已开票金额/未开票金额(已填写发票金额为准)
@@ -156,7 +149,7 @@
    @Log(title = "销售台账", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SalesLedgerDto salesLedgerDto) {
        Page page = new Page(-1, -1);
        Page<?> page = new Page<>(-1, -1);
        IPage<SalesLedger> salesLedgerIPage = listPage(page, salesLedgerDto);
        ExcelUtil<SalesLedger> util = new ExcelUtil<SalesLedger>(SalesLedger.class);
        if (salesLedgerIPage == null) {
@@ -173,7 +166,7 @@
    @Log(title = "导出开票登记列表", businessType = BusinessType.EXPORT)
    @PostMapping("/exportOne")
    public void exportOne(HttpServletResponse response, SalesLedgerDto salesLedgerDto) {
        Page page = new Page();
        Page<?> page = new Page<>();
        page.setCurrent(-1);
        page.setSize(-1);
        IPage<SalesLedger> salesLedgerIPage = listPage(page, salesLedgerDto);
@@ -269,91 +262,8 @@
     * æŸ¥è¯¢é”€å”®å°è´¦åˆ—表
     */
    @GetMapping("/listPage")
    public IPage<SalesLedger> listPage(Page page, SalesLedgerDto salesLedgerDto) {
        IPage<SalesLedger> iPage = salesLedgerService.selectSalesLedgerListPage(page, salesLedgerDto);
        //  æŸ¥è¯¢ç»“果为空,直接返回
        if (CollectionUtils.isEmpty(iPage.getRecords())) {
            return iPage;
        }
        //  èŽ·å–å½“å‰é¡µæ‰€æœ‰å°è´¦è®°å½•çš„ ID é›†åˆ
        List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
        //  æŸ¥è¯¢å‘票信息的已开票金额
        List<InvoiceLedgerDto> invoiceLedgerDtoList = invoiceLedgerMapper.invoicedTotal(salesLedgerIds);
        if (CollectionUtils.isEmpty(invoiceLedgerDtoList)) {
            invoiceLedgerDtoList = Collections.emptyList();
        }
        //  è½¬æ¢å‘票数据, key ä¸ºå°è´¦ID, value ä¸ºè¯¥å°è´¦çš„æ€»å¼€ç¥¨é‡‘额
        Map<Long, BigDecimal> invoiceTotals = invoiceLedgerDtoList.stream()
                .filter(dto -> dto.getSalesLedgerId() != null && dto.getInvoiceTotal() != null)
                .collect(Collectors.toMap(
                        dto -> dto.getSalesLedgerId().longValue(),
                        InvoiceLedgerDto::getInvoiceTotal,
                        BigDecimal::add // å­˜åœ¨é‡å¤ID执行累加
                ));
        //  æŸ¥è¯¢å›žæ¬¾/付款记录
        List<ReceiptPayment> receiptPayments = Collections.emptyList();
        if (!CollectionUtils.isEmpty(salesLedgerIds)) {
            receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
                    .in(ReceiptPayment::getSalesLedgerId, salesLedgerIds));
        }
        //  è½¬æ¢å›žæ¬¾æ•°æ®, key ä¸ºå°è´¦ID, value ä¸ºè¯¥å°è´¦çš„æ€»å›žæ¬¾é‡‘额
        Map<Long, BigDecimal> receiptTotals = new HashMap<>();
        if (!CollectionUtils.isEmpty(receiptPayments)) {
            for (ReceiptPayment receiptPayment : receiptPayments) {
                if (receiptPayment.getSalesLedgerId() != null && receiptPayment.getReceiptPaymentAmount() != null) {
                    //  å¦‚æžœ key å­˜åœ¨åˆ™ç›¸åŠ ,不存在则放入
                    receiptTotals.merge(receiptPayment.getSalesLedgerId(), receiptPayment.getReceiptPaymentAmount(), BigDecimal::add);
                }
            }
        }
        for (SalesLedger salesLedger : iPage.getRecords()) {
            Long ledgerId = salesLedger.getId();
            // åˆåŒæ€»é‡‘额
            BigDecimal contractAmount = salesLedger.getContractAmount() == null ? BigDecimal.ZERO : salesLedger.getContractAmount();
            // å¼€ç¥¨æ€»é¢å’Œå›žæ¬¾æ€»é¢
            BigDecimal invoiceTotal = invoiceTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
            BigDecimal receiptPaymentAmountTotal = receiptTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
            //  æœªå¼€ç¥¨é‡‘额 = åˆåŒé‡‘额 - å·²å¼€ç¥¨é‡‘额
            BigDecimal noInvoiceAmountTotal = contractAmount.subtract(invoiceTotal);
            if (noInvoiceAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
                noInvoiceAmountTotal = BigDecimal.ZERO;
            }
            //  å¾…回款金额 = å·²å¼€ç¥¨é‡‘额 - å·²å›žæ¬¾é‡‘额
            BigDecimal noReceiptPaymentAmountTotal = invoiceTotal.subtract(receiptPaymentAmountTotal);
            if (noReceiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
                noReceiptPaymentAmountTotal = BigDecimal.ZERO;
            }
            salesLedger.setNoInvoiceAmountTotal(noInvoiceAmountTotal);
            salesLedger.setInvoiceTotal(invoiceTotal);
            salesLedger.setReceiptPaymentAmountTotal(receiptPaymentAmountTotal);
            salesLedger.setNoReceiptAmount(noReceiptPaymentAmountTotal);
            //  å¦‚果已经有过开票或回款操作,则不允许编辑
            boolean hasInvoiceOperation = invoiceTotal.compareTo(BigDecimal.ZERO) > 0;
            boolean hasReceiptOperation = receiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) > 0;
            salesLedger.setIsEdit(!(hasInvoiceOperation || hasReceiptOperation));
        }
        if (ObjectUtils.isNotEmpty(salesLedgerDto.getStatus())) {
            if (salesLedgerDto.getStatus()) {
                // æ¸…除所有“未开票金额”为 0 çš„记录
                iPage.getRecords().removeIf(salesLedger ->
                        Objects.equals(salesLedger.getNoInvoiceAmountTotal(), new BigDecimal("0.00")));
                iPage.setTotal(iPage.getRecords().size());
            }
        }
        return iPage;
    public IPage<SalesLedger> listPage(Page<?> page, SalesLedgerDto salesLedgerDto) {
        return salesLedgerService.selectSalesLedgerListPage(page, salesLedgerDto);
    }
    @ApiOperation("查询销售台账消耗物料信息")
src/main/java/com/ruoyi/sales/dto/SalesInvoicesDto.java
@@ -65,6 +65,9 @@
        @ApiModelProperty("产品名称")
        private String productName;
        @ApiModelProperty("规格型号")
        private String specificationModel;
        @ApiModelProperty("明细列表")
        private List<InvoiceItemDto> items;
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -8,6 +8,7 @@
import lombok.Data;
import java.time.LocalDate;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@@ -65,4 +66,10 @@
    @ApiModelProperty(value = "入库状态")
    private Integer stockStatus;
    @ApiModelProperty(value = "产品宽")
    private BigDecimal width;
    @ApiModelProperty(value = "产品高")
    private BigDecimal height;
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductTotalsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.sales.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SalesLedgerProductTotalsDto {
    private Long salesLedgerId;
    private BigDecimal totalQuantity;
    private BigDecimal totalArea;
}
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -5,6 +5,7 @@
import com.ruoyi.common.config.MyBaseMapper;
import com.ruoyi.purchase.dto.ProcurementBusinessSummaryDto;
import com.ruoyi.purchase.dto.ProcurementBusinessSummaryStatisticsDto;
import com.ruoyi.sales.dto.SalesLedgerProductTotalsDto;
import com.ruoyi.sales.dto.LossProductModelDto;
import com.ruoyi.sales.dto.SalesLedgerProductDto;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
@@ -36,6 +37,8 @@
    ProcurementBusinessSummaryStatisticsDto procurementBusinessSummaryStatistics(@Param("req") ProcurementBusinessSummaryDto procurementBusinessSummaryDto);
    List<SalesLedgerProductTotalsDto> selectSalesLedgerProductTotals(@Param("salesLedgerIds") List<Long> salesLedgerIds, @Param("type") Integer type);
    List<LossProductModelDto> selectProductBomStructure(@Param("salesLedegerId") Long salesLedegerId);
    List<Map<String, Object>> selectProductSalesAnalysis();
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -10,6 +10,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.List;
/**
 * é”€å”®å°è´¦å¯¹è±¡ sales_ledger
@@ -165,5 +166,17 @@
    @TableField(exist = false)
    //是否可编辑
    private Boolean isEdit;
    @TableField(exist = false)
    @ApiModelProperty("订单产品总数量")
    private BigDecimal productTotalQuantity = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty("订单产品总面积(㎡)")
    private BigDecimal productTotalArea = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty("命中的销售产品列表")
    private List<SalesLedgerProduct> matchedProducts;
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -418,7 +418,112 @@
    @Override
    public IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) {
        return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
        IPage<SalesLedger> iPage = salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
        if (CollectionUtils.isEmpty(iPage.getRecords())) {
            return iPage;
        }
        List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
        boolean hasWidthHeightFilter = salesLedgerDto.getWidth() != null || salesLedgerDto.getHeight() != null;
        Map<Long, List<SalesLedgerProduct>> matchedProductsMap = Collections.emptyMap();
        if (hasWidthHeightFilter) {
            LambdaQueryWrapper<SalesLedgerProduct> productQueryWrapper = new LambdaQueryWrapper<SalesLedgerProduct>()
                    .in(SalesLedgerProduct::getSalesLedgerId, salesLedgerIds)
                    .eq(SalesLedgerProduct::getType, 1);
            if (salesLedgerDto.getWidth() != null) {
                productQueryWrapper.eq(SalesLedgerProduct::getWidth, salesLedgerDto.getWidth());
            }
            if (salesLedgerDto.getHeight() != null) {
                productQueryWrapper.eq(SalesLedgerProduct::getHeight, salesLedgerDto.getHeight());
            }
            List<SalesLedgerProduct> matchedProducts = salesLedgerProductMapper.selectList(productQueryWrapper);
            matchedProductsMap = CollectionUtils.isEmpty(matchedProducts) ? Collections.emptyMap()
                    : matchedProducts.stream().collect(Collectors.groupingBy(SalesLedgerProduct::getSalesLedgerId));
        }
        List<SalesLedgerProductTotalsDto> productTotals = salesLedgerProductMapper.selectSalesLedgerProductTotals(salesLedgerIds, 1);
        Map<Long, SalesLedgerProductTotalsDto> productTotalsMap = CollectionUtils.isEmpty(productTotals)
                ? Collections.emptyMap()
                : productTotals.stream()
                .filter(t -> t.getSalesLedgerId() != null)
                .collect(Collectors.toMap(SalesLedgerProductTotalsDto::getSalesLedgerId, Function.identity(), (a, b) -> a));
        List<InvoiceLedgerDto> invoiceLedgerDtoList = invoiceLedgerMapper.invoicedTotal(salesLedgerIds);
        if (CollectionUtils.isEmpty(invoiceLedgerDtoList)) {
            invoiceLedgerDtoList = Collections.emptyList();
        }
        Map<Long, BigDecimal> invoiceTotals = invoiceLedgerDtoList.stream()
                .filter(dto -> dto.getSalesLedgerId() != null && dto.getInvoiceTotal() != null)
                .collect(Collectors.toMap(
                        dto -> dto.getSalesLedgerId().longValue(),
                        InvoiceLedgerDto::getInvoiceTotal,
                        BigDecimal::add
                ));
        List<ReceiptPayment> receiptPayments = Collections.emptyList();
        if (!CollectionUtils.isEmpty(salesLedgerIds)) {
            receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
                    .in(ReceiptPayment::getSalesLedgerId, salesLedgerIds));
        }
        Map<Long, BigDecimal> receiptTotals = new HashMap<>();
        if (!CollectionUtils.isEmpty(receiptPayments)) {
            for (ReceiptPayment receiptPayment : receiptPayments) {
                if (receiptPayment.getSalesLedgerId() != null && receiptPayment.getReceiptPaymentAmount() != null) {
                    receiptTotals.merge(receiptPayment.getSalesLedgerId(), receiptPayment.getReceiptPaymentAmount(), BigDecimal::add);
                }
            }
        }
        for (SalesLedger salesLedger : iPage.getRecords()) {
            Long ledgerId = salesLedger.getId();
            SalesLedgerProductTotalsDto totals = productTotalsMap.get(ledgerId);
            if (totals != null) {
                salesLedger.setProductTotalQuantity(totals.getTotalQuantity() != null ? totals.getTotalQuantity() : BigDecimal.ZERO);
                salesLedger.setProductTotalArea(totals.getTotalArea() != null ? totals.getTotalArea() : BigDecimal.ZERO);
            } else {
                salesLedger.setProductTotalQuantity(BigDecimal.ZERO);
                salesLedger.setProductTotalArea(BigDecimal.ZERO);
            }
            if (hasWidthHeightFilter) {
                salesLedger.setMatchedProducts(matchedProductsMap.getOrDefault(ledgerId, Collections.emptyList()));
            }
            BigDecimal contractAmount = salesLedger.getContractAmount() == null ? BigDecimal.ZERO : salesLedger.getContractAmount();
            BigDecimal invoiceTotal = invoiceTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
            BigDecimal receiptPaymentAmountTotal = receiptTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
            BigDecimal noInvoiceAmountTotal = contractAmount.subtract(invoiceTotal);
            if (noInvoiceAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
                noInvoiceAmountTotal = BigDecimal.ZERO;
            }
            BigDecimal noReceiptPaymentAmountTotal = invoiceTotal.subtract(receiptPaymentAmountTotal);
            if (noReceiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
                noReceiptPaymentAmountTotal = BigDecimal.ZERO;
            }
            salesLedger.setNoInvoiceAmountTotal(noInvoiceAmountTotal);
            salesLedger.setInvoiceTotal(invoiceTotal);
            salesLedger.setReceiptPaymentAmountTotal(receiptPaymentAmountTotal);
            salesLedger.setNoReceiptAmount(noReceiptPaymentAmountTotal);
            boolean hasInvoiceOperation = invoiceTotal.compareTo(BigDecimal.ZERO) > 0;
            boolean hasReceiptOperation = receiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) > 0;
            salesLedger.setIsEdit(!(hasInvoiceOperation || hasReceiptOperation));
        }
        if (salesLedgerDto.getStatus() != null && salesLedgerDto.getStatus()) {
            iPage.getRecords().removeIf(salesLedger ->
                    Objects.equals(salesLedger.getNoInvoiceAmountTotal(), new BigDecimal("0.00")));
            iPage.setTotal(iPage.getRecords().size());
        }
        return iPage;
    }
    @Override
@@ -1536,6 +1641,7 @@
                Set<String> orderNos = groupOrderNos.getOrDefault(key, Collections.emptySet());
                group.setSalesContractNo(String.join(",", orderNos));
                group.setProductName(productName);
                group.setSpecificationModel(specificationModel);
                Map<String, SalesInvoicesDto.InvoiceItemDto> mergedItems = new LinkedHashMap<>();
                BigDecimal groupQty = BigDecimal.ZERO;
src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -95,6 +95,20 @@
            <if test="salesLedgerDto.stockStatus != null">
                AND T1.stock_status = #{salesLedgerDto.stockStatus}
            </if>
            <if test="salesLedgerDto.width != null or salesLedgerDto.height != null">
                AND EXISTS (
                SELECT 1
                FROM sales_ledger_product SLP
                WHERE SLP.sales_ledger_id = T1.id
                AND SLP.type = 1
                <if test="salesLedgerDto.width != null">
                    AND SLP.width = #{salesLedgerDto.width}
                </if>
                <if test="salesLedgerDto.height != null">
                    AND SLP.height = #{salesLedgerDto.height}
                </if>
                )
            </if>
        </where>
        ORDER BY T1.entry_date DESC,T1.id DESC
    </select>
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -278,4 +278,20 @@
                                 FROM product_tree);
    </select>
    <select id="selectSalesLedgerProductTotals" resultType="com.ruoyi.sales.dto.SalesLedgerProductTotalsDto">
        SELECT
            slp.sales_ledger_id AS salesLedgerId,
            COALESCE(SUM(slp.quantity), 0) AS totalQuantity,
            COALESCE(SUM(COALESCE(slp.settle_total_area, slp.actual_total_area, 0)), 0) AS totalArea
        FROM sales_ledger_product slp
        WHERE slp.sales_ledger_id IN
        <foreach collection="salesLedgerIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
        <if test="type != null">
            AND slp.type = #{type}
        </if>
        GROUP BY slp.sales_ledger_id
    </select>
</mapper>