yuan
13 小时以前 b9b1a775a9633a34130944d7fdbe9b9ba860aa8e
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -22,6 +22,7 @@
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.AmountUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.SecurityUtils;
@@ -63,7 +64,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.io.InputStream;
import java.lang.reflect.Field;
@@ -151,7 +151,7 @@
            // 查询退货信息
            List<Long> productIds = salesLedgerProducts.stream().map(SalesLedgerProduct::getProductModelId).collect(Collectors.toList());
            List<SimpleReturnOrderGroupDto> groupListByProductIds = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(productIds)){
            if (CollectionUtils.isNotEmpty(productIds)) {
                groupListByProductIds = purchaseReturnOrderProductsMapper.getReturnOrderGroupListByProductIds(productIds);
            }
            Map<Long, BigDecimal> returnOrderGroupDtoMap = groupListByProductIds.stream().collect(Collectors.toMap(SimpleReturnOrderGroupDto::getProductModelId, SimpleReturnOrderGroupDto::getSumReturnQuantity));
@@ -177,6 +177,7 @@
        productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedger.getId());
        productWrapper.eq(SalesLedgerProduct::getType, 1);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
        AmountUtils.normalizeSalesLedgerProducts(products);
        for (SalesLedgerProduct product : products) {
            product.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
            product.setRegisterDate(LocalDateTime.now());
@@ -186,7 +187,11 @@
                    .orderByDesc(ShippingInfo::getCreateTime)
                    .last("limit 1"));
            if (shippingInfo != null) {
                product.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                product.setShippingDate(shippingInfo.getShippingDate());
                product.setShippingStatus(shippingInfo.getStatus());
                product.setExpressCompany(shippingInfo.getExpressCompany());
                product.setExpressNumber(shippingInfo.getExpressNumber());
            }
        }
@@ -199,6 +204,7 @@
        // 4. 转换 DTO
        SalesLedgerDto resultDto = new SalesLedgerDto();
        BeanUtils.copyProperties(salesLedger, resultDto);
        AmountUtils.normalizeContractAmount(resultDto);
        if (!products.isEmpty()) {
            resultDto.setHasChildren(true);
            resultDto.setProductData(products);
@@ -298,7 +304,7 @@
            dto.setReceiptAmount(totalIncome);
            //开票金额
            List<AccountInvoiceApplication> accountInvoiceApplications = accountInvoiceApplicationMapper.selectList(new LambdaQueryWrapper<AccountInvoiceApplication>()
                            .eq(AccountInvoiceApplication::getStatus,1)
                    .eq(AccountInvoiceApplication::getStatus, 1)
                    .between(AccountInvoiceApplication::getApplyDate, startTime, endTime));
            BigDecimal totalInvoiceAmount = Optional.of(
                    accountInvoiceApplications.stream()
@@ -314,7 +320,11 @@
    @Override
    public IPage<SalesLedgerVo> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) {
        return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
        IPage<SalesLedgerVo> result = salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
        if (!CollectionUtils.isEmpty(result.getRecords())) {
            result.getRecords().forEach(AmountUtils::normalizeContractAmount);
        }
        return result;
    }
    @Override
@@ -331,17 +341,9 @@
            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("销售台账数据为空!");
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("销售产品数据");
            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("销售产品数据为空!");
            // 客户数据 - 参考 listPage 查询私海客户(type = 0)
            // type = 0(私海客户)或者 type = 1(公海客户)且已被分配,并且是自己领用、自己创建或者共享给自己的客户
            Long loginUserId = loginUser.getUser().getUserId();
            List<Customer> customers = customerMapper.selectList(new QueryWrapper<Customer>()
                    .in("customer_name", salesLedgerImportDtoList.stream()
                            .map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList()))
                    .and(wrapper -> wrapper.eq("type", 0)
                            .or(wrapper2 -> wrapper2.eq("type", 1).eq("is_assigned", 1)))
                    .and(wrapper -> wrapper.eq("usage_user", loginUserId)
                            .or(wrapper2 -> wrapper2.eq("create_user", loginUserId)
                                    .or(wrapper3 -> wrapper3.exists("select 1 from customer_user cu where cu.customer_id = customer.id and cu.user_id = " + loginUserId)))));
            // 客户数据
            List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList())));
