package com.ruoyi.sales.service.impl; 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.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl; import com.ruoyi.approve.vo.ApproveProcessVO; import com.ruoyi.basic.mapper.CustomerMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.dto.QuotationRecordJSON; import com.ruoyi.sales.dto.SalesQuotationDto; import com.ruoyi.sales.mapper.QuotationRecordMapper; import com.ruoyi.sales.mapper.SalesQuotationMapper; import com.ruoyi.sales.mapper.SalesQuotationProductMapper; import com.ruoyi.sales.pojo.SalesQuotation; import com.ruoyi.sales.pojo.SalesQuotationProduct; import com.ruoyi.sales.service.QuotationRecordService; import com.ruoyi.sales.service.SalesQuotationProductService; import com.ruoyi.sales.service.SalesQuotationService; import lombok.RequiredArgsConstructor; import org.apache.poi.ss.usermodel.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @Service @RequiredArgsConstructor @Transactional(rollbackFor = Exception.class) public class SalesQuotationServiceImpl extends ServiceImpl implements SalesQuotationService { private final SalesQuotationMapper salesQuotationMapper; private final SalesQuotationProductMapper salesQuotationProductMapper; private final SalesQuotationProductService salesQuotationProductService; private final ApproveProcessServiceImpl approveProcessService; private final CustomerMapper customerMapper; private final SysUserMapper sysUserMapper; private final ProductModelMapper productModelMapper; private final QuotationRecordMapper quotationRecordMapper; private final QuotationRecordService quotationRecordsService; @Override public IPage listPage(Page page, SalesQuotationDto salesQuotationDto) { IPage salesQuotationDtoIPage = salesQuotationMapper.listPage(page, salesQuotationDto); if (CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())) { return salesQuotationDtoIPage; } salesQuotationDtoIPage.getRecords().forEach(record -> { List products = salesQuotationProductMapper.selectBySalesQuotationId(record.getId()); record.setProducts(products); }); return salesQuotationDtoIPage; } @Override public boolean add(SalesQuotationDto salesQuotationDto) { LoginUser loginUser = SecurityUtils.getLoginUser(); SalesQuotation salesQuotation = new SalesQuotation(); BeanUtils.copyProperties(salesQuotationDto, salesQuotation); String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT", "quotation_no"); salesQuotation.setQuotationNo(quotationNo); salesQuotation.setStatus("待审批"); salesQuotationMapper.insert(salesQuotation); if (CollectionUtils.isEmpty(salesQuotationDto.getProducts())) { return true; } List products = salesQuotationDto.getProducts().stream().map(product -> { SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct(); BeanUtils.copyProperties(product, salesQuotationProduct); salesQuotationProduct.setSalesQuotationId(salesQuotation.getId()); return salesQuotationProduct; }).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()); try { approveProcessService.addApprove(approveProcessVO); } catch (Exception e) { log.error("SalesQuotationServiceImpl error:{}", e); throw new RuntimeException("审批失败"); } return true; } @Override public boolean edit(SalesQuotationDto salesQuotationDto) { SalesQuotation salesQuotation = new SalesQuotation(); BeanUtils.copyProperties(salesQuotationDto, salesQuotation); // if ("拒绝".equals(salesQuotationDto.getStatus())) { // vo.setApproveStatus(0); // salesQuotation.setStatus("待审批"); // } //编辑将审批改为待审批 salesQuotation.setStatus("待审批"); //将之前未审批的结束 LambdaQueryWrapper approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>(); approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveType, 6) .eq(ApproveProcess::getApproveReason, salesQuotationDto.getQuotationNo()); List approveProcesss = approveProcessService.list(approveProcessLambdaQueryWrapper); approveProcesss.forEach(approveProcess -> { approveProcess.setApproveStatus(4); }); approveProcessService.updateBatchById(approveProcesss); if (salesQuotationMapper.updateById(salesQuotation) != 1) { return false; } salesQuotationProductMapper.delete(new LambdaQueryWrapper().eq(SalesQuotationProduct::getSalesQuotationId, salesQuotationDto.getId())); if (CollectionUtils.isEmpty(salesQuotationDto.getProducts())) { return true; } List products = salesQuotationDto.getProducts().stream().map(product -> { SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct(); BeanUtils.copyProperties(product, salesQuotationProduct); salesQuotationProduct.setSalesQuotationId(salesQuotation.getId()); return salesQuotationProduct; }).collect(Collectors.toList()); salesQuotationProductService.saveBatch(products); // 修改报价审批 ApproveProcessVO approveProcessVO = new ApproveProcessVO(); approveProcessVO.setApproveType(6); approveProcessVO.setApproveDeptId(SecurityUtils.getLoginUser().getCurrentDeptId()); approveProcessVO.setApproveReason(salesQuotation.getQuotationNo()); approveProcessVO.setApproveUserIds(salesQuotationDto.getApproveUserIds()); approveProcessVO.setApproveUser(SecurityUtils.getUserId()); approveProcessVO.setApproveTime(LocalDate.now().toString()); approveProcessVO.setPrice(salesQuotationDto.getTotalAmount()); try { approveProcessService.addApprove(approveProcessVO); }catch (Exception e){ log.error("SalesQuotationServiceImpl error:{}", 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().eq(SalesQuotationProduct::getSalesQuotationId, id)); // 删除报价审批 ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper() .eq(ApproveProcess::getApproveType, 6) .eq(ApproveProcess::getApproveReason, salesQuotation.getQuotationNo())); if (one != null) { approveProcessService.delByIds(Collections.singletonList(one.getId())); } return true; } @Override public QuotationRecordJSON importData(MultipartFile file, String approveUserIdsJson) { try (InputStream inputStream = file.getInputStream(); Workbook workbook = WorkbookFactory.create(inputStream)) { Sheet sheet = workbook.getNumberOfSheets() > 1 ? workbook.getSheetAt(1) : workbook.getSheetAt(0); DataFormatter dataFormatter = new DataFormatter(); QuotationRecordJSON result = new QuotationRecordJSON(); // 模板中客户信息固定在第2行(A2-F2),且只有一行 Row customerRow = sheet.getRow(1); List customers = customerMapper.selectList(new LambdaQueryWrapper() .eq(Customer::getCustomerName, getStringCell(customerRow, 0, dataFormatter))); if (CollectionUtils.isEmpty(customers)) { throw new RuntimeException("客户不存在"); } List sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper() .eq(SysUser::getNickName, getStringCell(customerRow, 1, dataFormatter))); if (CollectionUtils.isEmpty(sysUsers)) { throw new RuntimeException("业务员不存在"); } if (customerRow != null) { result.setCustomer(getStringCell(customerRow, 0, dataFormatter)); result.setSalesperson(getStringCell(customerRow, 1, dataFormatter)); result.setQuotationDate(getStringCell(customerRow, 2, dataFormatter)); result.setValidDate(getStringCell(customerRow, 3, dataFormatter)); result.setPaymentMethod(getStringCell(customerRow, 4, dataFormatter)); result.setRemark(getStringCell(customerRow, 5, dataFormatter)); } // 模板中产品表头在第7行,数据从第8行开始 List products = new ArrayList<>(); int startRow = 7; for (int i = startRow; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row == null) { continue; } String product = getStringCell(row, 0, dataFormatter); String specification = getStringCell(row, 1, dataFormatter); List productModels = productModelMapper.selectList(new LambdaQueryWrapper() .eq(ProductModel::getModel, specification)); if (CollectionUtils.isEmpty(productModels)) { throw new RuntimeException("产品不存在"); } ProductModel productModel = productModels.get(0); BigDecimal unitPrice = getDecimalCell(row, 2, dataFormatter); if (isBlank(product) && isBlank(specification) && unitPrice == null) { continue; } QuotationRecordJSON.ProductJSON item = new QuotationRecordJSON.ProductJSON(); item.setProduct(product); item.setSpecification(specification); item.setUnit(productModel.getUnit()); item.setUnitPrice(unitPrice); products.add(item); } result.setProducts(products); // 处理报价单 SalesQuotation salesQuotation = addOrUpdateApproveProcess(result, approveUserIdsJson); Integer insertResult = quotationRecordsService.add(salesQuotation.getId(), result); if (insertResult <= 0) { throw new RuntimeException("报价记录新增失败"); } return result; } catch (Exception e) { throw new RuntimeException("导入销售报价模板失败:" + e.getMessage(), e); } } private SalesQuotation addOrUpdateApproveProcess(QuotationRecordJSON quotationRecordJSON, String approveUserIdsJson) { List salesQuotations = salesQuotationMapper.selectList(new LambdaQueryWrapper() .eq(SalesQuotation::getCustomer, quotationRecordJSON.getCustomer()) .eq(SalesQuotation::getStatus, "待审批")); if (CollectionUtils.isEmpty(salesQuotations)) { LoginUser loginUser = SecurityUtils.getLoginUser(); SalesQuotation salesQuotation = new SalesQuotation(); String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT", "quotation_no"); salesQuotation.setQuotationNo(quotationNo); salesQuotation.setCustomer(quotationRecordJSON.getCustomer()); salesQuotation.setSalesperson(quotationRecordJSON.getSalesperson()); salesQuotation.setQuotationDate(LocalDate.parse(quotationRecordJSON.getQuotationDate())); salesQuotation.setValidDate(LocalDate.parse(quotationRecordJSON.getValidDate())); salesQuotation.setPaymentMethod(quotationRecordJSON.getPaymentMethod()); salesQuotation.setStatus("待审批"); BigDecimal totalAmount = quotationRecordJSON.getProducts().stream() .map(QuotationRecordJSON.ProductJSON::getUnitPrice) .reduce(BigDecimal.ZERO, BigDecimal::add); salesQuotation.setTotalAmount(totalAmount); salesQuotationMapper.insert(salesQuotation); List products = quotationRecordJSON.getProducts().stream().map(product -> { SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct(); salesQuotationProduct.setProduct(product.getProduct()); salesQuotationProduct.setSpecification(product.getSpecification()); salesQuotationProduct.setUnit(product.getUnit()); salesQuotationProduct.setUnitPrice(product.getUnitPrice().doubleValue()); salesQuotationProduct.setSalesQuotationId(salesQuotation.getId()); return salesQuotationProduct; }).collect(Collectors.toList()); salesQuotationProductService.saveBatch(products); // 报价审批 ApproveProcessVO approveProcessVO = new ApproveProcessVO(); approveProcessVO.setApproveType(6); approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); approveProcessVO.setApproveReason(quotationNo); approveProcessVO.setApproveUserIds(approveUserIdsJson); approveProcessVO.setApproveUser(loginUser.getUserId()); approveProcessVO.setApproveTime(LocalDate.now().toString()); approveProcessVO.setPrice(salesQuotation.getTotalAmount()); try { approveProcessService.addApprove(approveProcessVO); } catch (Exception e) { log.error("SalesQuotationServiceImpl error:{}", e); throw new RuntimeException("审批失败"); } return salesQuotation; } else { if (salesQuotations.size() > 1) { throw new RuntimeException("存在多个待审批的报价单"); } else { SalesQuotation salesQuotation = salesQuotations.get(0); salesQuotation.setSalesperson(quotationRecordJSON.getSalesperson()); salesQuotation.setQuotationDate(LocalDate.parse(quotationRecordJSON.getQuotationDate())); salesQuotation.setValidDate(LocalDate.parse(quotationRecordJSON.getValidDate())); salesQuotation.setPaymentMethod(quotationRecordJSON.getPaymentMethod()); BigDecimal totalAmount = quotationRecordJSON.getProducts().stream() .map(QuotationRecordJSON.ProductJSON::getUnitPrice) .reduce(BigDecimal.ZERO, BigDecimal::add); salesQuotation.setTotalAmount(totalAmount); salesQuotationMapper.updateById(salesQuotation); // 删除原来的报价产品 salesQuotationProductMapper.delete(new LambdaQueryWrapper() .eq(SalesQuotationProduct::getSalesQuotationId, salesQuotation.getId())); List products = quotationRecordJSON.getProducts().stream().map(product -> { SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct(); salesQuotationProduct.setProduct(product.getProduct()); salesQuotationProduct.setSpecification(product.getSpecification()); salesQuotationProduct.setUnit(product.getUnit()); salesQuotationProduct.setUnitPrice(product.getUnitPrice().doubleValue()); salesQuotationProduct.setSalesQuotationId(salesQuotation.getId()); return salesQuotationProduct; }).collect(Collectors.toList()); salesQuotationProductService.saveBatch(products); return salesQuotation; } } } private String getStringCell(Row row, int columnIndex, DataFormatter dataFormatter) { if (row == null) { return null; } Cell cell = row.getCell(columnIndex); if (cell == null) { return null; } if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) { return cell.getLocalDateTimeCellValue().toLocalDate().format(DateTimeFormatter.ISO_LOCAL_DATE); } String value = dataFormatter.formatCellValue(cell); return isBlank(value) ? null : value.trim(); } private BigDecimal getDecimalCell(Row row, int columnIndex, DataFormatter dataFormatter) { String value = getStringCell(row, columnIndex, dataFormatter); if (isBlank(value)) { return null; } try { return new BigDecimal(value.replace(",", "")); } catch (Exception e) { return null; } } private boolean isBlank(String value) { return value == null || value.trim().isEmpty(); } }