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);