//            // 规格型号数据
//            List<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getModel,
//                    salesLedgerProductImportDtoList.stream().map(SalesLedgerImportDto::getSpecificationModel).collect(Collectors.toList())));
@@ -359,26 +361,21 @@
                if (salesLedger1 != null) {
                    continue;
                }
                // 判断业务员是否存在
                SysUser salesman = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getNickName, salesLedgerImportDto.getSalesman()));
                if (salesman == null) {
                    throw new RuntimeException("业务员:" + salesLedgerImportDto.getSalesman() + "不存在!");
                }
                SalesLedger salesLedger = new SalesLedger();
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
                salesLedger.setDeliveryDate(DateUtils.toLocalDate(salesLedgerImportDto.getDeliveryDate()));
                // 通过客户名称查询客户ID,客户合同号
                Optional<Customer> customerOptional = customers.stream()
                salesLedger.setCustomerId(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst();
                if (customerOptional.isEmpty()) {
                    throw new RuntimeException("客户:" + salesLedger.getCustomerName() + "不存在!或者非私海用户");
                }
                salesLedger.setCustomerId(customerOptional.get().getId());
                salesLedger.setCustomerContractNo(customerOptional.get().getTaxpayerIdentificationNumber());
                        .findFirst()
                        .map(Customer::getId)
                        .orElse(null));
                salesLedger.setCustomerContractNo(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getTaxpayerIdentificationNumber)
                        .orElse(null));
                Long aLong = sysUsers.stream()
                        .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson()))
                        .findFirst()
