package com.ruoyi.project.business.service.quotation.impl;

import static com.ruoyi.project.business.enums.AuditFlowEnum.BARGAIN;
import static com.ruoyi.project.business.enums.AuditStatusEnum.*;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.QuotationUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.business.domain.TbSalesDiscount;
import com.ruoyi.project.business.domain.TqPriceDetail;
import com.ruoyi.project.business.domain.TqQuotation;
import com.ruoyi.project.business.domain.TqSalespersonSetPrice;
import com.ruoyi.project.business.domain.TqSpecification;
import com.ruoyi.project.business.domain.TqSpecificationNonStandard;
import com.ruoyi.project.business.domain.flow.FlowAuditParam;
import com.ruoyi.project.business.enums.AuditStatusEnum;
import com.ruoyi.project.business.enums.DelFlagEnum;
import com.ruoyi.project.business.enums.NodeRoleEnum;
import com.ruoyi.project.business.enums.QuotationMsgEnum;
import com.ruoyi.project.business.enums.QuotationStatusEnum;
import com.ruoyi.project.business.enums.SystemCheckResultEnum;
import com.ruoyi.project.business.mapper.quotation.TqQuotationMapper;
import com.ruoyi.project.business.mapper.quotation.TqSpecificationMapper;
import com.ruoyi.project.business.service.ITbSalesDiscountService;
import com.ruoyi.project.business.service.flow.IFlowService;
import com.ruoyi.project.business.service.quotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.ruoyi.project.system.domain.SysRole;
import com.ruoyi.project.system.domain.SysUserRole;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

