From c1bbff15e4f64767d471de763613a54c9cb8d4b4 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期五, 24 四月 2026 14:28:15 +0800
Subject: [PATCH] feat(sales): 添加销售台账批量导入功能

---
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java |  185 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 175 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index e46f2cf..c9ba799 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -18,10 +18,14 @@
 import com.deepoove.poi.config.Configure;
 import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
 import com.ruoyi.account.service.AccountIncomeService;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.dto.ProductModelAnticlockwiseDto;
 import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.service.IProductModelService;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.enums.SaleEnum;
 import com.ruoyi.common.exception.base.BaseException;
@@ -34,13 +38,12 @@
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.other.mapper.TempFileMapper;
 import com.ruoyi.other.pojo.TempFile;
-import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.mapper.ProductStructureMapper;
 import com.ruoyi.production.service.ProductionProductMainService;
 import com.ruoyi.project.system.domain.SysDept;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserMapper;
-import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.sales.dto.*;
 import com.ruoyi.sales.mapper.*;
 import com.ruoyi.sales.pojo.*;
@@ -129,6 +132,10 @@
 
     @Autowired
     private SysUserMapper sysUserMapper;
+    @Autowired
+    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
+    @Autowired
+    private IProductModelService productModelService;
 
     @Override
     public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
@@ -475,14 +482,15 @@
         exportProcessContract.setId(id);
         SalesLedger salesLedger = salesLedgerMapper.selectById(id);
         // 鏌ヨ瀹㈡埛鍏徃淇℃伅
-        Customer customer = customerMapper.selectById(salesLedger.getCustomerId());
+        CustomerPrivatePoolDto customerPrivatePoolDto = customerPrivatePoolMapper.selectInfo(salesLedger.getCustomerId());
+
         exportProcessContract.setCreateTime(LocalDateTimeUtil.format(Optional.ofNullable(salesLedger.getExecutionDate()).orElse(LocalDate.now()), "yyyy骞碝M鏈坉d鏃�"));
         exportProcessContract.setRemark(Optional.ofNullable(salesLedger.getRemarks()).orElse("鏃�")); // 澶囨敞
         exportProcessContract.setPlaceOfSinging(Optional.ofNullable(salesLedger.getPlaceOfSinging()).orElse(""));
 
         // 濉啓鐢叉柟淇℃伅
-        ExportProcessContractVo.Customer partyA = ExportProcessContractVo.Customer.getCustomer(customer);
-        exportProcessContract.setPartyAClientName(customer.getCustomerName());
+        ExportProcessContractVo.Customer partyA = ExportProcessContractVo.Customer.getCustomer(customerPrivatePoolDto);
+        exportProcessContract.setPartyAClientName(customerPrivatePoolDto.getCustomerName());
         exportProcessContract.setPartyA(partyA);
 
         // 濉啓涔欐柟淇℃伅
@@ -522,6 +530,141 @@
         exportProcessContract.setTotalAmountZh(Convert.digitToChinese(totalAmount[0].doubleValue()));
 
         exportProcessContractToWord(exportProcessContract);