@@ -404,18 +401,21 @@
                    BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                    salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                    salesLedgerProduct.setType(1);
                    AmountUtils.normalizeSalesLedgerProduct(salesLedgerProduct);
                    // 计算不含税总价
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    // 校验产品规格是否存在
                    Optional<Map<String, Object>> productModelOptional = list.stream()
                    salesLedgerProduct.setTaxExclusiveTotalPrice(
                            AmountUtils.calcTaxExclusiveTotalPrice(
                                    salesLedgerProduct.getTaxInclusiveTotalPrice(),
                                    salesLedgerProduct.getTaxRate()
                            )
                    );
                    list.stream()
                            .filter(map -> Objects.equals(map.get("productName"), salesLedgerProduct.getProductCategory()) && Objects.equals(map.get("model"), salesLedgerProduct.getSpecificationModel()))
                            .findFirst();
                    if (productModelOptional.isEmpty()) {
                        throw new RuntimeException("产品大类:" + salesLedgerProduct.getProductCategory() + ",规格型号:" + salesLedgerProduct.getSpecificationModel() + "不存在!");
                    }
                    Map<String, Object> productModelMap = productModelOptional.get();
                    salesLedgerProduct.setProductModelId(Long.parseLong(productModelMap.get("modelId").toString()));
                    salesLedgerProduct.setProductId(Long.parseLong(productModelMap.get("id").toString()));
                            .findFirst()
                            .ifPresent(map -> {
                                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()
@@ -462,21 +462,23 @@
            productWrapper.eq(SalesLedgerProduct::getType, 1);
            List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
            for (SalesLedgerProduct product : products) {
               product.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
                product.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
                product.setRegisterDate(LocalDateTime.now());
                // 发货信息
                ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
                        .eq(ShippingInfo::getSalesLedgerProductId, product.getId())
                        .orderByDesc(ShippingInfo::getCreateTime)
                        .last("limit 1"));
                product.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                product.setShippingDate(shippingInfo.getShippingDate());
                if (shippingInfo != null) {
                    product.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                    product.setShippingDate(shippingInfo.getShippingDate());
                    product.setShippingStatus(shippingInfo.getStatus());
                    product.setExpressCompany(shippingInfo.getExpressCompany());
                    product.setExpressNumber(shippingInfo.getExpressNumber());
                }
            }
            // 过滤只保留发货记录
            products = products.stream().filter(product -> "已发货".equals(product.getShippingStatus())).collect(Collectors.toList());
            products = products.stream().filter(product -> "审核通过".equals(product.getShippingStatus())).collect(Collectors.toList());
            if (!products.isEmpty()) {
                salesLedger.setHasChildren(true);
                salesLedger.setProductData(products);
@@ -521,6 +523,7 @@
        // 删除销售管理数据
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList)
                .eq(SalesLedgerProduct::getType, 1)
                .select(SalesLedgerProduct::getId);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(queryWrapper);
@@ -569,17 +572,14 @@
        // 2. DTO转Entity
        SalesLedger salesLedger = convertToEntity(salesLedgerDto);
        AmountUtils.normalizeContractAmount(salesLedger);
        salesLedger.setCustomerName(customer.getCustomerName());
        salesLedger.setTenantId(customer.getTenantId());
        // 录入人:如果未传则使用当前登录用户
        if (StringUtils.isEmpty(salesLedger.getEntryPerson())) {
            salesLedger.setEntryPerson(String.valueOf(SecurityUtils.getUserId()));
        }
        // 3. 新增或更新主表
        if (salesLedger.getId() == null) {
            String contractNo = salesLedger.getSalesContractNo();
            if (StringUtils.isEmpty(contractNo)) {
                contractNo = generateSalesContractNo(salesLedgerDto.getEntryDate());
                contractNo = generateSalesContractNo();
            }
            salesLedger.setSalesContractNo(contractNo);
            salesLedgerMapper.insert(salesLedger);
@@ -591,6 +591,7 @@
        // 4. 处理子表数据
        List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
        if (productList != null && !productList.isEmpty()) {
            AmountUtils.normalizeSalesLedgerProducts(productList);
            handleSalesLedgerProducts(salesLedger.getId(), productList, EnumUtil.fromCode(SaleEnum.class, salesLedgerDto.getType()));
            updateMainContractAmount(
                    salesLedger.getId(),
@@ -620,6 +621,7 @@
        // 执行更新操作
        if (!updateList.isEmpty()) {
            for (SalesLedgerProduct product : updateList) {
                AmountUtils.normalizeSalesLedgerProduct(product);
                product.setType(type.getCode());
                salesLedgerProductMapper.updateById(product);
            }
@@ -627,6 +629,7 @@
        // 执行插入操作
        if (!insertList.isEmpty()) {
            for (SalesLedgerProduct salesLedgerProduct : insertList) {
                AmountUtils.normalizeSalesLedgerProduct(salesLedgerProduct);
                salesLedgerProduct.setType(type.getCode());
                salesLedgerProductMapper.insert(salesLedgerProduct);
                // 添加生产数据
@@ -642,8 +645,8 @@
    }
    @Transactional(readOnly = true)
    public String generateSalesContractNo(Date entryDate) {
        LocalDate currentDate = entryDate != null ? DateUtils.toLocalDate(entryDate) : LocalDate.now();
    public String generateSalesContractNo() {
        LocalDate currentDate = LocalDate.now();
        String datePart = currentDate.format(DateTimeFormatter.BASIC_ISO_DATE);
        String lockKey = LOCK_PREFIX + datePart;
        String lockValue = Thread.currentThread().getId() + "-" + System.nanoTime(); // 唯一标识锁持有者
@@ -671,14 +674,15 @@
            }
            // 2. 查询当天/公司已存在的序列号(与原逻辑一致)
            Long tenantId = SecurityUtils.getLoginUser().getTenantId();
            if (null != tenantId) {
                //获取公司编号
                SysDept sysDept = sysDeptMapper.selectDeptById(tenantId.longValue());
                if (!ObjectUtils.isEmpty(sysDept)) {
                    datePart = (StringUtils.isEmpty(sysDept.getDeptNick()) ? "" : sysDept.getDeptNick()) + datePart;
                }
            }
//            Long tenantId = SecurityUtils.getLoginUser().getTenantId();
//            if (null != tenantId) {
            //获取公司编号
//                SysDept sysDept = sysDeptMapper.selectDeptById(tenantId.longValue());
//                if (!ObjectUtils.isEmpty(sysDept)) {
//                    datePart = (StringUtils.isEmpty(sysDept.getDeptNick()) ? "" : sysDept.getDeptNick()) + datePart;
//                }
//            }
            datePart = "D" + datePart;
            List<Integer> existingSequences = salesLedgerMapper.selectSequencesByDate(datePart);
            int nextSequence = findFirstMissingSequence(existingSequences);
@@ -737,7 +741,7 @@
            Field amountField = mainEntityClass.getDeclaredField("contractAmount");
            amountField.setAccessible(true);
            amountField.set(entity, totalAmount);
            amountField.set(entity, AmountUtils.scaleAmount(totalAmount));
            mainMapper.updateById(entity);
        } catch (Exception e) {
@@ -774,4 +778,19 @@
            return totalAmount;
        }
    }
    @Override
    public Map<String, Object> getPrintData(Long id) {
        SalesLedgerDto dto = new SalesLedgerDto();
        dto.setId(id);
        SalesLedgerDto ledger = getSalesLedgerWithProducts(dto);
        if (ledger == null) {
            return null;
        }
        SysDept dept = sysDeptMapper.selectDeptById(100L);
        Map<String, Object> result = new HashMap<>();
        result.put("companyName", dept != null ? dept.getDeptName() : "");
        result.put("ledger", ledger);
        return result;
    }
}