From 11214e3074266a23fe61e8eebbce647fdb7305ef Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 12 六月 2026 18:02:03 +0800
Subject: [PATCH] 报价单修改-优化,增加导入记录,降价历史
---
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java | 474 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 435 insertions(+), 39 deletions(-)
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
index f181ea0..c1084b3 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
@@ -4,56 +4,94 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-
+import com.ruoyi.approve.bean.dto.ApprovalInstanceDto;
+import com.ruoyi.approve.bean.vo.ApproveGetAndUpdateVo;
+import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
+import com.ruoyi.approve.pojo.ApprovalInstance;
+import com.ruoyi.approve.pojo.ApprovalTemplate;
import com.ruoyi.approve.pojo.ApproveProcess;
-import com.ruoyi.approve.service.IApproveProcessService;
+import com.ruoyi.approve.service.ApprovalInstanceService;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
-import com.ruoyi.approve.vo.ApproveGetAndUpdateVo;
-import com.ruoyi.approve.vo.ApproveProcessVO;
+import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.common.enums.IsDeleteEnum;
+import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
-import com.ruoyi.common.utils.uuid.UUID;
+import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.sales.dto.SalesQuotationDto;
+import com.ruoyi.sales.dto.SalesQuotationImportDto;
+import com.ruoyi.sales.dto.SalesQuotationMainImportDto;
+import com.ruoyi.sales.dto.SalesQuotationProductImportDto;
+import com.ruoyi.sales.mapper.SalesQuotationImportLogMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
+import com.ruoyi.sales.mapper.SalesQuotationPriceHistoryMapper;
import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
-import com.ruoyi.sales.pojo.SalesQuotation;
-import com.ruoyi.sales.pojo.SalesQuotationProduct;
+import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.SalesQuotationProductService;
import com.ruoyi.sales.service.SalesQuotationService;
-import org.springframework.beans.factory.annotation.Autowired;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
+import java.math.BigDecimal;
import java.time.LocalDate;
-import java.util.List;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
import java.util.stream.Collectors;
+@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor
public class SalesQuotationServiceImpl extends ServiceImpl<SalesQuotationMapper, SalesQuotation> implements SalesQuotationService {
- @Autowired
- private SalesQuotationMapper salesQuotationMapper;
- @Autowired
- private SalesQuotationProductMapper salesQuotationProductMapper;
- @Autowired
- private SalesQuotationProductService salesQuotationProductService;
+ private final SalesQuotationProductMapper salesQuotationProductMapper;
+ private final SalesQuotationMapper salesQuotationMapper;
+ private final SalesQuotationProductService salesQuotationProductService;
+ private final SalesQuotationPriceHistoryMapper priceHistoryMapper;
+ private final SalesQuotationImportLogMapper importLogMapper;
- @Autowired
- private ApproveProcessServiceImpl approveProcessService;
+ private final ApproveProcessServiceImpl approveProcessService;
+ private final CustomerMapper customerMapper;
+ private final ApprovalTemplateMapper approvalTemplateMapper;
+ private final ApprovalInstanceService approvalInstanceService;
+
@Override
public IPage<SalesQuotationDto> listPage(Page page, SalesQuotationDto salesQuotationDto) {
IPage<SalesQuotationDto> salesQuotationDtoIPage = salesQuotationMapper.listPage(page, salesQuotationDto);
if(CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())){
return salesQuotationDtoIPage;
}
- salesQuotationDtoIPage.getRecords().forEach(record -> {
- List<SalesQuotationProduct> products = salesQuotationProductMapper.selectBySalesQuotationId(record.getId());
- record.setProducts(products);
- });
+
+ // 鎵归噺鏌ヨ浜у搧锛岄伩鍏� N+1 闂
+ List<Long> quotationIds = salesQuotationDtoIPage.getRecords().stream()
+ .map(SalesQuotationDto::getId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ if (!quotationIds.isEmpty()) {
+ List<SalesQuotationProduct> allProducts = salesQuotationProductMapper.selectList(
+ new LambdaQueryWrapper<SalesQuotationProduct>()
+ .in(SalesQuotationProduct::getSalesQuotationId, quotationIds)
+ );
+
+ Map<Long, List<SalesQuotationProduct>> productMap = allProducts.stream()
+ .collect(Collectors.groupingBy(SalesQuotationProduct::getSalesQuotationId));
+
+ salesQuotationDtoIPage.getRecords().forEach(record ->
+ record.setProducts(productMap.getOrDefault(record.getId(), new ArrayList<>()))
+ );
+ }
return salesQuotationDtoIPage;
}
@@ -62,7 +100,12 @@
LoginUser loginUser = SecurityUtils.getLoginUser();
SalesQuotation salesQuotation = new SalesQuotation();
BeanUtils.copyProperties(salesQuotationDto, salesQuotation);
- String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT");
+ salesQuotation.setId(null);
+ Customer customer = customerMapper.selectById(salesQuotationDto.getCustomerId());
+ if (ObjectUtils.isNotEmpty(customer)) {
+ salesQuotation.setCustomer(customer.getCustomerName());
+ }
+ String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT","quotation_no", salesQuotationDto.getCreateTime() != null ? salesQuotationDto.getCreateTime() : LocalDateTime.now());
salesQuotation.setQuotationNo(quotationNo);
salesQuotation.setStatus("寰呭鎵�");
salesQuotationMapper.insert(salesQuotation);
@@ -77,22 +120,35 @@
}).collect(Collectors.toList());
salesQuotationProductService.saveBatch(products);
// 鎶ヤ环瀹℃壒
- ApproveProcessVO approveProcessVO = new ApproveProcessVO();
- approveProcessVO.setApproveType(6);
- approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
- approveProcessVO.setApproveReason(quotationNo);
- approveProcessVO.setApproveUserIds(salesQuotationDto.getApproveUserIds());
- approveProcessVO.setApproveUser(loginUser.getUserId());
- approveProcessVO.setApproveTime(LocalDate.now().toString());
- approveProcessVO.setPrice(salesQuotationDto.getTotalAmount());
+ ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+ new LambdaQueryWrapper<ApprovalTemplate>()
+ .eq(ApprovalTemplate::getBusinessType, 6L)
+ .eq(ApprovalTemplate::getDeleted, 0)
+ .orderByDesc(ApprovalTemplate::getId)
+ .last("LIMIT 1")
+ );
+ if (approvalTemplate == null) {
+ throw new RuntimeException("璇峰厛閰嶇疆鎶ヤ环瀹℃壒妯℃澘");
+ }
+ ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
+ approvalInstance.setTemplateId(approvalTemplate.getId());
+ approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
+ approvalInstance.setBusinessId(salesQuotation.getId());
+ approvalInstance.setBusinessType(6L);
+ approvalInstance.setCurrentLevel(1);
+ approvalInstance.setTitle(quotationNo+"瀹℃壒");
+ approvalInstance.setApplicantId(loginUser.getUserId());
+ approvalInstance.setApplicantName(loginUser.getNickName());
+ approvalInstance.setApplyTime(LocalDateTime.now());
try {
- approveProcessService.addApprove(approveProcessVO);
- }catch (Exception e){
- log.error("SalesQuotationServiceImpl error:{}", e);
- throw new RuntimeException("瀹℃壒澶辫触");
+ approvalInstanceService.add(approvalInstance);
+ } catch (Exception e) {
+ log.error("SalesQuotationServiceImpl approve error for quotationNo: {}", e);
+ throw new RuntimeException("瀹℃壒澶辫触: " + e.getMessage(), e);
}
return true;
}
+
@Override
public boolean edit(SalesQuotationDto salesQuotationDto) {
SalesQuotation salesQuotation = new SalesQuotation();
@@ -118,18 +174,358 @@
salesQuotationProductService.saveBatch(products);
// 淇敼鎶ヤ环瀹℃壒
- vo.setApproveUserIds(salesQuotationDto.getApproveUserIds());
- vo.setApproveType(6);
- vo.setApproveReason(salesQuotationDto.getQuotationNo());
- approveProcessService.updateApproveUser(vo);
+ // 鍏堢粨鏉熶箣鍓嶆湭缁撴潫鐨勬姤浠峰鎵�
+ approvalInstanceService.lambdaUpdate().set(ApprovalInstance::getStatus,"REJECTED").eq(ApprovalInstance::getBusinessId,salesQuotation.getId()).eq(ApprovalInstance::getBusinessType,6L).update();
+
+ ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+ new LambdaQueryWrapper<ApprovalTemplate>()
+ .eq(ApprovalTemplate::getBusinessType, 6L)
+ .eq(ApprovalTemplate::getDeleted, 0)
+ .orderByDesc(ApprovalTemplate::getId)
+ .last("LIMIT 1")
+ );
+ if (approvalTemplate == null) {
+ throw new RuntimeException("璇峰厛閰嶇疆鎶ヤ环瀹℃壒妯℃澘");
+ }
+ ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
+ approvalInstance.setTemplateId(approvalTemplate.getId());
+ approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
+ approvalInstance.setBusinessId(salesQuotation.getId());
+ approvalInstance.setBusinessType(6L);
+ approvalInstance.setCurrentLevel(1);
+ approvalInstance.setTitle(salesQuotation.getQuotationNo()+"瀹℃壒");
+ approvalInstance.setApplicantId(SecurityUtils.getUserId());
+ approvalInstance.setApplicantName(SecurityUtils.getLoginUser().getNickName());
+ approvalInstance.setApplyTime(LocalDateTime.now());
+ try {
+ approvalInstanceService.add(approvalInstance);
+ } catch (Exception e) {
+ log.error("SalesQuotationServiceImpl approve error for quotationNo: {}", e);
+ throw new RuntimeException("瀹℃壒澶辫触: " + e.getMessage(), e);
+ }
return true;
}
+
@Override
public boolean delete(Long id) {
+ SalesQuotation salesQuotation = salesQuotationMapper.selectById(id);
+ if(salesQuotation==null) return false;
salesQuotationMapper.deleteById(id);
salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, id));
+ // 鍒犻櫎鎶ヤ环瀹℃壒
+ ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
+ .eq(ApproveProcess::getApproveType, 6)
+ .eq(ApproveProcess::getApproveDelete, IsDeleteEnum.NOT_DELETED)
+ .eq(ApproveProcess::getApproveReason, salesQuotation.getQuotationNo()));
+ if(one != null){
+ approveProcessService.delByIds(Collections.singletonList(one.getId()));
+ }
return true;
}
+ @Override
+ public void downloadTemplate(HttpServletResponse response) {
+ // 鎶ヤ环鍗曟暟鎹ず渚�
+ List<SalesQuotationMainImportDto> mainList = new ArrayList<>();
+ SalesQuotationMainImportDto mainExample = new SalesQuotationMainImportDto();
+ mainExample.setQuotationNo("QT202606120001");
+ mainExample.setCustomerName("绀轰緥瀹㈡埛");
+ mainExample.setSalesperson("寮犱笁");
+ mainExample.setPaymentMethod("鏈堢粨30澶�");
+ mainExample.setDeliveryPeriod("7澶�");
+ mainExample.setRemark("绀轰緥鎶ヤ环鍗�");
+ mainList.add(mainExample);
+ // 鎶ヤ环浜у搧鏁版嵁绀轰緥
+ List<SalesQuotationProductImportDto> productList = new ArrayList<>();
+ SalesQuotationProductImportDto productExample1 = new SalesQuotationProductImportDto();
+ productExample1.setQuotationNo("QT202606120001");
+ productExample1.setProductCategory("鐢垫睜缁勪欢");
+ productExample1.setSpecificationModel("MODEL-A-100W");
+ productExample1.setUnit("鐗�");
+ productExample1.setUnitPrice(new BigDecimal("150.00"));
+ productList.add(productExample1);
+
+ SalesQuotationProductImportDto productExample2 = new SalesQuotationProductImportDto();
+ productExample2.setQuotationNo("QT202606120001");
+ productExample2.setProductCategory("鐢垫睜缁勪欢");
+ productExample2.setSpecificationModel("MODEL-B-200W");
+ productExample2.setUnit("鐗�");
+ productExample2.setUnitPrice(new BigDecimal("200.00"));
+ productList.add(productExample2);
+
+ // 浣跨敤闈欐�佹柟娉曞鍑哄Sheet妯℃澘
+ Map<String, ExcelUtil.SheetData<?>> sheetDataMap = new LinkedHashMap<>();
+ sheetDataMap.put("鎶ヤ环鍗曟暟鎹�", new ExcelUtil.SheetData<>(mainList, SalesQuotationMainImportDto.class));
+ sheetDataMap.put("鎶ヤ环浜у搧鏁版嵁", new ExcelUtil.SheetData<>(productList, SalesQuotationProductImportDto.class));
+
+ ExcelUtil.exportExcelMultiSheet(response, sheetDataMap, "閿�鍞姤浠峰鍏ユā鏉�");
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public SalesQuotationImportLog importQuotation(MultipartFile file) {
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+
+ // 妫�鏌ュ鎵规ā鏉挎槸鍚﹀瓨鍦�
+ ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectOne(
+ new LambdaQueryWrapper<ApprovalTemplate>()
+ .eq(ApprovalTemplate::getBusinessType, 6L)
+ .eq(ApprovalTemplate::getDeleted, 0)
+ .orderByDesc(ApprovalTemplate::getId)
+ .last("LIMIT 1")
+ );
+ if (approvalTemplate == null) {
+ throw new ServiceException("璇峰厛閰嶇疆鎶ヤ环瀹℃壒妯℃澘锛屾棤娉曞鍏�");
+ }
+
+ // 瑙f瀽澶歋heet Excel鏂囦欢
+ ExcelUtil<SalesQuotationMainImportDto> mainUtil = new ExcelUtil<>(SalesQuotationMainImportDto.class);
+ Map<String, List<SalesQuotationMainImportDto>> sheetMap;
+ try {
+ sheetMap = mainUtil.importExcelMultiSheet(Arrays.asList("鎶ヤ环鍗曟暟鎹�", "鎶ヤ环浜у搧鏁版嵁"), file.getInputStream(), 0);
+ } catch (IOException e) {
+ throw new ServiceException("璇诲彇鏂囦欢澶辫触: " + e.getMessage());
+ }
+
+ List<SalesQuotationMainImportDto> mainList = sheetMap.get("鎶ヤ环鍗曟暟鎹�");
+ List<SalesQuotationMainImportDto> productListRaw = sheetMap.get("鎶ヤ环浜у搧鏁版嵁");
+
+ if (CollectionUtils.isEmpty(mainList)) {
+ throw new ServiceException("鎶ヤ环鍗曟暟鎹负绌猴紝璇锋鏌ユā鏉垮唴瀹�");
+ }
+
+ // 灏嗕骇鍝佹暟鎹浆涓烘纭殑DTO绫诲瀷
+ ExcelUtil<SalesQuotationProductImportDto> productUtil = new ExcelUtil<>(SalesQuotationProductImportDto.class);
+ Map<String, List<SalesQuotationProductImportDto>> productSheetMap;
+ try {
+ productSheetMap = productUtil.importExcelMultiSheet(Arrays.asList("鎶ヤ环浜у搧鏁版嵁"), file.getInputStream(), 0);
+ } catch (IOException e) {
+ throw new ServiceException("璇诲彇浜у搧鏁版嵁澶辫触: " + e.getMessage());
+ }
+ List<SalesQuotationProductImportDto> productList = productSheetMap.get("鎶ヤ环浜у搧鏁版嵁");
+
+ // 鐢熸垚鎵规鍙�
+ String batchNo = "QT_IMP_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+
+ // 鍒涘缓瀵煎叆璁板綍
+ SalesQuotationImportLog importLog = new SalesQuotationImportLog();
+ importLog.setBatchNo(batchNo);
+ importLog.setFileName(file.getOriginalFilename());
+ importLog.setTotalCount(mainList.size());
+ importLog.setSuccessCount(0);
+ importLog.setUpdateCount(0);
+ importLog.setNewCount(0);
+ importLog.setFailCount(0);
+ importLog.setStatus("completed");
+ importLog.setCreateUser(loginUser.getUserId());
+ importLog.setCreateUserName(loginUser.getNickName());
+ importLogMapper.insert(importLog);
+
+ // 鏌ヨ鐩稿叧鏁版嵁
+ List<Customer> customers = customerMapper.selectList(
+ new LambdaQueryWrapper<Customer>()
+ .in(Customer::getCustomerName, mainList.stream()
+ .map(SalesQuotationMainImportDto::getCustomerName)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList()))
+ );
+ Map<String, Customer> customerMap = customers.stream()
+ .collect(Collectors.toMap(Customer::getCustomerName, c -> c, (a, b) -> a));
+
+ // 鎸夋姤浠峰崟鍙峰垎缁勪骇鍝�
+ Map<String, List<SalesQuotationProductImportDto>> productGroupMap = new HashMap<>();
+ if (!CollectionUtils.isEmpty(productList)) {
+ productGroupMap = productList.stream()
+ .filter(p -> p.getQuotationNo() != null && !p.getQuotationNo().isEmpty())
+ .collect(Collectors.groupingBy(SalesQuotationProductImportDto::getQuotationNo));
+ }
+
+ int successCount = 0;
+ int newCount = 0;
+ int updateCount = 0;
+ int failCount = 0;
+
+ for (SalesQuotationMainImportDto mainDto : mainList) {
+ try {
+ String customerName = mainDto.getCustomerName();
+ if (customerName == null || customerName.isEmpty()) {
+ failCount++;
+ continue;
+ }
+
+ // 鏌ユ壘瀹㈡埛
+ Customer customer = customerMap.get(customerName);
+
+ // 鍒涘缓鎶ヤ环鍗�
+ SalesQuotation quotation = new SalesQuotation();
+ quotation.setCustomer(customerName);
+ quotation.setCustomerId(customer != null ? customer.getId() : null);
+
+ // 鐢熸垚鎶ヤ环鍗曞彿
+ String quotationNo;
+ if (mainDto.getQuotationNo() != null && !mainDto.getQuotationNo().isEmpty()) {
+ quotationNo = mainDto.getQuotationNo();
+ } else {
+ quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT", "quotation_no", LocalDateTime.now());
+ }
+ quotation.setQuotationNo(quotationNo);
+
+ // 妫�鏌ユ姤浠峰崟鍙锋槸鍚﹀凡瀛樺湪
+ SalesQuotation existing = salesQuotationMapper.selectOne(
+ new LambdaQueryWrapper<SalesQuotation>()
+ .eq(SalesQuotation::getQuotationNo, quotationNo)
+ .last("LIMIT 1")
+ );
+ boolean isUpdate = existing != null;
+
+ if (isUpdate) {
+ quotation.setId(existing.getId());
+ quotation.setQuotationDate(existing.getQuotationDate());
+ quotation.setStatus(existing.getStatus());
+ } else {
+ quotation.setQuotationDate(LocalDate.now());
+ quotation.setStatus("寰呭鎵�");
+ }
+ quotation.setSalesperson(mainDto.getSalesperson());
+ quotation.setPaymentMethod(mainDto.getPaymentMethod());
+ quotation.setDeliveryPeriod(mainDto.getDeliveryPeriod());
+ quotation.setRemark("瀵煎叆鎵规鍙�: " + batchNo + (mainDto.getRemark() != null ? "锛�" + mainDto.getRemark() : ""));
+
+ // 璁$畻鎬婚噾棰濆苟淇濆瓨浜у搧
+ BigDecimal totalAmount = BigDecimal.ZERO;
+ List<SalesQuotationProduct> quotationProducts = new ArrayList<>();
+
+ List<SalesQuotationProductImportDto> products = productGroupMap.get(quotationNo);
+ if (!CollectionUtils.isEmpty(products)) {
+ for (SalesQuotationProductImportDto productDto : products) {
+ SalesQuotationProduct product = new SalesQuotationProduct();
+ product.setProduct(productDto.getProductCategory());
+ product.setSpecification(productDto.getSpecificationModel());
+ product.setUnit(productDto.getUnit());
+ product.setQuantity(0);
+ product.setUnitPrice(productDto.getUnitPrice() != null ? productDto.getUnitPrice().doubleValue() : 0.0);
+
+ BigDecimal amount = productDto.getUnitPrice() != null
+ ? productDto.getUnitPrice()
+ : BigDecimal.ZERO;
+ product.setAmount(amount.doubleValue());
+ totalAmount = totalAmount.add(amount);
+
+ quotationProducts.add(product);
+ }
+ }
+
+ quotation.setTotalAmount(totalAmount);
+ if (isUpdate) {
+ salesQuotationMapper.updateById(quotation);
+ // 鍒犻櫎鏃т骇鍝佹暟鎹�
+ salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>()
+ .eq(SalesQuotationProduct::getSalesQuotationId, existing.getId()));
+ } else {
+ salesQuotationMapper.insert(quotation);
+ }
+
+ // 淇濆瓨浜у搧骞惰褰曢檷浠峰巻鍙�
+ for (SalesQuotationProduct product : quotationProducts) {
+ product.setSalesQuotationId(quotation.getId());
+ salesQuotationProductMapper.insert(product);
+ recordPriceHistory(quotation.getId(), product, batchNo);
+ }
+
+ if (!isUpdate) {
+ // 鍒涘缓瀹℃壒瀹炰緥
+ ApprovalInstanceDto approvalInstance = new ApprovalInstanceDto();
+ approvalInstance.setTemplateId(approvalTemplate.getId());
+ approvalInstance.setTemplateName(approvalTemplate.getTemplateName());
+ approvalInstance.setBusinessId(quotation.getId());
+ approvalInstance.setBusinessType(6L);
+ approvalInstance.setCurrentLevel(1);
+ approvalInstance.setTitle(quotationNo + "瀹℃壒");
+ approvalInstance.setApplicantId(loginUser.getUserId());
+ approvalInstance.setApplicantName(loginUser.getNickName());
+ approvalInstance.setApplyTime(LocalDateTime.now());
+ approvalInstanceService.add(approvalInstance);
+ }
+
+ successCount++;
+ if (isUpdate) {
+ updateCount++;
+ } else {
+ newCount++;
+ }
+ } catch (Exception e) {
+ log.error("瀵煎叆鎶ヤ环鍗曞け璐�: {}", e.getMessage());
+ failCount++;
+ }
+ }
+
+ // 鏇存柊瀵煎叆璁板綍
+ importLog.setSuccessCount(successCount);
+ importLog.setNewCount(newCount);
+ importLog.setUpdateCount(updateCount);
+ importLog.setFailCount(failCount);
+ importLogMapper.updateById(importLog);
+
+ return importLog;
+ }
+
+ /**
+ * 璁板綍闄嶄环鍘嗗彶
+ */
+ private void recordPriceHistory(Long quotationId, SalesQuotationProduct product, String batchNo) {
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+
+ // 鏌ユ壘鐩稿悓椤圭洰鍚嶇О鐨勫巻鍙叉姤浠蜂骇鍝�
+ List<SalesQuotationProduct> historyProducts = salesQuotationProductMapper.selectList(
+ new LambdaQueryWrapper<SalesQuotationProduct>()
+ .eq(SalesQuotationProduct::getProduct, product.getProduct())
+ .ne(SalesQuotationProduct::getId, product.getId())
+ .orderByDesc(SalesQuotationProduct::getCreateTime)
+ .last("LIMIT 1")
+ );
+
+ if (!historyProducts.isEmpty()) {
+ SalesQuotationProduct historyProduct = historyProducts.get(0);
+ BigDecimal oldPrice = historyProduct.getUnitPrice() != null
+ ? new BigDecimal(historyProduct.getUnitPrice().toString())
+ : BigDecimal.ZERO;
+ BigDecimal newPrice = product.getUnitPrice() != null
+ ? new BigDecimal(product.getUnitPrice().toString())
+ : BigDecimal.ZERO;
+
+ // 濡傛灉浠锋牸鏈夊彉鍖栵紝璁板綍闄嶄环鍘嗗彶
+ if (oldPrice.compareTo(newPrice) != 0) {
+ SalesQuotationPriceHistory priceHistory = new SalesQuotationPriceHistory();
+ priceHistory.setQuotationId(quotationId);
+ priceHistory.setQuotationProductId(product.getId());
+ priceHistory.setProductName(product.getProduct());
+ priceHistory.setSpecification(product.getSpecification());
+ priceHistory.setOldPrice(oldPrice);
+ priceHistory.setNewPrice(newPrice);
+ priceHistory.setPriceChange(newPrice.subtract(oldPrice));
+ priceHistory.setImportBatch(batchNo);
+ priceHistory.setImportTime(LocalDateTime.now());
+ priceHistory.setCreateUser(loginUser.getUserId());
+ priceHistory.setCreateUserName(loginUser.getNickName());
+ priceHistory.setChangeReason(newPrice.compareTo(oldPrice) < 0 ? "闄嶄环" : "娑ㄤ环");
+ priceHistoryMapper.insert(priceHistory);
+ }
+ }
+ }
+
+ @Override
+ public IPage<SalesQuotationImportLog> listImportLog(Page page) {
+ return importLogMapper.selectPage(page,
+ new LambdaQueryWrapper<SalesQuotationImportLog>()
+ .orderByDesc(SalesQuotationImportLog::getCreateTime));
+ }
+
+ @Override
+ public List<SalesQuotationPriceHistory> listPriceHistory(Long quotationId) {
+ return priceHistoryMapper.selectList(
+ new LambdaQueryWrapper<SalesQuotationPriceHistory>()
+ .eq(SalesQuotationPriceHistory::getQuotationId, quotationId)
+ .orderByDesc(SalesQuotationPriceHistory::getImportTime));
+ }
}
--
Gitblit v1.9.3