| | |
| | | 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.IApproveProcessService; |
| | | 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.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.common.utils.uuid.UUID; |
| | | 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 org.springframework.beans.factory.annotation.Autowired; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | 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<SalesQuotationMapper, SalesQuotation> implements SalesQuotationService { |
| | | @Autowired |
| | | private SalesQuotationMapper salesQuotationMapper; |
| | | @Autowired |
| | | private SalesQuotationProductMapper salesQuotationProductMapper; |
| | | @Autowired |
| | | private SalesQuotationProductService salesQuotationProductService; |
| | | 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; |
| | | |
| | | @Autowired |
| | | private ApproveProcessServiceImpl approveProcessService; |
| | | @Override |
| | | public IPage<SalesQuotationDto> listPage(Page page, SalesQuotationDto salesQuotationDto) { |
| | | IPage<SalesQuotationDto> salesQuotationDtoIPage = salesQuotationMapper.listPage(page, salesQuotationDto); |
| | | if(CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())){ |
| | | if (CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())) { |
| | | return salesQuotationDtoIPage; |
| | | } |
| | | salesQuotationDtoIPage.getRecords().forEach(record -> { |
| | |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | SalesQuotation salesQuotation = new SalesQuotation(); |
| | | BeanUtils.copyProperties(salesQuotationDto, salesQuotation); |
| | | String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT","quotation_no"); |
| | | String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT", "quotation_no"); |
| | | salesQuotation.setQuotationNo(quotationNo); |
| | | salesQuotation.setStatus("待审批"); |
| | | salesQuotationMapper.insert(salesQuotation); |
| | | if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){ |
| | | if (CollectionUtils.isEmpty(salesQuotationDto.getProducts())) { |
| | | return true; |
| | | } |
| | | List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> { |
| | |
| | | approveProcessVO.setPrice(salesQuotationDto.getTotalAmount()); |
| | | try { |
| | | approveProcessService.addApprove(approveProcessVO); |
| | | }catch (Exception e){ |
| | | } 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); |
| | | ApproveGetAndUpdateVo vo = new ApproveGetAndUpdateVo(); |
| | | if("拒绝".equals(salesQuotationDto.getStatus())){ |
| | | vo.setApproveStatus(0); |
| | | salesQuotation.setStatus("待审批"); |
| | | } |
| | | if(salesQuotationMapper.updateById(salesQuotation)!=1){ |
| | | // if ("拒绝".equals(salesQuotationDto.getStatus())) { |
| | | // vo.setApproveStatus(0); |
| | | // salesQuotation.setStatus("待审批"); |
| | | // } |
| | | //编辑将审批改为待审批 |
| | | salesQuotation.setStatus("待审批"); |
| | | //将之前未审批的结束 |
| | | LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveType, 6) |
| | | .eq(ApproveProcess::getApproveReason, salesQuotationDto.getQuotationNo()); |
| | | List<ApproveProcess> approveProcesss = approveProcessService.list(approveProcessLambdaQueryWrapper); |
| | | approveProcesss.forEach(approveProcess -> { |
| | | approveProcess.setApproveStatus(4); |
| | | }); |
| | | approveProcessService.updateBatchById(approveProcesss); |
| | | |
| | | if (salesQuotationMapper.updateById(salesQuotation) != 1) { |
| | | return false; |
| | | } |
| | | salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, salesQuotationDto.getId())); |
| | | if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){ |
| | | if (CollectionUtils.isEmpty(salesQuotationDto.getProducts())) { |
| | | return true; |
| | | } |
| | | List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> { |
| | |
| | | |
| | | salesQuotationProductService.saveBatch(products); |
| | | // 修改报价审批 |
| | | vo.setApproveUserIds(salesQuotationDto.getApproveUserIds()); |
| | | vo.setApproveType(6); |
| | | vo.setApproveReason(salesQuotationDto.getQuotationNo()); |
| | | approveProcessService.updateApproveUser(vo); |
| | | 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; |
| | | 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::getApproveReason, salesQuotation.getQuotationNo())); |
| | | if(one != null){ |
| | | 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<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>() |
| | | .eq(Customer::getCustomerName, getStringCell(customerRow, 0, dataFormatter))); |
| | | if (CollectionUtils.isEmpty(customers)) { |
| | | throw new RuntimeException("客户不存在"); |
| | | } |
| | | List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>() |
| | | .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<QuotationRecordJSON.ProductJSON> 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<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>() |
| | | .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<SalesQuotation> salesQuotations = salesQuotationMapper.selectList(new LambdaQueryWrapper<SalesQuotation>() |
| | | .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<SalesQuotationProduct> 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<SalesQuotationProduct>() |
| | | .eq(SalesQuotationProduct::getSalesQuotationId, salesQuotation.getId())); |
| | | |
| | | List<SalesQuotationProduct> 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(); |
| | | } |
| | | } |