feat: 支持个人对私录入销售订单;支持个人采购;供应商、客户档案、销售采购导入导出修改
已修改26个文件
659 ■■■■ 文件已修改
doc/长治-烜曌工贸.sql 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/Customer.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/SupplierManage.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerImportDto.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerProductImportDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedgerTemplate.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/SalesLedgerProductTemplate.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 175 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 137 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/SupplierManageMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseLedgerTemplateMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/采购台账导入模板.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/销售台账导入模板.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
doc/³¤ÖÎ-Ÿ@•×¹¤Ã³.sql
@@ -12,4 +12,29 @@
    MODIFY COLUMN `supplier_type` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '供应商类型(对公/对私)' AFTER `company_address`;
ALTER TABLE `product-inventory-management-xzgm`.`sales_ledger`
    ADD COLUMN `sales_type` varchar(255) NULL COMMENT '台账类型(对公/对私)' AFTER `delivery_date`;
    ADD COLUMN `sales_type` varchar(255) NULL COMMENT '台账类型(对公/对私)' AFTER `delivery_date`;
ALTER TABLE `sales_ledger_product`
    ADD COLUMN `unit_price`         decimal(18, 2) DEFAULT NULL COMMENT '对私-单价',
    ADD COLUMN `freight`            decimal(18, 2) DEFAULT 0.00 COMMENT '对私-运费',
    ADD COLUMN `price_with_freight` decimal(18, 2) DEFAULT NULL COMMENT '对私-含运费单价(单价+运费)',
    ADD COLUMN `total_price`        decimal(18, 2) DEFAULT NULL COMMENT '对私-总价(含运费单价*数量)';
ALTER TABLE `product-inventory-management-xzgm`.`customer`
    MODIFY COLUMN `customer_type` int NOT NULL COMMENT '客户分类:1-对公,2-对私' AFTER `bank_code`;
ALTER TABLE `product-inventory-management-xzgm`.`sales_ledger`
    MODIFY COLUMN `sales_type` int NULL DEFAULT NULL COMMENT '台账类型(1-对公,2-对私)' AFTER `delivery_date`;
ALTER TABLE `product-inventory-management-xzgm`.`supplier_manage`
    MODIFY COLUMN `supplier_type` int NULL DEFAULT NULL COMMENT '供应商类型(1-对公/2-对私)' AFTER `company_address`;