// 报价流程审批
@Service
@Slf4j
public class QuoteApprovalServiceImpl extends ServiceImpl<TqQuotationMapper, TqQuotation> implements
    IQuoteApprovalService {

    public static final String ONE_HUNDRED = "100";

    @Resource
    private ITqPriceDetailService priceDetailService;

    @Resource
    private IFlowService flowService;

    @Resource
    private ITqSalespersonSetPriceService tqSalespersonSetPriceService;

    @Resource
    private ITqSpecificationNonStandardService tqSpecificationNonStandardService;

    @Resource
    private ITqSpecificationService tqSpecificationService;

    @Resource
    private TqSpecificationMapper tqSpecificationMapper;

    @Resource
    private ITbSalesDiscountService tbSalesDiscountService;

    @Resource
    private ITqPriceDetailService tqPriceDetailService;


    @Override
    @Transactional
    public void changeQuotationStatus(FlowAuditParam auditParam) {
        TqQuotation quotation = this.getById(auditParam.getBusinessId());
        if (AuditStatusEnum.INIT.getValue().equals(auditParam.getCurrentStatus())) {
            // 初始化审批流时,发邮件/站内信
            QuotationUtil.sendMsgAsync(QuotationMsgEnum.REVIEW, auditParam.getNextAuditUsers(),
                quotation.getQuotationNo());
            log.info("[{}] 未知节点状态 [{}]", auditParam.getBusinessId(), auditParam.getCurrentStatus());
            return;
        }
        String quotationStatus = null;
        JSONObject reviewResultJson = Optional.ofNullable(auditParam.getBusinessObj())
            .map(a -> a.getJSONObject("reviewResultJson")).orElse(new JSONObject());
        // 报价当前状态
        AuditStatusEnum auditStatusEnum = AuditStatusEnum.from(auditParam.getCurrentStatus());

        // 非销售确认
        if (!auditStatusEnum.getValue().equals(AuditStatusEnum.SALES_CONFIRM.getValue())) {
            // 审批通过 且非 销售确认
            if (auditParam.isPass()) {
                QuotationUtil.sendMsgAsync(QuotationMsgEnum.REVIEW, auditParam.getNextAuditUsers(),
                    quotation.getQuotationNo());
            } else {
                // 审批驳回
                QuotationUtil.sendMsgAsync(QuotationMsgEnum.REVIEW_REJECT, auditParam.getNextAuditUsers(),
                    quotation.getQuotationNo());
            }
        }

        switch (auditStatusEnum) {
            // 技术评审中
            case TECH_REVIEW_ELECTRIC:
            case TECH_REVIEW_MACHINE:
                // 技术评审通过
                for (Map.Entry<String, Object> entry : reviewResultJson.entrySet()) {
                    JSONArray from = JSONArray.from(entry.getValue());
                    for (int i = 0; i < from.size(); i++) {
                        JSONObject jsonObject = from.getJSONObject(i);
                        String solution = jsonObject.getString("solution");
                        String solutionMachine = jsonObject.getString("solutionMachine");
                        String quotationFlagElectric = jsonObject.getString("quotationFlagElectric");
                        String quotationFlagMachine = jsonObject.getString("quotationFlagMachine");
                        String buyerPrice = jsonObject.getString("buyerPrice");
                        String buyerPriceMachine = jsonObject.getString("buyerPriceMachine");
                        Long id = jsonObject.getLong("id");
                        if (Boolean.TRUE.equals(jsonObject.getBoolean("nonStandardDescFlag"))) {
                            tqSpecificationNonStandardService.update(
                                Wrappers.<TqSpecificationNonStandard>lambdaUpdate()
                                    .eq(TqSpecificationNonStandard::getId, id)
                                    .set(TqSpecificationNonStandard::getSolution, solution)
                                    .set(TqSpecificationNonStandard::getSolutionMachine, solutionMachine)
                                    .set(TqSpecificationNonStandard::getBuyerPrice, buyerPrice)
                                    .set(TqSpecificationNonStandard::getBuyerPriceMachine, buyerPriceMachine)
                                    .set(TqSpecificationNonStandard::getQuotationFlagElectric,
                                        quotationFlagElectric)
                                    .set(TqSpecificationNonStandard::getQuotationFlagMachine,
                                        quotationFlagMachine));
                        } else {
                            priceDetailService.update(
                                Wrappers.<TqPriceDetail>lambdaUpdate()
                                    .eq(TqPriceDetail::getId, id)
                                    .set(TqPriceDetail::getSolution, solution)
                                    .set(TqPriceDetail::getSolutionMachine, solutionMachine)
                                    .set(TqPriceDetail::getBuyerPrice, buyerPrice)
                                    .set(TqPriceDetail::getBuyerPriceMachine, buyerPriceMachine)
                                    .set(TqPriceDetail::getQuotationFlagElectric, quotationFlagElectric)
                                    .set(TqPriceDetail::getQuotationFlagMachine, quotationFlagMachine));
                        }
                    }
                }
                // 技术评审(机械) 且 通过
                if (auditParam.isPass() && auditStatusEnum.equals(AuditStatusEnum.TECH_REVIEW_MACHINE)) {
                    quotationStatus = QuotationStatusEnum.TREASURE.getCode();
                }
                // 技术评审驳回
                if (!auditParam.isPass()) {
                    quotationStatus = QuotationStatusEnum.REVIEW_REJECT.getCode();
                }

                if (Objects.nonNull(quotationStatus)) {
                    // 更新报价
                    this.update(Wrappers.<TqQuotation>lambdaUpdate()
                        .eq(TqQuotation::getId, auditParam.getBusinessId())
                        .set(TqQuotation::getQuotationStatus, quotationStatus));
                    // 更新电梯规格
                    tqSpecificationService.update(Wrappers.<TqSpecification>lambdaUpdate()
                        .eq(TqSpecification::getQuotationId, auditParam.getBusinessId())
                        .eq(TqSpecification::getSystemCheckResult, SystemCheckResultEnum.OFF_STANDARD.getCode())
                        .set(TqSpecification::getQuotationStatus, quotationStatus)
                    );
                }
                break;
            // 财务报价中
            case TREASURE_INQUIRY:
                // 电梯规格的非标选配价格总和MAP    KEY:specificationId  VALUE:非标选配价格总和
                for (Map.Entry<String, Object> entry : reviewResultJson.entrySet()) {
                    JSONArray from = JSONArray.from(entry.getValue());
                    for (int i = 0; i < from.size(); i++) {
                        JSONObject jsonObject = from.getJSONObject(i);
                        Long specificationId = jsonObject.getLong("specificationId");
                        String floatPercent = jsonObject.getString("floatPercent");
                        String floatPercentMachine = jsonObject.getString("floatPercentMachine");
                        String treasurePriceStr = jsonObject.getString("treasurerPrice");
                        String treasurePriceStrMachine = jsonObject.getString("treasurerPriceMachine");
                        String totalStr = jsonObject.getString("total");
                        BigDecimal treasurePrice = StringUtils.isNotBlank(treasurePriceStr)
                            ? new BigDecimal(treasurePriceStr) : BigDecimal.ZERO;
                        BigDecimal treasurePriceMachine = StringUtils.isNotBlank(treasurePriceStrMachine)
                            ? new BigDecimal(treasurePriceStrMachine) : BigDecimal.ZERO;
                        BigDecimal treasurePriceTotal = treasurePrice.add(treasurePriceMachine);
                        BigDecimal total = new BigDecimal(totalStr);
                        Long id = jsonObject.getLong("id");

                        if (Boolean.TRUE.equals(jsonObject.getBoolean("nonStandardDescFlag"))) {
                            tqSpecificationNonStandardService.update(
                                Wrappers.<TqSpecificationNonStandard>lambdaUpdate()
                                    .eq(TqSpecificationNonStandard::getId, id)
                                    .set(TqSpecificationNonStandard::getFloatPercent, floatPercent)
                                    .set(TqSpecificationNonStandard::getFloatPercentMachine, floatPercentMachine)
                                    .set(TqSpecificationNonStandard::getTreasurerPrice, treasurePrice)
                                    .set(TqSpecificationNonStandard::getTreasurerPriceMachine, treasurePriceMachine)
                                    .set(TqSpecificationNonStandard::getPrice, treasurePriceTotal)
                                    .set(TqSpecificationNonStandard::getTotal, total));
                        } else {
                            priceDetailService.update(Wrappers.<TqPriceDetail>lambdaUpdate()
                                .eq(TqPriceDetail::getId, id)
                                .set(TqPriceDetail::getFloatPercent, floatPercent)
                                .set(TqPriceDetail::getFloatPercentMachine, floatPercentMachine)
                                .set(TqPriceDetail::getTreasurerPrice, treasurePrice)
                                .set(TqPriceDetail::getTreasurerPriceMachine, treasurePriceMachine)
                                .set(TqPriceDetail::getPrice, treasurePriceTotal)
                                .set(TqPriceDetail::getTotal, total));
                        }
                    }
                }

                // 更新报价
                this.update(Wrappers.<TqQuotation>lambdaUpdate()
                        .eq(TqQuotation::getId, auditParam.getBusinessId())
                        .set(TqQuotation::getQuotationStatus, QuotationStatusEnum.SALES.getCode()));

                // 更新电梯规格
                tqSpecificationService.update(Wrappers.<TqSpecification>lambdaUpdate()
                        .eq(TqSpecification::getQuotationId, auditParam.getBusinessId())
                        .eq(TqSpecification::getSystemCheckResult, SystemCheckResultEnum.OFF_STANDARD.getCode())
                        .set(TqSpecification::getQuotationStatus, QuotationStatusEnum.SALES.getCode()));

                break;
            // 销售确认
            case SALES_CONFIRM:
                if (auditParam.isPass()){
                    QuotationUtil.sendMsgAsync(QuotationMsgEnum.REVIEW_PASS,
                            Collections.singletonList(Long.valueOf(quotation.getCreateBy())),
                            quotation.getQuotationNo());

                    // 更新价格信息
                    updatePrice(quotation.getId());

                } else {
                    // 驳回则追加财务报价及后续流程
                    flowService.insertCopy(auditParam,
                            Lists.newArrayList(TREASURE_INQUIRY.getValue(), SALES_CONFIRM.getValue()));
                    QuotationUtil.sendMsgAsync(QuotationMsgEnum.REVIEW_PASS,
                            auditParam.getNextAuditUsers(),
                            quotation.getQuotationNo());
                }

                quotationStatus = auditParam.isPass() ? QuotationStatusEnum.ALREADY_BID.getCode(): QuotationStatusEnum.TREASURE.getCode();
                // 更新报价
                this.update(Wrappers.<TqQuotation>lambdaUpdate()
                        .eq(TqQuotation::getId, auditParam.getBusinessId())
                        .set(TqQuotation::getQuotationStatus, quotationStatus));

                // 更新电梯规格
                tqSpecificationService.update(Wrappers.<TqSpecification>lambdaUpdate()
                        .eq(TqSpecification::getQuotationId, auditParam.getBusinessId())
                        .eq(TqSpecification::getSystemCheckResult, SystemCheckResultEnum.OFF_STANDARD.getCode())
                        .set(TqSpecification::getQuotationStatus, quotationStatus));
                break;
            default:
                log.info("[报价] 未知状态 [{}]", auditParam.getCurrentStatus());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updatePrice(Long id) {
        TqQuotation tqQuotation = getById(id);
        List<TqSpecification> tqSpecifications = tqSpecificationService.list(Wrappers.<TqSpecification>lambdaQuery()
                .eq(TqSpecification::getQuotationId, id)
                .eq(TqSpecification::getDelFlag, DelFlagEnum.NORMAL.getValue()));
        Map<Long, TqSpecification> existSpecificationMap = tqSpecifications.stream().collect(Collectors.toMap(TqSpecification::getId, Function.identity()));
        Map<Long, BigDecimal> nonStandardTotalMap = tqSpecificationNonStandardService.list(Wrappers.<TqSpecificationNonStandard>lambdaQuery()
                .in(TqSpecificationNonStandard::getSpecificationId, existSpecificationMap.keySet())
                .eq(TqSpecificationNonStandard::getDelFlag, DelFlagEnum.NORMAL.getValue())
        ).stream().collect(Collectors.toMap(TqSpecificationNonStandard::getSpecificationId, TqSpecificationNonStandard::getTotal));

        Map<Long, BigDecimal> nonStandardDetailMap = tqPriceDetailService.list(Wrappers.<TqPriceDetail>lambdaQuery()
                .in(TqPriceDetail::getSpecificationId, existSpecificationMap.keySet())
                .eq(TqPriceDetail::getSystemCheckResult, SystemCheckResultEnum.OFF_STANDARD.getCode())
                .eq(TqPriceDetail::getDelFlag, DelFlagEnum.NORMAL.getValue())
        ).stream().collect(Collectors.groupingBy(TqPriceDetail::getSpecificationId, Collectors.reducing(BigDecimal.ZERO, TqPriceDetail::getTotal, BigDecimal::add)));

        boolean discountFlag = Objects.nonNull(tqQuotation.getDiscountFlag()) && tqQuotation.getDiscountFlag();
        tqQuotation.setQuotationStatus(QuotationStatusEnum.SALES.getCode());
        tqQuotation.setOriginalBasicPrice(BigDecimal.ZERO);
        tqQuotation.setOriginalOptionalPrice(BigDecimal.ZERO);
        tqQuotation.setBasicPrice(BigDecimal.ZERO);
        tqQuotation.setOptionalPrice(BigDecimal.ZERO);
        tqQuotation.setPrice(BigDecimal.ZERO);

        List<TqSpecification> updateList = Lists.newArrayList();
        tqSpecifications.forEach(tqSpecification -> {
            BigDecimal price = nonStandardTotalMap.getOrDefault(tqSpecification.getId(), BigDecimal.ZERO);
            BigDecimal detailPrice = nonStandardDetailMap.getOrDefault(tqSpecification.getId(), BigDecimal.ZERO);
            price = price.add(detailPrice);
            BigDecimal optionalDiscount = tqSpecification.getOptionalPrice().divide(tqSpecification.getOriginalOptionalPrice(), 6, BigDecimal.ROUND_HALF_UP);

            price = price.multiply(tqQuotation.getExchangeRate());
            // 重新计算规格价格
            tqSpecification.setOriginalOptionalPrice(tqSpecification.getOriginalOptionalPrice().add(price));
            tqSpecification.setOptionalPrice(tqSpecification.getOriginalOptionalPrice().multiply(optionalDiscount).setScale(0, BigDecimal.ROUND_HALF_UP));
            tqSpecification.setPrice(tqSpecification.getBasicPrice().add(tqSpecification.getOptionalPrice()));
            // 重新计算基价折率
            tqSpecification.setDiscountRate(tqSpecification.getPrice().subtract(tqSpecification.getOriginalOptionalPrice()).divide(tqSpecification.getOriginalBasicPrice(), 6, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(ONE_HUNDRED)));
            updateList.add(tqSpecification);

            BigDecimal num = BigDecimal.valueOf(tqSpecification.getElevatorNumber());
            tqQuotation.setOriginalBasicPrice(tqQuotation.getOriginalBasicPrice().add(tqSpecification.getOriginalBasicPrice().multiply(num)));
            tqQuotation.setOriginalOptionalPrice(tqQuotation.getOriginalOptionalPrice().add(tqSpecification.getOriginalOptionalPrice().multiply(num)));
            tqQuotation.setBasicPrice(tqQuotation.getBasicPrice().add(tqSpecification.getBasicPrice().multiply(num)));
            tqQuotation.setOptionalPrice(tqQuotation.getOptionalPrice().add(tqSpecification.getOptionalPrice().multiply(num)));
            tqQuotation.setPrice(tqQuotation.getPrice().add(tqSpecification.getPrice().multiply(num)));
        });
        updateById(tqQuotation);
        tqSpecificationService.updateBatchById(updateList);
    }

    @Override
    public void changeBargainStatus(FlowAuditParam auditParam) {
        TqQuotation quotation = this.getById(auditParam.getBusinessId());
        if (AuditStatusEnum.INIT.getValue().equals(auditParam.getCurrentStatus())) {
            // 初始化审批流时,发邮件/站内信
            QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE, auditParam.getNextAuditUsers(),
                quotation.getQuotationNo());
            log.info("[{}] 未知节点状态", auditParam.getBusinessId());
            return;
        }
        Long bargainId = Optional.ofNullable(auditParam.getBusinessObj())
            .map(a -> a.getLong("bargainId")).orElse(0L);
        Long quotationId = Optional.ofNullable(auditParam.getBusinessObj())
            .map(a -> a.getLong("quotationId")).orElse(0L);
        String totalDiscountRate = Optional.ofNullable(auditParam.getBusinessObj())
            .map(a -> a.getString("discountRate")).orElse("");
        JSONArray tableList = Optional.ofNullable(auditParam.getBusinessObj())
            .map(a -> a.getJSONArray("tableList")).orElse(new JSONArray());

        // 报价当前状态
        AuditStatusEnum auditStatusEnum = AuditStatusEnum.from(auditParam.getCurrentStatus());
        NodeRoleEnum nodeRoleEnum = NodeRoleEnum.fromAuditStatusEnum(auditParam.getCurrentStatus());
        TbSalesDiscount salesDiscount;
        switch (auditStatusEnum) {
            // 议价审批(销售)
            case BARGAIN_APPROVAL1:
                // 议价审批(区总)
            case BARGAIN_APPROVAL2:
                // 议价审批(销售VP)
            case BARGAIN_APPROVAL3:
                // 议价审批(财务)
            case BARGAIN_APPROVAL5:
                salesDiscount = getRoleDiscount(nodeRoleEnum.getRoleId());
                log.info("议价审批获取角色折扣率  [{}] 区间 [{}]  [{}]",
                    nodeRoleEnum.getName(), salesDiscount.getMinDiscount(), salesDiscount.getMaxDiscount());
                boolean isFinish = false;
                for (int i = 0; i < tableList.size(); i++) {
                    JSONObject row = tableList.getJSONObject(i);
                    Long specificationId = row.getLong("id");
                    BigDecimal basicPrice = row.getBigDecimal("basicPrice");
                    BigDecimal optionalPrice = row.getBigDecimal("optionalPrice");
                    BigDecimal discountRate = row.getBigDecimal("discountRate");
                    BigDecimal discountBasicPrice = row.getBigDecimal("discountBasicPrice");
                    BigDecimal discountPrice = row.getBigDecimal("discountPrice");
                    // 新增议价定价表
                    TqSalespersonSetPrice tqSalespersonSetPrice = new TqSalespersonSetPrice();
                    tqSalespersonSetPrice.setBargainId(bargainId);
                    tqSalespersonSetPrice.setSpecificationId(specificationId);
                    tqSalespersonSetPrice.setBasicPrice(basicPrice);
                    tqSalespersonSetPrice.setOptionalPrice(optionalPrice);
                    tqSalespersonSetPrice.setDiscountRate(discountRate);
                    tqSalespersonSetPrice.setDiscountbasicPrice(discountBasicPrice);
                    tqSalespersonSetPrice.setDiscountPrice(discountPrice);
                    tqSalespersonSetPrice.setDelFlag(DelFlagEnum.NORMAL.getValue());
                    tqSalespersonSetPrice.setCreateBy(SecurityUtils.getStrUserId());
                    tqSalespersonSetPrice.setCreateTime(DateUtils.getNowDate());
                    tqSalespersonSetPrice.setUpdateBy(SecurityUtils.getStrUserId());
                    tqSalespersonSetPrice.setUpdateTime(DateUtils.getNowDate());
                    tqSalespersonSetPriceService.save(tqSalespersonSetPrice);
                }
                String quotationStatus = null;

                // 节点通过
                if (auditParam.isPass()) {
                    BigDecimal ratePoint = quotation.getPrice().subtract(quotation.getOriginalOptionalPrice()).divide(quotation.getOriginalBasicPrice(), 6, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(ONE_HUNDRED)).subtract(new BigDecimal(totalDiscountRate));
                    boolean isSubtract = ratePoint.compareTo(BigDecimal.ZERO) >= 0;
                    if ((isSubtract && ratePoint.compareTo(salesDiscount.getMinDiscount()) <= 0)
                            || (!isSubtract && ratePoint.abs().compareTo(salesDiscount.getMaxDiscount()) <= 0)){
                        isFinish = true;
                    }
                    if (isFinish) {
                        // 结束审批
                        this.bargainPass(quotationId);
                        quotationStatus = QuotationStatusEnum.BARGAIN_CONFIRM.getCode();
                        // 消息通知    议价驳回（通知发起议价的人）
                        QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE_PASS,
                            Collections.singletonList(Long.valueOf(quotation.getCreateBy())),
                            quotation.getQuotationNo());
                    } else {
                        // 消息通知    议价通过 且  超出折率范围 （通知下个审批角色）
                        QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE,
                            auditParam.getNextAuditUsers(),
                            quotation.getQuotationNo());
                    }
                } else {
                    // 节点驳回
                    quotationStatus = QuotationStatusEnum.BARGAIN_REJECT.getCode();
                    // 消息通知    议价驳回（通知发起议价的人）
                    QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE_REJECT,
                        Collections.singletonList(Long.valueOf(quotation.getCreateBy())),
                        quotation.getQuotationNo());
                }
                if (Objects.nonNull(quotationStatus)) {
                    // 更新报价
                    this.update(Wrappers.<TqQuotation>lambdaUpdate()
                        .eq(TqQuotation::getId, quotationId)
                        .set(TqQuotation::getQuotationStatus, quotationStatus));
                    // 更新电梯规格
                    tqSpecificationService.update(Wrappers.<TqSpecification>lambdaUpdate()
                        .eq(TqSpecification::getQuotationId, quotationId)
                        .set(TqSpecification::getQuotationStatus, quotationStatus));
                }
                break;
            // 议价审批(总经理) 101
            case BARGAIN_APPROVAL4:
                // 审批通过 且 流程结束
                if (auditParam.isPass() && auditParam.isFinish()) {
                    this.bargainPass(quotationId);
                    // 消息通知    议价通过 （通知发起议价的人）
                    QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE_PASS,
                        Collections.singletonList(Long.valueOf(quotation.getCreateBy())),
                        quotation.getQuotationNo());
                }
                if (!auditParam.isPass()) {
                    // 驳回则追加vp审核及后续流程
                    flowService.insertCopy(auditParam,
                        Lists.newArrayList(BARGAIN_APPROVAL3.getValue(), BARGAIN_APPROVAL5.getValue(), BARGAIN_APPROVAL4.getValue()));
                    // 消息通知  议价驳回 且  总经理 （通知下个审批角色）
                    QuotationUtil.sendMsgAsync(QuotationMsgEnum.APPROVE, auditParam.getNextAuditUsers(),
                        quotation.getQuotationNo());
                }
                break;
        }
    }


    // 根据当前用户的角色信息获取可用销售折率
    @Override
    public TbSalesDiscount getRoleDiscount(Long roleId) {
        List<Long> roleIds = SecurityUtils.getLoginUser().getUser().getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList());
        List<TbSalesDiscount> list = CollectionUtils.isNotEmpty(roleIds) ? tbSalesDiscountService.list(Wrappers.<TbSalesDiscount>lambdaQuery()
            .in(TbSalesDiscount::getRoleId, roleIds)
            .eq(TbSalesDiscount::getDelFlag, DelFlagEnum.NORMAL.getValue())
        ): Lists.newArrayList();
        if (CollUtil.isEmpty(list)) {
            throw new ServiceException("请先设置销售折率");
        } else {
            return list.get(0);
        }
    }

    private void bargainPass(Long quotationId) {
        String quotationStatus = QuotationStatusEnum.BARGAIN_CONFIRM.getCode();
        // 更新报价
        this.update(Wrappers.<TqQuotation>lambdaUpdate()
            .eq(TqQuotation::getId, quotationId)
            .set(TqQuotation::getQuotationStatus, quotationStatus));
        // 更新电梯规格
        tqSpecificationService.update(Wrappers.<TqSpecification>lambdaUpdate()
            .eq(TqSpecification::getQuotationId, quotationId)
            .set(TqSpecification::getQuotationStatus, quotationStatus));
        FlowAuditParam param = new FlowAuditParam();
        param.setAuditFlow((long)BARGAIN.getValue());
        param.setBusinessId(quotationId);
        flowService.finish(param);
    }

}