+    }
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxResult importSalsesLedger(MultipartFile file) {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        int successCount = 0;
+        Date lastDate = null;
+        BigDecimal lastUnitPrice = null;
+        int skipCount = 0;
+        List<String> errorMessages = new ArrayList<>();
+        CustomerPrivatePoolDto lastCustomer = null;
+
+        try {
+            InputStream inputStream = file.getInputStream();
+            ExcelUtil<SalesLedgerSimpleImportDto> excelUtil = new ExcelUtil<>(SalesLedgerSimpleImportDto.class);
+            List<SalesLedgerSimpleImportDto> importDataList = excelUtil.importExcel(inputStream);
+
+            if (CollectionUtils.isEmpty(importDataList)) {
+                return AjaxResult.error("瀵煎叆鏁版嵁涓虹┖锛�");
+            }
+
+            List<String> customerNames = importDataList.stream()
+                    .map(SalesLedgerSimpleImportDto::getCustomerName)
+                    .filter(StrUtil::isNotBlank)
+                    .distinct()
+                    .collect(Collectors.toList());
+
+            List<CustomerPrivatePoolDto> customers = customerPrivatePoolMapper.selectByCusterNames(customerNames);
+
+            for (int i = 0; i < importDataList.size(); i++) {
+                SalesLedgerSimpleImportDto importDto = importDataList.get(i);
+                int rowNum = i + 2;
+
+                if (StrUtil.isBlank(importDto.getOrderNo())) {
+                    errorMessages.add(String.format("绗�%d琛岋細璁㈠崟缂栧彿涓虹┖", rowNum));
+                    skipCount++;
+                    continue;
+                }
+
+                if (importDto.getQuantity() == null ) {
+                    errorMessages.add(String.format("绗�%d琛岋細鏁伴噺涓嶈兘涓虹┖", rowNum));
+                    skipCount++;
+                    continue;
+                }
+
+                long count = salesLedgerMapper.selectCount(new LambdaQueryWrapper<SalesLedger>()
+                        .eq(SalesLedger::getSalesContractNo, importDto.getOrderNo()));
+                if (count > 0) {
+                    errorMessages.add(String.format("绗�%d琛岋細璁㈠崟缂栧彿[%s]宸插瓨鍦�", rowNum, importDto.getOrderNo()));
+                    skipCount++;
+                    continue;
+                }
+
+                CustomerPrivatePoolDto matchedCustomer = customers.stream()
+                        .filter(c -> c.getCustomerName().equals(importDto.getCustomerName()))
+                        .findFirst()
+                        .orElse(lastCustomer);
+
+                if (matchedCustomer == null) {
+                    errorMessages.add(String.format("绗�%d琛岋細瀹㈡埛[%s]涓嶅瓨鍦ㄤ笖鏃犲巻鍙插鎴�", rowNum, importDto.getCustomerName()));
+                    skipCount++;
+                    continue;
+                }
+
+                lastCustomer = matchedCustomer;
+
+                try {
+                    SalesLedger salesLedger = new SalesLedger();
+                    salesLedger.setSalesContractNo(importDto.getOrderNo());
+                    salesLedger.setCustomerName(matchedCustomer.getCustomerName());
+                    salesLedger.setCustomerId(matchedCustomer.getCustomerId());
+                    salesLedger.setCustomerContractNo(matchedCustomer.getTaxpayerIdentificationNumber());
+                    Date date = importDto.getOrderDate();
+                    if (ObjectUtils.isEmpty(date)){
+                        date = lastDate;
+                    }
+                    lastDate = date;
+                    salesLedger.setEntryDate(date);
+                    salesLedger.setContractAmount(importDto.getAmount());
+                    salesLedger.setEntryPerson(loginUser.getUserId().toString());
+                    salesLedger.setTenantId(matchedCustomer.getTenantId());
+                    salesLedgerMapper.insert(salesLedger);
+
+                    SalesLedgerProduct product = new SalesLedgerProduct();
+                    product.setSalesLedgerId(salesLedger.getId());
+                    product.setType(1);
+                    product.setQuantity(importDto.getQuantity());
+                    BigDecimal unitPrice = importDto.getUnitPrice();
+                    if (ObjectUtils.isEmpty(unitPrice)) {
+                        unitPrice = lastUnitPrice;
+                    }
+                    lastUnitPrice = unitPrice;
+                    product.setTaxInclusiveUnitPrice(unitPrice);
+                    product.setTaxInclusiveTotalPrice(unitPrice.multiply(importDto.getQuantity()));
+                    product.setTaxExclusiveTotalPrice(unitPrice.multiply(importDto.getQuantity()));
+                    product.setNoInvoiceNum(importDto.getQuantity());
+                    product.setNoInvoiceAmount(importDto.getAmount());
+                    product.setPendingInvoiceTotal(importDto.getAmount());
+                    product.setUnit("/");
+                    product.setProductCategory(importDto.getProductName());
+                    product.setSpecificationModel(importDto.getProductName());
+                    product.setRegister(loginUser.getNickName());
+                    product.setRegisterDate(LocalDateTime.now());
+                    product.setApproveStatus(0);
+
+                    if (ObjectUtils.isEmpty(product.getProductModelId())) {
+                        ProductModelAnticlockwiseDto productModelAnticlockwiseDto = new ProductModelAnticlockwiseDto();
+                        productModelAnticlockwiseDto.setModel(product.getSpecificationModel());
+                        productModelAnticlockwiseDto.setProductName(product.getProductCategory());
+                        productModelAnticlockwiseDto.setUnit("/");
+                        productModelAnticlockwiseDto.setSubUnit("/");
+                        Long productModelId = productModelService.productModelAnticlockwise(productModelAnticlockwiseDto);
+                        product.setProductModelId(productModelId);
+                    }
+
+                    salesLedgerProductMapper.insert(product);
+                    salesLedgerProductServiceImpl.addProductionData(product);
+                    successCount++;
+
+                } catch (Exception e) {
+                    log.error("绗瑊}琛岃鍗昜{}]瀵煎叆澶辫触锛歿}", rowNum, importDto.getOrderNo(), e.getMessage(), e);
+                    errorMessages.add(String.format("绗�%d琛岃鍗昜%s]锛氬鍏ュけ璐�-%s", rowNum, importDto.getOrderNo(), e.getMessage()));
+                    skipCount++;
+                }
+            }
+
+            String message = String.format("瀵煎叆瀹屾垚锛佹垚鍔�%d鏉★紝璺宠繃%d鏉�", successCount, skipCount);
+            if (!errorMessages.isEmpty()) {
+                message += "銆傞敊璇鎯咃細" + String.join("锛�", errorMessages);
+            }
+            return AjaxResult.success(message);
+        } catch (Exception e) {
+            log.error("瀵煎叆閿�鍞彴璐﹀け璐�", e);
+            throw new RuntimeException("瀵煎叆澶辫触锛�" + e.getMessage(), e);
+        }
     }
 
     @SneakyThrows