ALTER TABLE `product-inventory-management-xzgm`.`purchase_ledger_template`
    MODIFY COLUMN `template_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '模板名称' AFTER `execution_date`,
    ADD COLUMN `template_type` int NULL COMMENT '模板类型(1-对公/2-对私)' AFTER `template_name`;
ALTER TABLE `sales_ledger_product_template`
    ADD COLUMN `unit_price`         decimal(18, 2) DEFAULT NULL COMMENT '单价(对私专用)',
    ADD COLUMN `total_price`        decimal(18, 2) DEFAULT NULL COMMENT '总价(对私专用)',
    ADD COLUMN `freight`            decimal(18, 2) DEFAULT 0.00 COMMENT '运费',
    ADD COLUMN `price_with_freight` decimal(18, 2) DEFAULT NULL COMMENT '含运费单价';
src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java
@@ -1,5 +1,6 @@
package com.ruoyi.basic.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.basic.pojo.SupplierManage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java
@@ -15,6 +15,9 @@
    @Excel(name = "供应商名称")
    private String supplierName;
    @Excel(name = "供应商类型(1-对公/2-对私)")
    private Integer supplierType;
    @Excel(name = "纳税人识别号")
    private String taxpayerIdentificationNum;
src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -50,8 +50,8 @@
    @TableField(exist = false)
    private Date followUpTime;
    @Excel(name = "客户分类")
    private String customerType;
    @Excel(name = "客户分类:1-对公,2-对私")
    private Integer customerType;
    /**
     * çº³ç¨Žäººè¯†åˆ«å·
src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
@@ -28,6 +28,10 @@
    @Excel(name = "公司地址")
    private String companyAddress;
    @ApiModelProperty(value = "供应商类型")
    @Excel(name = "供应商类型(1-对公/2-对私)")
    private Integer supplierType;
    @ApiModelProperty(value = "公司电话")
    @Excel(name = "公司电话")
    private String companyPhone;
@@ -79,8 +83,4 @@
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "供应商类型")
    @TableField(value = "supplier_type")
    private String supplierType;
}
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -134,12 +134,12 @@
        // 2. æž„建查询条件(增强空值安全)
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        String customerName = customer.getCustomerName();
        String customerType = customer.getCustomerType();
        Integer customerType = customer.getCustomerType();
        if (StringUtils.isNotBlank(customerName)) {
            queryWrapper.like(Customer::getCustomerName, customerName);
        }
        if (StringUtils.isNotBlank(customerType)) {
            queryWrapper.like(Customer::getCustomerType, customerType);
        if (customerType != null) {
            queryWrapper.eq(Customer::getCustomerType, customerType);
        }
        // 3. æ‰§è¡Œåˆ†é¡µæŸ¥è¯¢ï¼ˆä¿ç•™åˆ†é¡µå…ƒæ•°æ®ï¼‰
@@ -150,10 +150,17 @@
                .filter(Objects::nonNull) // è¿‡æ»¤ç©ºå¯¹è±¡ï¼ˆé¿å…åŽç»­æ“ä½œNPE)
                .peek(c -> {
                    // å®‰å…¨èŽ·å–å­—æ®µï¼Œé¿å…null值拼接
                    String address = StringUtils.defaultString(c.getCompanyAddress(), "");
                    String phone = StringUtils.defaultString(c.getCompanyPhone(), "");
                    c.setAddressPhone(address + "(" + phone + ")");
                    String address = StringUtils.defaultString(c.getCompanyAddress(), "").trim();
                    String phone = StringUtils.defaultString(c.getCompanyPhone(), "").trim();
                    if (StringUtils.isNotEmpty(address) && StringUtils.isNotEmpty(phone)) {
                        c.setAddressPhone(address + "(" + phone + ")");
                    } else if (StringUtils.isNotEmpty(address)) {
                        c.setAddressPhone(address);
                    } else if (StringUtils.isNotEmpty(phone)) {
                        c.setAddressPhone(phone);
                    } else {
                        c.setAddressPhone("");
                    }
                    // æŸ¥è¯¢æœ€æ–°çš„跟进记录
                    CustomerFollowUp followUp = customerFollowUpService.getOne(
                            new LambdaQueryWrapper<CustomerFollowUp>()
@@ -263,7 +270,7 @@
    @Override
    public List<Map<String, Object>> customerList(Customer customer) {
        LambdaQueryWrapper<Customer> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(Customer::getId, Customer::getCustomerName, Customer::getTaxpayerIdentificationNumber);
        queryWrapper.select(Customer::getId, Customer::getCustomerName, Customer::getTaxpayerIdentificationNumber, Customer::getCustomerType);
        // èŽ·å–åŽŸå§‹æŸ¥è¯¢ç»“æžœ
        List<Map<String, Object>> result = customerMapper.selectMaps(queryWrapper);
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -35,6 +35,7 @@
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -128,8 +129,8 @@
    @PostMapping("/export")
    public void export(HttpServletResponse response, PurchaseLedger purchaseLedger) {
        List<PurchaseLedger> list = purchaseLedgerService.selectPurchaseLedgerList(purchaseLedger);
        ExcelUtil<PurchaseLedger> util = new ExcelUtil<PurchaseLedger>(PurchaseLedger.class);
        util.exportExcel(response, list, "【请填写功能名称】数据");
        ExcelUtil<PurchaseLedger> util = new ExcelUtil<>(PurchaseLedger.class);
        util.exportExcel(response, list, "采购台账数据");
    }
    /**
@@ -160,8 +161,11 @@
     */
    @ApiOperation("/查询采购模板")
    @GetMapping("/getPurchaseTemplateList")
    public AjaxResult getPurchaseTemplateList() {
        List<PurchaseLedgerTemplate>  purchaseLedgers = purchaseLedgerTemplateMapper.selectList(null);
    public AjaxResult getPurchaseTemplateList(@RequestParam(required = false) Integer templateType) {
        if (templateType == null){
            return AjaxResult.success(new ArrayList<>());
        }
        List<PurchaseLedgerTemplate>  purchaseLedgers = purchaseLedgerTemplateMapper.selectList(new LambdaQueryWrapper<PurchaseLedgerTemplate>().eq(PurchaseLedgerTemplate::getTemplateType,templateType));
        purchaseLedgers.forEach(purchaseLedgerDto1 -> {
            LambdaQueryWrapper<SalesLedgerProductTemplate> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SalesLedgerProductTemplate::getSalesLedgerId, purchaseLedgerDto1.getId())
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -51,7 +51,7 @@
     * ä¾›åº”商名称
     */
    @Excel(name = "供应商类型")
    private String supplierType;
    private Integer supplierType;
     /**
     * æ˜¯å¦ç™½åå•
     */
@@ -131,7 +131,7 @@
    private Boolean hasChildren = false;
    private Integer Type;
    private Integer type;
    private List<SalesLedgerProduct> productData;
@@ -190,11 +190,6 @@
    @Excel(name = "未来票金额(元)")
    private BigDecimal unReceiptPaymentAmount =BigDecimal.ZERO;
    @ApiModelProperty("文件类型  å– 4")
    @TableField(exist = false)
    private Integer type;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty("审批状态")
@@ -203,4 +198,8 @@
    private String templateName;
    @ApiModelProperty(value = "审批人id")
    private Integer approverId;
    @ApiModelProperty("模板类型(1-对公/2-对私)")
    private Integer templateType;
}
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerImportDto.java
@@ -7,11 +7,14 @@
import java.util.Date;
import lombok.EqualsAndHashCode;
/**
 * @author :yys
 * @date : 2026/1/26 16:01
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class PurchaseLedgerImportDto extends PurchaseLedgerProductImportDto{
    @Excel(name = "采购单号")
@@ -48,6 +51,10 @@
    @Excel(name = "审核人(多个用,隔开)")
    private String approveUserIds;
    @ApiModelProperty(value = "台账分类")
    @Excel(name = "台账分类")
    private String purchaseType;
}
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerProductImportDto.java
@@ -80,4 +80,10 @@
    @Excel(name = "是否质检", readConverterExp = "0=否,1=是")
    private Integer isChecked;
    @Excel(name = "单价")
    private BigDecimal unitPrice;
    @Excel(name = "总价")
    private BigDecimal totalPrice;
}
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -159,4 +159,9 @@
    @ApiModelProperty(value = "审批人id")
    private String approveUserIds;
    @ApiModelProperty(value = "台账分类")
    @Excel(name = "台账分类(1-对公/2-对私)")
    @TableField(exist = false)
    private Integer purchaseType;
}
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedgerTemplate.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
@@ -91,6 +92,9 @@
    @ApiModelProperty("模板名称")
    private String templateName;
    @ApiModelProperty("模板类型(1-对公/2-对私)")
    private Integer templateType;
    @TableField(exist = false)
    private List<SalesLedgerProductTemplate> productList;
}
src/main/java/com/ruoyi/purchase/pojo/SalesLedgerProductTemplate.java
@@ -6,6 +6,8 @@
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
@@ -81,4 +83,29 @@
    @ApiModelProperty("是否推送质检")
    private Boolean isChecked;
    /**
     * å•价(对私专用)
     */
    @ApiModelProperty(value = "单价(对私专用)")
    private BigDecimal unitPrice;
    /**
     * æ€»ä»·ï¼ˆå¯¹ç§ä¸“用)
     */
    @ApiModelProperty(value = "总价(对私专用)")
    private BigDecimal totalPrice;
    /**
     * è¿è´¹
     */
    @ApiModelProperty(value = "运费")
    private BigDecimal freight = BigDecimal.ZERO;
    /**
     * å«è¿è´¹å•ä»·
     */
    @ApiModelProperty(value = "含运费单价")
    private BigDecimal priceWithFreight;
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -17,13 +17,11 @@
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.mapper.SupplierManageMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -51,7 +49,6 @@
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
@@ -62,8 +59,8 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
@@ -159,13 +156,43 @@
        if (StringUtils.isNotBlank(purchaseLedger.getPurchaseContractNumber())) {
            queryWrapper.like(PurchaseLedger::getPurchaseContractNumber, purchaseLedger.getPurchaseContractNumber());
        }
        if(purchaseLedger.getSupplierId()!=null){
        if (purchaseLedger.getSupplierId() != null) {
            queryWrapper.eq(PurchaseLedger::getSupplierId, purchaseLedger.getSupplierId());
        }
        if (purchaseLedger.getApprovalStatus() != null) {
            queryWrapper.eq(PurchaseLedger::getApprovalStatus, purchaseLedger.getApprovalStatus());
        }
        return purchaseLedgerMapper.selectList(queryWrapper);
        if (StringUtils.isNotBlank(purchaseLedger.getSupplierName())) {
            queryWrapper.like(PurchaseLedger::getSupplierName, purchaseLedger.getSupplierName());
        }
        if (StringUtils.isNotBlank(purchaseLedger.getSalesContractNo())) {
            queryWrapper.like(PurchaseLedger::getSalesContractNo, purchaseLedger.getSalesContractNo());
        }
        if (StringUtils.isNotBlank(purchaseLedger.getProjectName())) {
            queryWrapper.like(PurchaseLedger::getProjectName, purchaseLedger.getProjectName());
        }
        queryWrapper.orderByDesc(PurchaseLedger::getEntryDate);
        List<PurchaseLedger> list = purchaseLedgerMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            Set<Long> supplierIds = list.stream()
                    .map(PurchaseLedger::getSupplierId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            if (!supplierIds.isEmpty()) {
                List<SupplierManage> suppliers = supplierManageMapper.selectBatchIds(supplierIds);
                Map<Long, Integer> typeMap = suppliers.stream()
                        .collect(Collectors.toMap(SupplierManage::getId, SupplierManage::getSupplierType, (k1, k2) -> k1));
                list.forEach(item -> {
                    if (item.getSupplierId() != null) {
                        item.setPurchaseType(typeMap.get(item.getSupplierId()));
                    }
                });
            }
        }
        return list;
    }
    @Override
@@ -176,7 +203,10 @@
        //录入人
        SysUser sysUser = userMapper.selectUserById(purchaseLedgerDto.getRecorderId());
        SupplierManage supplierManage = supplierManageMapper.selectById(purchaseLedgerDto.getSupplierId());
        SupplierManage supplierManage = null;
        if (purchaseLedgerDto.getSupplierId() != null) {
            supplierManage = supplierManageMapper.selectById(purchaseLedgerDto.getSupplierId());
        }
        // DTO转Entity
        PurchaseLedger purchaseLedger = new PurchaseLedger();
@@ -187,7 +217,7 @@
        }
        purchaseLedger.setSalesContractNo(ObjectUtils.isNotEmpty(salesLedger) ? salesLedger.getSalesContractNo() : "");
        purchaseLedger.setSalesLedgerId(ObjectUtils.isNotEmpty(salesLedger) ? salesLedger.getId() : -1);
        purchaseLedger.setSupplierName(supplierManage.getSupplierName());
        purchaseLedger.setSupplierName(supplierManage != null ? supplierManage.getSupplierName() : purchaseLedgerDto.getSupplierName());
        purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
        purchaseLedger.setRecorderName(sysUser.getNickName());
        purchaseLedger.setPhoneNumber(sysUser.getPhonenumber());
@@ -328,22 +358,29 @@
                LocalDateTime localDateTime = entryDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                salesLedgerProduct.setRegisterDate(localDateTime);
                salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
                salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                if (Integer.valueOf(2).equals(purchaseLedger.getPurchaseType())) {
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO);
                    salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO);
                } else {
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                    salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                }
                salesLedgerProductMapper.insert(salesLedgerProduct);
            }
        }
        // è®¡ç®—总含税金额
        BigDecimal totalTaxInclusiveAmount = products.stream()
                .map(SalesLedgerProduct::getTaxInclusiveTotalPrice)
        // è®¡ç®—总金额
        BigDecimal totalAmount = products.stream()
                .map(p -> Integer.valueOf(2).equals(purchaseLedger.getPurchaseType()) ?
                        (p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO) :
                        (p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO))
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // æ›´æ–°ä¸»è¡¨çš„æ€»é‡‘额字段
        if (salesLedgerId != null) {
            // ç›´æŽ¥æ›´æ–°æŒ‡å®šID的记录的contractAmount字段为totalTaxInclusiveAmount
            purchaseLedgerMapper.updateContractAmountById(salesLedgerId, totalTaxInclusiveAmount);
            // ç›´æŽ¥æ›´æ–°æŒ‡å®šID的记录的contractAmount字段为totalAmount
            purchaseLedgerMapper.updateContractAmountById(salesLedgerId, totalAmount);
        }
    }
@@ -660,14 +697,14 @@
    public AjaxResult importData(MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        try {
            InputStream inputStream = file.getInputStream();
            byte[] fileBytes = file.getBytes();
            ExcelUtil<PurchaseLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(PurchaseLedgerImportDto.class);
            Map<String, List<PurchaseLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("采购台账数据", "采购产品数据"), inputStream, 0);
            if (CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("采购表格为空!");
            // ä¸šåŠ¡å±‚åˆå¹¶
            List<PurchaseLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("采购台账数据");
            // é‡‡è´­å°è´¦æ•°æ®ä¸è·³è¿‡æ ‡é¢˜
            List<PurchaseLedgerImportDto> salesLedgerImportDtoList = salesLedgerImportDtoExcelUtil.importExcel("采购台账数据", new ByteArrayInputStream(fileBytes), 0);
            // é‡‡è´­äº§å“æ•°æ®è·³è¿‡1行标题
            List<PurchaseLedgerImportDto> salesLedgerProductImportDtoList = salesLedgerImportDtoExcelUtil.importExcel("采购产品数据", new ByteArrayInputStream(fileBytes), 1);
            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("采购台账数据为空!");
            List<PurchaseLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("采购产品数据");
            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("采购产品数据为空!");
            // ä¾›åº”商数据
            List<SupplierManage> customers = supplierManageMapper.selectList(new LambdaQueryWrapper<SupplierManage>().in(SupplierManage::getSupplierName,
@@ -685,12 +722,19 @@
                }
                PurchaseLedger salesLedger = new PurchaseLedger();
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                // é€šè¿‡ä¾›åº”商名称查询ID
                salesLedger.setSupplierId(customers.stream()
                // æŸ¥è¯¢ä¾›åº”商档案并设置采购类型(对公1/对私2)
                SupplierManage matchedSupplier = customers.stream()
                        .filter(customer -> customer.getSupplierName().equals(salesLedger.getSupplierName()))
                        .findFirst()
                        .map(SupplierManage::getId)
                        .orElse(null));
                        .orElse(null);
                if (matchedSupplier != null) {
                    salesLedger.setSupplierId(matchedSupplier.getId());
                    salesLedger.setPurchaseType(matchedSupplier.getSupplierType());
                } else {
                    salesLedger.setPurchaseType(1); // é»˜è®¤å¯¹å…¬
                }
                Long aLong = sysUsers.stream()
                        .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getRecorderName()))
                        .findFirst()
@@ -699,15 +743,30 @@
                if (aLong == null)
                    throw new RuntimeException("录入人:" + salesLedger.getRecorderName() + ",无对应用户!");
                salesLedger.setRecorderId(aLong);
                // é‡‡è´­äº§å“æ•°æ®ç»‘定,通过采购单号获取对应采购产品数据
                // é‡‡è´­äº§å“æ•°æ®ç»‘定
                List<PurchaseLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
                        .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getPurchaseContractNumber().equals(salesLedger.getPurchaseContractNumber()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(salesLedgerProductImportDtos))
                    throw new RuntimeException("采购单号:" + salesLedgerImportDto.getPurchaseContractNumber() + ",无对应产品数据!");
                boolean isPrivate = Integer.valueOf(2).equals(salesLedger.getPurchaseType());
                // ç»Ÿä¸€è®¡ç®—主表合同金额
                salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
                        .map(PurchaseLedgerProductImportDto::getTaxInclusiveTotalPrice)
                        .reduce(BigDecimal.ZERO,BigDecimal::add));
                        .map(dto -> {
                            if (isPrivate) {
                                if (dto.getTotalPrice() != null) return dto.getTotalPrice();
                                BigDecimal up = dto.getUnitPrice() != null ? dto.getUnitPrice() : BigDecimal.ZERO;
                                BigDecimal qty = dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO;
                                return up.multiply(qty);
                            } else {
                                return dto.getTaxInclusiveTotalPrice() != null ? dto.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                            }
                        })
                        .reduce(BigDecimal.ZERO, BigDecimal::add));
                // é€šè¿‡é”€å”®å•号绑定销售
                SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                        .eq(SalesLedger::getSalesContractNo, salesLedger.getSalesContractNo())
@@ -719,8 +778,8 @@
                // é€šè¿‡æ˜µç§°èŽ·å–ç”¨æˆ·ID
                String[] split = salesLedger.getApproveUserIds().split(",");
                List<Long> ids = new ArrayList<>();
                for (int i = 0; i < split.length; i++) {
                    SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getNickName, split[i])
                for (String s : split) {
                    SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getNickName, s)
                            .last("LIMIT 1"));
                    if (sysUser != null) {
                        ids.add(sysUser.getUserId());
@@ -736,10 +795,48 @@
                    BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                    salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                    salesLedgerProduct.setType(2);
                    // è®¡ç®—不含税总价
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    // æœªæ¥ç¥¨æ•°é‡
                    salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
                    if (isPrivate) {
                        // å¯¹ç§é‡‡è´­é€»è¾‘
                        if (salesLedgerProduct.getTotalPrice() == null && salesLedgerProduct.getUnitPrice() != null && salesLedgerProduct.getQuantity() != null) {
                            salesLedgerProduct.setTotalPrice(salesLedgerProduct.getUnitPrice().multiply(salesLedgerProduct.getQuantity()));
                        }
                        BigDecimal tp = salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO;
                        salesLedgerProduct.setTaxInclusiveTotalPrice(tp);
                        salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getUnitPrice() != null ?
                                salesLedgerProduct.getUnitPrice().multiply(salesLedgerProduct.getQuantity()) : tp);
                        //  ç»Ÿä¸€é‡‘额
                        salesLedgerProduct.setFutureTicketsAmount(tp);
                        salesLedgerProduct.setPendingTicketsTotal(tp);
                        salesLedgerProduct.setTaxRate(null);
                        salesLedgerProduct.setTaxInclusiveUnitPrice(null);
                        salesLedgerProduct.setInvoiceType(null);
                    } else {
                        // å¯¹å…¬é‡‡è´­é€»è¾‘
                        //  è¡¥å…¨ä¸å«ç¨Žæ€»ä»·
                        if (salesLedgerProduct.getTaxInclusiveTotalPrice() != null && salesLedgerProduct.getTaxRate() != null) {
                            salesLedgerProduct.setTaxExclusiveTotalPrice(
                                    salesLedgerProduct.getTaxInclusiveTotalPrice()
                                            .divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP)
                            );
                        }
                        //  å¯¹å…¬ç»Ÿä¸€ä½¿ç”¨å«ç¨Žæ€»ä»·
                        BigDecimal titp = salesLedgerProduct.getTaxInclusiveTotalPrice() != null ? salesLedgerProduct.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                        salesLedgerProduct.setFutureTicketsAmount(titp);
                        salesLedgerProduct.setPendingTicketsTotal(titp);
                        salesLedgerProduct.setUnitPrice(null);
                        salesLedgerProduct.setTotalPrice(null);
                    }
                    // åŒ¹é…äº§å“ç§ç±»å’Œè§„格型号映射ID
                    list.stream()
                            .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel()))
                            .findFirst()
@@ -747,13 +844,15 @@
                                salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
                                salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
                            });
                    // å¡«å……登记信息
                    salesLedgerProduct.setRegister(loginUser.getNickName());
                    salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                    salesLedgerProduct.setApproveStatus(0);
                    salesLedgerProduct.setPendingTicketsTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
                    // æ˜¯å¦è´¨æ£€åˆ¤æ–­
                    salesLedgerProduct.setIsChecked(salesLedgerProductImportDto.getIsChecked() == 1);
                    if(salesLedgerProductImportDto.getIsChecked() == 1){
                    salesLedgerProduct.setIsChecked(salesLedgerProductImportDto.getIsChecked() != null && salesLedgerProductImportDto.getIsChecked() == 1);
                    if(salesLedgerProduct.getIsChecked()){
                        addQualityInspect(salesLedger, salesLedgerProduct);
                    }
                    salesLedgerProductMapper.insert(salesLedgerProduct);
@@ -764,9 +863,9 @@
            return AjaxResult.success("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导入失败:", e);
            throw new RuntimeException("导入数据过程中发生了错误:" + e.getMessage());
        }
        return AjaxResult.success("导入失败");
    }
    @Override
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -61,4 +61,7 @@
    @ApiModelProperty(value = "客户分类")
    private String customerType;
    @ApiModelProperty(value = "台账分类")
    private Integer salesType;
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java
@@ -47,5 +47,7 @@
    @Excel(name = "付款方式")
    private String paymentMethod;
    @ApiModelProperty(value = "台账分类")
    @Excel(name = "台账分类")
    private Integer salesType;
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
@@ -73,6 +73,18 @@
    @Excel(name = "是否质检", readConverterExp = "0=否,1=是")
    private Boolean isChecked;
    @Excel(name = "单价")
    private BigDecimal unitPrice;
    @Excel(name = "总价")
    private BigDecimal totalPrice;
    @Excel(name = "运费")
    private BigDecimal freight = BigDecimal.ZERO;
    @Excel(name = "含运费单价")
    private BigDecimal priceWithFreight;
}
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -153,6 +153,7 @@
    private String customerType;
    @ApiModelProperty(value = "台账分类")
    private String salesType;
    @Excel(name = "台账分类")
    private Integer salesType;
}
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -243,4 +243,32 @@
    // å¯ç”¨æ•°é‡  quantity - returnQuality
    @TableField(exist = false)
    private BigDecimal availableQuality;
    /**
     * å•价(对私专用)
     */
    @ApiModelProperty(value = "单价(对私专用)")
    @Excel(name = "单价(对私)")
    private BigDecimal unitPrice;
    /**
     * æ€»ä»·ï¼ˆå¯¹ç§ä¸“用)
     */
    @ApiModelProperty(value = "总价(对私专用)")
    @Excel(name = "总价(对私)")
    private BigDecimal totalPrice;
    /**
     * è¿è´¹
     */
    @ApiModelProperty(value = "运费")
    @Excel(name = "运费")
    private BigDecimal freight = BigDecimal.ZERO;
    /**
     * å«è¿è´¹å•ä»·
     */
    @ApiModelProperty(value = "含运费单价")
    @Excel(name = "含运费单价")
    private BigDecimal priceWithFreight;
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -171,10 +171,9 @@
        }
        // å¯èƒ½å±žäºŽå¤šä¸ªä¸»è¡¨
        Set<Long> mainIds = deletedProducts.stream()
                .map(SalesLedgerProduct::getSalesLedgerId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Map<Long, Integer> mainIdTypeMap = deletedProducts.stream()
                .filter(p -> p.getSalesLedgerId() != null)
                .collect(Collectors.toMap(SalesLedgerProduct::getSalesLedgerId, SalesLedgerProduct::getType, (existing, replacement) -> existing));
        // 2. æ‰§è¡Œåˆ é™¤æ“ä½œ
        int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
@@ -182,19 +181,44 @@
        deleteProductionData(Arrays.asList(ids));
        // 3. å¯¹æ¯ä¸ªä¸»è¡¨ID进行金额更新
        for (Long salesLedgerId : mainIds) {
        for (Map.Entry<Long, Integer> entry : mainIdTypeMap.entrySet()) {
            Long salesLedgerId = entry.getKey();
            Integer type = entry.getValue();
            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId);
            wrapper.eq(SalesLedgerProduct::getType, type);
            List<SalesLedgerProduct> remainingProducts = salesLedgerProductMapper.selectList(wrapper);
            // è°ƒç”¨é€šç”¨æ–¹æ³•更新主表金额
            updateMainContractAmount(
                    salesLedgerId,
                    remainingProducts,
                    SalesLedgerProduct::getTaxInclusiveTotalPrice,
                    salesLedgerMapper,
                    SalesLedger.class
            );
            if (type == 1) {
                SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerId);
                if (salesLedger != null) {
                    Function<SalesLedgerProduct, BigDecimal> amountGetter = Integer.valueOf(2).equals(salesLedger.getSalesType()) ?
                            p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                            : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            amountGetter,
                            salesLedgerMapper,
                            SalesLedger.class
                    );
                }
            } else {
                PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(salesLedgerId);
                if (purchaseLedger != null) {
                    Function<SalesLedgerProduct, BigDecimal> amountGetter = Integer.valueOf(2).equals(purchaseLedger.getPurchaseType()) ?
                            p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                            : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            amountGetter,
                            purchaseLedgerMapper,
                            PurchaseLedger.class
                    );
                }
            }
        }
        return result;
    }
@@ -202,21 +226,86 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrUpdateSalesLedgerProduct(SalesLedgerProduct salesLedgerProduct) {
        if (salesLedgerProduct.getId() != null) {
            SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProduct.getId());
            if (dbProduct != null) {
                if (salesLedgerProduct.getSalesLedgerId() == null) {
                    salesLedgerProduct.setSalesLedgerId(dbProduct.getSalesLedgerId());
                }
                if (salesLedgerProduct.getType() == null) {
                    salesLedgerProduct.setType(dbProduct.getType());
                }
                if (salesLedgerProduct.getInvoiceTotal() == null) {
                    salesLedgerProduct.setInvoiceTotal(dbProduct.getInvoiceTotal());
                }
                if (salesLedgerProduct.getTicketsTotal() == null) {
                    salesLedgerProduct.setTicketsTotal(dbProduct.getTicketsTotal());
                }
                if (salesLedgerProduct.getQuantity() == null) {
                    salesLedgerProduct.setQuantity(dbProduct.getQuantity());
                }
                if (salesLedgerProduct.getTotalPrice() == null) {
                    salesLedgerProduct.setTotalPrice(dbProduct.getTotalPrice());
                }
                if (salesLedgerProduct.getTaxInclusiveTotalPrice() == null) {
                    salesLedgerProduct.setTaxInclusiveTotalPrice(dbProduct.getTaxInclusiveTotalPrice());
                }
                if (salesLedgerProduct.getTaxExclusiveTotalPrice() == null) {
                    salesLedgerProduct.setTaxExclusiveTotalPrice(dbProduct.getTaxExclusiveTotalPrice());
                }
                if (salesLedgerProduct.getTaxRate() == null) {
                    salesLedgerProduct.setTaxRate(dbProduct.getTaxRate());
                }
                if (salesLedgerProduct.getUnitPrice() == null) {
                    salesLedgerProduct.setUnitPrice(dbProduct.getUnitPrice());
                }
                if (salesLedgerProduct.getFreight() == null) {
                    salesLedgerProduct.setFreight(dbProduct.getFreight());
                }
                if (salesLedgerProduct.getPriceWithFreight() == null) {
                    salesLedgerProduct.setPriceWithFreight(dbProduct.getPriceWithFreight());
                }
            }
        }
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
        SalesLedger salesLedger = null;
        PurchaseLedger purchaseLedger = null;
        boolean isPrivate = false;
        if (salesLedgerProduct.getType() != null && salesLedgerProduct.getType().equals(1)) {
            salesLedger = salesLedgerMapper.selectById(salesLedgerId);
            if (salesLedger != null && Integer.valueOf(2).equals(salesLedger.getSalesType())) {
                isPrivate = true;
            }
        } else {
            purchaseLedger = purchaseLedgerMapper.selectById(salesLedgerId);
            if (purchaseLedger != null && Integer.valueOf(2).equals(purchaseLedger.getPurchaseType())) {
                isPrivate = true;
            }
        }
        BigDecimal totalPrice = isPrivate ?
                (salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO) :
                (salesLedgerProduct.getTaxInclusiveTotalPrice() != null ? salesLedgerProduct.getTaxInclusiveTotalPrice() : BigDecimal.ZERO);
        BigDecimal invoiceTotal = salesLedgerProduct.getInvoiceTotal() != null ? salesLedgerProduct.getInvoiceTotal() : BigDecimal.ZERO;
        BigDecimal ticketsTotal = salesLedgerProduct.getTicketsTotal() != null ? salesLedgerProduct.getTicketsTotal() : BigDecimal.ZERO;
        // å¾…回款,付款
        if(salesLedgerProduct.getType().equals(1)){
            salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getInvoiceTotal()));
            salesLedgerProduct.setPendingInvoiceTotal(totalPrice.subtract(invoiceTotal));
            //未开票数量+金额
            salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
            salesLedgerProduct.setNoInvoiceAmount(totalPrice);
        }else{
            salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getTicketsTotal()));
            salesLedgerProduct.setPendingTicketsTotal(totalPrice.subtract(ticketsTotal));
            // æœªæ¥ç¥¨æ•°é‡+金额
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
            salesLedgerProduct.setFutureTicketsAmount(totalPrice);
        }
        int result;
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
        if (salesLedgerProduct.getId() == null) {
            salesLedgerProduct.setRegisterDate(LocalDateTime.now());
            result = salesLedgerProductMapper.insert(salesLedgerProduct);
@@ -239,12 +328,17 @@
            wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId)
                    .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
            List<SalesLedgerProduct> productList = salesLedgerProductMapper.selectList(wrapper);
            Function<SalesLedgerProduct, BigDecimal> amountGetter = isPrivate ?
                    p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                    : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
            if (salesLedgerProduct.getType() == 1) {
                // è°ƒç”¨é€šç”¨æ–¹æ³•更新主表金额
                updateMainContractAmount(
                        salesLedgerId,
                        productList,
                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
                        amountGetter,
                        salesLedgerMapper,
                        SalesLedger.class
                );
@@ -253,7 +347,7 @@
                updateMainContractAmount(
                        salesLedgerId,
                        productList,
                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
                        amountGetter,
                        purchaseLedgerMapper,
                        PurchaseLedger.class
                );
@@ -337,6 +431,9 @@
     * åˆ é™¤ç”Ÿäº§æ•°æ®
     */
    public void deleteProductionData(List<Long> productIds) {
        if (productIds == null || productIds.isEmpty()){
            return;
        }
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -15,6 +15,7 @@
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.EnumUtil;
@@ -51,8 +52,8 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
@@ -343,14 +344,14 @@
    public AjaxResult importData(MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        try {
            InputStream inputStream = file.getInputStream();
            byte[] fileBytes = file.getBytes();
            ExcelUtil<SalesLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(SalesLedgerImportDto.class);
            Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("销售台账数据", "销售产品数据"), inputStream, 0);
            if (CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("销售表格为空!");
            // ä¸šåŠ¡å±‚åˆå¹¶
            List<SalesLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("销售台账数据");
            // é”€å”®å°è´¦æ•°æ®ä¸è·³è¿‡æ ‡é¢˜
            List<SalesLedgerImportDto> salesLedgerImportDtoList = salesLedgerImportDtoExcelUtil.importExcel("销售台账数据", new ByteArrayInputStream(fileBytes), 0);
            // é”€å”®äº§å“æ•°æ®è·³è¿‡1行标题
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = salesLedgerImportDtoExcelUtil.importExcel("销售产品数据", new ByteArrayInputStream(fileBytes), 1);
            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("销售台账数据为空!");
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("销售产品数据");
            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("销售产品数据为空!");
            // å®¢æˆ·æ•°æ®
            List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
@@ -376,16 +377,20 @@
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
                // é€šè¿‡å®¢æˆ·åç§°æŸ¥è¯¢å®¢æˆ·ID,客户合同号
                salesLedger.setCustomerId(customers.stream()
                // æŸ¥è¯¢å®¢æˆ·æ¡£æ¡ˆå¹¶è®¾ç½®é”€å”®ç±»åž‹ï¼ˆå¯¹å…¬1/对私2)
                Customer matchedCustomer = customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getId)
                        .orElse(null));
                salesLedger.setCustomerContractNo(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getTaxpayerIdentificationNumber)
                        .orElse(null));
                        .orElse(null);
                if (matchedCustomer != null) {
                    salesLedger.setCustomerId(matchedCustomer.getId());
                    salesLedger.setSalesType(matchedCustomer.getCustomerType());
                    salesLedger.setCustomerContractNo(matchedCustomer.getTaxpayerIdentificationNumber());
                } else {
                    salesLedger.setSalesType(1);
                }
                Long aLong = sysUsers.stream()
                        .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson()))
                        .findFirst()
@@ -394,14 +399,30 @@
                if (aLong == null)
                    throw new RuntimeException("录入人:" + salesLedger.getEntryPerson() + ",无对应用户!");
                salesLedger.setEntryPerson(aLong.toString());
                // é”€å”®äº§å“æ•°æ®ç»‘定,通过销售单号获取对应销售产品数据
                // é”€å”®äº§å“æ•°æ®ç»‘定
                List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
                        .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(salesLedgerProductImportDtos))
                    throw new RuntimeException("销售单号:" + salesLedgerImportDto.getSalesContractNo() + ",无对应产品数据!");
                boolean isPrivate = Integer.valueOf(2).equals(salesLedger.getSalesType());
                // ç»Ÿä¸€è®¡ç®—合同总金额
                salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
                        .map(SalesLedgerProductImportDto::getTaxInclusiveTotalPrice)
                        .map(dto -> {
                            if (isPrivate) {
                                if (dto.getTotalPrice() != null) return dto.getTotalPrice();
                                BigDecimal up = dto.getUnitPrice() != null ? dto.getUnitPrice() : BigDecimal.ZERO;
                                BigDecimal fr = dto.getFreight() != null ? dto.getFreight() : BigDecimal.ZERO;
                                BigDecimal qty = dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO;
                                return up.add(fr).multiply(qty);
                            } else {
                                return dto.getTaxInclusiveTotalPrice() != null ? dto.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                            }
                        })
                        .reduce(BigDecimal.ZERO, BigDecimal::add));
                salesLedgerMapper.insert(salesLedger);
@@ -411,10 +432,54 @@
                    BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                    salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                    salesLedgerProduct.setType(1);
                    // è®¡ç®—不含税总价
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
                    if (isPrivate) {
                        // å¯¹ç§ä¸šåŠ¡
                        if (salesLedgerProduct.getFreight() == null) salesLedgerProduct.setFreight(BigDecimal.ZERO);
                        if (salesLedgerProduct.getUnitPrice() != null && salesLedgerProduct.getQuantity() != null) {
                            if (salesLedgerProduct.getPriceWithFreight() == null) {
                                salesLedgerProduct.setPriceWithFreight(salesLedgerProduct.getUnitPrice().add(salesLedgerProduct.getFreight()));
                            }
                            if (salesLedgerProduct.getTotalPrice() == null) {
                                salesLedgerProduct.setTotalPrice(salesLedgerProduct.getPriceWithFreight().multiply(salesLedgerProduct.getQuantity()));
                            }
                        }
                        BigDecimal tp = salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO;
                        salesLedgerProduct.setTaxInclusiveTotalPrice(tp);
                        salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getUnitPrice() != null ?
                                salesLedgerProduct.getUnitPrice().multiply(salesLedgerProduct.getQuantity()) : tp);
                        //  ä½¿ç”¨å«è¿è´¹æ€»ä»·
                        salesLedgerProduct.setNoInvoiceAmount(tp);
                        salesLedgerProduct.setPendingInvoiceTotal(tp);
                        salesLedgerProduct.setTaxRate(null);
                        salesLedgerProduct.setTaxInclusiveUnitPrice(null);
                        salesLedgerProduct.setInvoiceType(null);
                    } else {
                        // å¯¹å…¬ä¸šåŠ¡é€»è¾‘
                        if (salesLedgerProduct.getTaxInclusiveTotalPrice() != null && salesLedgerProduct.getTaxRate() != null) {
                            salesLedgerProduct.setTaxExclusiveTotalPrice(
                                    salesLedgerProduct.getTaxInclusiveTotalPrice()
                                            .divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP)
                            );
                        }
                        // å¯¹å…¬ä½¿ç”¨å«ç¨Žæ€»ä»·
                        BigDecimal titp = salesLedgerProduct.getTaxInclusiveTotalPrice() != null ? salesLedgerProduct.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                        salesLedgerProduct.setNoInvoiceAmount(titp);
                        salesLedgerProduct.setPendingInvoiceTotal(titp);
                        salesLedgerProduct.setUnitPrice(null);
                        salesLedgerProduct.setTotalPrice(null);
                        salesLedgerProduct.setFreight(BigDecimal.ZERO);
                        salesLedgerProduct.setPriceWithFreight(null);
                    }
                    // åŒ¹é…äº§å“ç§ç±»å’Œè§„格型号映射ID
                    list.stream()
                            .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel()))
                            .findFirst()
@@ -422,20 +487,12 @@
                                salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
                                salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
                            });
//                    salesLedgerProduct.setProductId(productList.stream()
//                            .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory()))
//                            .findFirst()
//                            .map(Product::getId)
//                            .orElse(null));
//                    salesLedgerProduct.setProductModelId(productModels.stream()
//                            .filter(productModel -> productModel.getModel().equals(salesLedgerProduct.getSpecificationModel()))
//                            .findFirst()
//                            .map(ProductModel::getId)
//                            .orElse(null));
                    // å¡«å……登记信息
                    salesLedgerProduct.setRegister(loginUser.getNickName());
                    salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                    salesLedgerProduct.setApproveStatus(0);
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
                    salesLedgerProductMapper.insert(salesLedgerProduct);
                    // æ·»åŠ ç”Ÿäº§æ•°æ®
                    salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
@@ -444,9 +501,9 @@
            return AjaxResult.success("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导入失败:", e);
            throw new RuntimeException("导入数据过程中发生了错误:" + e.getMessage());
        }
        return AjaxResult.success("导入失败");
    }
    @Override
@@ -612,16 +669,23 @@
            // 4. å¤„理子表数据
            List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
            if (productList != null && !productList.isEmpty()) {
                handleSalesLedgerProducts(salesLedger.getId(), productList, EnumUtil.fromCode(SaleEnum.class, salesLedgerDto.getType()));
            if (productList == null || productList.isEmpty()){
                throw new ServiceException("新增/修改失败,销售产品不能为空");
            }
                handleSalesLedgerProducts(salesLedger.getId(), productList, EnumUtil.fromCode(SaleEnum.class, salesLedgerDto.getType()), salesLedger.getSalesType());
                Function<SalesLedgerProduct, BigDecimal> amountGetter =
                    Integer.valueOf(2).equals(salesLedger.getSalesType()) ?
                        p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                        : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                updateMainContractAmount(
                        salesLedger.getId(),
                        productList,
                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
                        amountGetter,
                        salesLedgerMapper,
                        SalesLedger.class
                );
            }
            // 5. è¿ç§»ä¸´æ—¶æ–‡ä»¶åˆ°æ­£å¼ç›®å½•
            if (salesLedgerDto.getTempFileIds() != null && !salesLedgerDto.getTempFileIds().isEmpty()) {
@@ -712,6 +776,10 @@
    @Override
    public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type) {
        handleSalesLedgerProducts(salesLedgerId, products, type, 1);
    }
    public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type, Integer salesType) {
        // æŒ‰ID分组,区分新增和更新的记录
        Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
                .peek(p -> p.setSalesLedgerId(salesLedgerId))
@@ -732,8 +800,13 @@
            for (SalesLedgerProduct salesLedgerProduct : insertList) {
                salesLedgerProduct.setType(type.getCode());
                salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                if (Integer.valueOf(2).equals(salesType)) {
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO);
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO);
                } else {
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                }
                salesLedgerProductMapper.insert(salesLedgerProduct);
                // æ·»åŠ ç”Ÿäº§æ•°æ®
//                salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.basic.mapper.SupplierManageMapper">
    <select id="supplierListPage" resultType="com.ruoyi.basic.dto.SupplierManageDto">
    <select id="supplierListPage" resultType="com.ruoyi.basic.pojo.SupplierManage">
        SELECT
        T1.id,
        T1.supplier_name,
@@ -41,6 +41,7 @@
        SELECT
        T1.id,
        T1.supplier_name,
        T1.supplier_type,
        T1.taxpayer_identification_num,
        T1.company_address,
        T1.company_phone,
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -66,7 +66,7 @@
            <if test="c.supplierId != null">
                AND pl.supplier_id = #{c.supplierId}
            </if>
            <if test="c.supplierType != null and c.supplierType != ''">
            <if test="c.supplierType != null">
                AND sm.supplier_type = #{c.supplierType}
            </if>
        </where>
src/main/resources/mapper/purchase/PurchaseLedgerTemplateMapper.xml
@@ -24,6 +24,7 @@
        <result column="payment_method" property="paymentMethod" />
        <result column="execution_date" property="executionDate" />
        <result column="template_name" property="templateName" />
        <result column="template_type" property="templateType" />
    </resultMap>
</mapper>
src/main/resources/static/²É¹ºÌ¨Õ˵¼ÈëÄ£°å.xlsx
Binary files differ
src/main/resources/static/ÏúÊŲ̂Õ˵¼ÈëÄ£°å.xlsx
Binary files differ