@@ -603,11 +746,12 @@
         List<Long> productIds = products.stream()
                 .map(SalesLedgerProduct::getId)
                 .collect(Collectors.toList());
-        //鍒犻櫎鐢熶骇鏁版嵁
-        salesLedgerProductServiceImpl.deleteProductionData(productIds);
+
 
         // 鎵归噺鍒犻櫎浜у搧瀛愯〃
         if (!productIds.isEmpty()) {
+            //鍒犻櫎鐢熶骇鏁版嵁
+            salesLedgerProductServiceImpl.deleteProductionData(productIds);
             salesLedgerProductMapper.deleteBatchIds(productIds);
         }
 
@@ -658,28 +802,48 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto) {
-        try {
             // 1. 鏍¢獙瀹㈡埛淇℃伅
-            Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId());
+            CustomerPrivatePoolDto customer = customerPrivatePoolMapper.selectInfo(salesLedgerDto.getCustomerId());
             if (customer == null) {
                 throw new BaseException("瀹㈡埛涓嶅瓨鍦�");
             }
+            // 蹇呴』濉啓閿�鍞悎鍚屽彿
+//            Assert.notNull(salesLedgerDto.getSalesContractNo(), "閿�鍞悎鍚屽彿涓嶈兘涓虹┖");
 
             // 2. DTO杞珽ntity
             SalesLedger salesLedger = convertToEntity(salesLedgerDto);
             salesLedger.setCustomerName(customer.getCustomerName());
             salesLedger.setTenantId(customer.getTenantId());
+
             // 3. 鏂板鎴栨洿鏂颁富琛�
             if (salesLedger.getId() == null) {
-                String contractNo = generateSalesContractNoBy8Date();
+                // 涓虹┖ 鑷姩鐢熸垚
+                String contractNo =StrUtil.isBlank(salesLedgerDto.getSalesContractNo())? generateSalesContractNoBy8Date():salesLedgerDto.getSalesContractNo();
+                // 涓嶈兘鏈夐噸澶嶆暟鎹殑鍚堝悓鍙�
+               Assert.isTrue(salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
+                        .eq(SalesLedger::getSalesContractNo, contractNo)
+                        .last("limit 1")) == null, contractNo+"鍚堝悓鍙峰凡瀛樺湪");
                 salesLedger.setSalesContractNo(contractNo);
                 salesLedgerMapper.insert(salesLedger);
             } else {
+                salesLedger.setSalesContractNo(null);
                 salesLedgerMapper.updateById(salesLedger);
             }
 
             // 4. 澶勭悊瀛愯〃鏁版嵁
             List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
+            for (SalesLedgerProduct product : productList) {
+                //绌虹殑鍏堟柊澧炲熀纭�鏁版嵁  闈炵┖鐩存帴寰�涓嬭蛋
+                if (ObjectUtils.isEmpty(product.getProductModelId())) {
+                    ProductModelAnticlockwiseDto  productModelAnticlockwiseDto =  new ProductModelAnticlockwiseDto();
+                    productModelAnticlockwiseDto.setModel(product.getSpecificationModel());
+                    productModelAnticlockwiseDto.setProductName(product.getProductCategory());
+                    productModelAnticlockwiseDto.setUnit(product.getUnit());
+                    productModelAnticlockwiseDto.setSubUnit(product.getUnit());
+                    Long productModelId = productModelService.productModelAnticlockwise(productModelAnticlockwiseDto);
+                    product.setProductModelId(productModelId);
+                }
+            }
             if (productList != null && !productList.isEmpty()) {
                 handleSalesLedgerProducts(salesLedger.getId(), productList, EnumUtil.fromCode(SaleEnum.class, salesLedgerDto.getType()));
                 updateMainContractAmount(
@@ -690,6 +854,7 @@
                         SalesLedger.class
                 );
             }
+        try {
 
             // 5. 杩佺Щ涓存椂鏂囦欢鍒版寮忕洰褰�
             if (salesLedgerDto.getTempFileIds() != null && !salesLedgerDto.getTempFileIds().isEmpty()) {

--
Gitblit v1.9.3