package com.sunxung.factoring.service.refundsManagement.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.*;
import com.sunxung.factoring.entity.customerinformation.SupplierBankCardInfo;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.ledger.LedgerAccountBasicInfo;
import com.sunxung.factoring.entity.ledger.LedgerFundGoodsAssign;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectCoreEnterprise;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingTaskVo;
import com.sunxung.factoring.entity.project.vo.SearchBusinessProcessingTask;
import com.sunxung.factoring.entity.refundsManagement.*;
import com.sunxung.factoring.entity.refundsManagement.vo.FactoringBusinessLoanRecordAccountsReceivableVo;
import com.sunxung.factoring.entity.refundsManagement.vo.LedgerDetailsVo;
import com.sunxung.factoring.entity.refundsManagement.vo.PaymentCollectionBasicVo;
import com.sunxung.factoring.entity.refundsManagement.vo.RefundManagementVo;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesContract;
import com.sunxung.factoring.entity.supplier.SupplierInfo;
import com.sunxung.factoring.entity.sys.Dictionary;
import com.sunxung.factoring.entity.underlying.sop.PaymentCollectionPlanFactoring;
import com.sunxung.factoring.mapper.refundsManagement.RefundManagementMapper;
import com.sunxung.factoring.service.customerinformation.SupplierBankCardInfoService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.ledger.LedgerAccountBasicInfoService;
import com.sunxung.factoring.service.ledger.LedgerFundGoodsAssignService;
import com.sunxung.factoring.service.ledger.LedgerSupplierBankRefService;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.project.IProjectCoreEnterpriseService;
import com.sunxung.factoring.service.project.IProjectInformationService;
import com.sunxung.factoring.service.refundsManagement.*;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractService;
import com.sunxung.factoring.service.supplier.ISupplierInfoService;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.sys.SerialNumberGenerator;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 退款管理表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2024-03-04
 */
@Service("refundManagementService")
public class RefundManagementServiceImpl extends ServiceImpl<RefundManagementMapper, RefundManagement>
        implements IRefundManagementService {

    @Autowired
    private LedgerAccountBasicInfoService ledgerAccountBasicInfoService;
    @Autowired
    private LedgerFundGoodsAssignService ledgerFundGoodsAssignService;
    @Autowired
    private RestTemplate restTemplate;
    @Value("${sop.getPaymentCollBasicStatus}")
    private String getPaymentCollBasicStatus;
    @Autowired
    private IRefundManagementPayCollPlanFactoringRefService refundManagementPayCollPlanFactoringRefService;
    @Autowired
    private IRefundManagementPayCollPlanFactoringRefHisService refundManagementPayCollPlanFactoringRefHisService;
    @Autowired
    private IRefundsApplyDetailsService refundsApplyDetailsService;
    @Autowired
    private IRefundsApplyDetailsHisService refundsApplyDetailsHisService;
    @Autowired
    private IRefundDetailsHisService refundDetailsHisService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private IRefundDetailsService refundDetailsService;
    @Autowired
    private LedgerSupplierBankRefService ledgerSupplierBankRefService;
    @Autowired
    private SupplierBankCardInfoService supplierBankCardInfoService;
    @Autowired
    @Resource(name = "projectInformationService")
    private IProjectInformationService projectInformationService;
    @Autowired
    private ISupplierInfoService supplierInfoService;
    @Autowired
    private IProjectCoreEnterpriseService projectCoreEnterpriseService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Value("${sop.judgeOverdueBySocialCreditCode}")
    private String judgeOverdueBySocialCreditCodeUrl;
    @Value("${sop.getPaymentCollBasicOneStatus}")
    private String getPaymentCollBasicOneStatusUrl;
    @Autowired
    private IRefundManagementApprovalService refundManagementApprovalService;
    @Autowired
    private IRefundManagementApprovalApplyDetailsRefService refundManagementApprovalApplyDetailsRefService;
    @Autowired
    private IRefundDetailsRefundsApplyDetailsRefService refundDetailsRefundsApplyDetailsRefService;
    @Autowired
    private IRefundsApplyAccountInfoService refundsApplyAccountInfoService;
    @Autowired
    private IRefundsApplyAccountInfoHisService refundsApplyAccountInfoHisService;
    @Autowired
    private IRefundManagementHisService refundManagementHisService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private UserService userService;
    @Autowired
    private SalesContractService salesContractService;
    @Autowired
    private IRefundsApplyDetailsPayCollPlanRefService refundsApplyDetailsPayCollPlanRefService;
    @Autowired
    private SerialNumberGenerator serialNumberGenerator;
    @Value("${sop.getAllOACompanyEntityUrl}")
    private String getAllOACompanyEntityUrl;
    @Autowired
    private BusinessProcessingLogService businessProcessingLogService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(LedgerFundGoodsAssign ledgerFundGoodsAssign) {

        //首次分账时，当 履约保证金 + 质保金 + 实退金额 > 0 时 插入数据，否则需要判断是否是已融资的货物
        //如是，需要判断对应的收支计划是否存在保证金放款，负的利息、负的管理费，如果存在，插入数据，否则不做插入操作

        if (ledgerFundGoodsAssign == null) {
            throw new BusinessException(CodeUtil.FAIL, "分账货款分配信息不能为空！");
        }
        RefundManagement refundManagement = null;
        Boolean flag = false;
        BigDecimal allAmount = ledgerFundGoodsAssign.getAccrualAmount().add(ledgerFundGoodsAssign.getDiscountAmount())
                .add(ledgerFundGoodsAssign.getGuarantee());
        if (allAmount.compareTo(BigDecimal.ZERO) > 0) {
            flag = true;
        }
        if (ledgerFundGoodsAssign.getQuotaDisburseBatch() != null) {
            //融资数据
            refundManagement = lambdaQuery().eq(RefundManagement::getBusinessNumber, ledgerFundGoodsAssign.getBusinessNumber())
                    .eq(RefundManagement::getContractNo, ledgerFundGoodsAssign.getContractNo())
                    .eq(RefundManagement::getQuotaDisburseBatch, ledgerFundGoodsAssign.getQuotaDisburseBatch()).one();
        }
        if (!flag && refundManagement == null) {
            //判断收支计划是否有保证金放款
            PaymentCollectionBasicVo paymentCollectionBasicVo = new PaymentCollectionBasicVo();
            FactoringBusinessLoanRecordAccountsReceivableVo factoringBusinessLoanRecordAccountsReceivableVo = new FactoringBusinessLoanRecordAccountsReceivableVo();
            factoringBusinessLoanRecordAccountsReceivableVo.setSopAccountsReceivableId(ledgerFundGoodsAssign.getSopAccountsReceivableId());
            factoringBusinessLoanRecordAccountsReceivableVo.setBillingFactoringBusinessLoanRecordId(ledgerFundGoodsAssign.getBillingFactoringBusinessLoanRecordId());
            paymentCollectionBasicVo.setFactoringBusinessLoanRecordAccountsReceivableVo(factoringBusinessLoanRecordAccountsReceivableVo);

            JSONObject jsonObject = restTemplate.postForObject(getPaymentCollBasicOneStatusUrl, paymentCollectionBasicVo, JSONObject.class);
            if (jsonObject != null) {
                if (jsonObject.get("code").equals(CodeUtil.FAIL)) {
                    throw new BusinessException(CodeUtil.FAIL, jsonObject.get("msg").toString());
                }
                String data = JSONArray.toJSONString(jsonObject.get("data"));
                PaymentCollectionBasicVo paymentCollectionBasicVoSop = JSON.parseObject(data
                        , PaymentCollectionBasicVo.class);
                List<PaymentCollectionPlanFactoring> plans = paymentCollectionBasicVoSop.getPaymentCollectionPlanFactorings();
                if (CollectionUtil.isNotEmpty(plans)) {
                    for (PaymentCollectionPlanFactoring plan : plans) {

                        //非已完成的计划
                        if (!plan.getStatus().getCode().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {
                            if (plan.getAmountType().getCode().equals(IncomeExpenditureTypeDict.ChildEnum.MARGIN.getCode())
                                    && plan.getPaymentCollectionType().equals(ConstantConversionUtil.PAY_COLL_PAYMENT)) {
                                //保证金放款
                                flag = true;
                            }

                            if (plan.getAmountType().getCode().equals(IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode())
                                    && plan.getAmount().compareTo(BigDecimal.ZERO) < 0) {
                                //利息 < 0
                                flag = true;
                            }

                            if ((plan.getAmountType().getCode().equals(IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode())
                                    && plan.getAmount().compareTo(BigDecimal.ZERO) < 0)) {
                                //管理费 < 0
                                flag = true;
                            }

                        }
                    }
                }

            }

        } else {
            //贸易
            refundManagement = lambdaQuery().eq(RefundManagement::getBusinessNumber, ledgerFundGoodsAssign.getBusinessNumber()).eq(RefundManagement::getQuotaDisburseBatch, null)
                    .eq(RefundManagement::getContractNo, null).one();
        }
        if (refundManagement == null && flag) {
            //新增
            refundManagement = new RefundManagement(ledgerFundGoodsAssign);
            CSalesContract salesContract = salesContractService.getByBusinessNumber(refundManagement.getBusinessNumber());
            refundManagement.setTradingPlatformId(salesContract.getTradingPlatformId());
            //生成退款编号
            String refundNumber = serialNumberGenerator.nextValue(ConstantUtil.REFUND_MANAGEMENT_CODE);
            refundManagement.setRefundNumber(refundNumber);
            //保存退款基础信息
            save(refundManagement);
        }

    }

    @Override
    public List<BusinessProcessingTaskVo> findBySearch(SearchBusinessProcessingTask search) {

        List<BusinessProcessingTaskVo> rows = baseMapper.findBySearch(search);
        if (CollectionUtil.isNotEmpty(rows)) {

            //筛选出做融资的退款
            List<PaymentCollectionBasicVo> paymentCollectionBasicVoList = new ArrayList<>();
            rows.stream().filter(financingData -> financingData.getQuotaDisburseBatch() != null).forEach(taskVo -> {

                if (taskVo.getStatus() != null) {
                    taskVo.setStatusStr(taskVo.getStatus().getName());
                }
                PaymentCollectionBasicVo paymentCollectionBasicVo = new PaymentCollectionBasicVo();
                paymentCollectionBasicVo.setContractNo(taskVo.getContractNumber());
                paymentCollectionBasicVo.setQuotaDisburseBatch(taskVo.getQuotaDisburseBatch());

                //货款分配数据
                List<LedgerFundGoodsAssign> ledgerFundGoodsAssignList = ledgerFundGoodsAssignService.lambdaQuery()
                        .eq(LedgerFundGoodsAssign::getBusinessNumber, taskVo.getBusinessNumber())
                        .eq(LedgerFundGoodsAssign::getContractNo, taskVo.getContractNumber())
                        .eq(LedgerFundGoodsAssign::getQuotaDisburseBatch, taskVo.getQuotaDisburseBatch()).list();

                if (CollectionUtil.isNotEmpty(ledgerFundGoodsAssignList)) {
                    LedgerFundGoodsAssign ledgerFundGoodsAssign = ledgerFundGoodsAssignList.get(0);
                    FactoringBusinessLoanRecordAccountsReceivableVo factoringBusinessLoanRecordAccountsReceivableVo = new FactoringBusinessLoanRecordAccountsReceivableVo();
                    factoringBusinessLoanRecordAccountsReceivableVo.setSopAccountsReceivableId(ledgerFundGoodsAssign.getSopAccountsReceivableId());
                    factoringBusinessLoanRecordAccountsReceivableVo.setBillingFactoringBusinessLoanRecordId(ledgerFundGoodsAssign.getBillingFactoringBusinessLoanRecordId());
                    paymentCollectionBasicVo.setFactoringBusinessLoanRecordAccountsReceivableVo(factoringBusinessLoanRecordAccountsReceivableVo);
                }
                paymentCollectionBasicVoList.add(paymentCollectionBasicVo);

                autoExecutor(taskVo);
            });

            autoPlanAndAmount(paymentCollectionBasicVoList, rows);

        }
        return rows;
    }

    @Override
    public RefundManagement get(Long id) {
        RefundManagement refundManagement = baseMapper.getById(id);
        if (refundManagement != null) {
            Dictionary status = dictionaryService.getByCode(refundManagement.getRefundStatus());
            refundManagement.setStatusDictionary(status);
        }
        if (refundManagement.getQuotaDisburseBatch() != null && refundManagement.getContractNumber() != null) {


            List<PaymentCollectionPlanFactoring> allPlans = findPlanBySop(refundManagement.getBusinessNumber(),
                    refundManagement.getContractNumber(), refundManagement.getQuotaDisburseBatch(), refundManagement);

            BigDecimal mustReturn = autoMustAmount(allPlans, refundManagement.getBusinessNumber(), refundManagement.getContractNumber()
                    , refundManagement.getQuotaDisburseBatch());
            refundManagement.setFinancingAmount(mustReturn);

        }

        return refundManagement;
    }

    @Override
    public RefundManagementVo edit(Long id) {

        RefundManagement refundManagement = get(id);
        if (refundManagement == null) {
            throw new BusinessException(CodeUtil.FAIL, "未查询到退款信息！");
        }

        RefundManagementVo refundManagementVo = new RefundManagementVo(refundManagement);

        //应退明细
        List<LedgerDetailsVo> ledgerDetailsVos = baseMapper.listByRefundId(id);
        if (CollectionUtil.isNotEmpty(ledgerDetailsVos)) {
            ledgerDetailsVos.forEach(detailsVo -> {
                Dictionary amountTypeDic = dictionaryService.getByCode(detailsVo.getAmountType());
                detailsVo.setAmountTypeDic(amountTypeDic);
            });

            List<List<LedgerDetailsVo>> ledgerDetailsVoLists = groupRefundDetails(ledgerDetailsVos);
            refundManagementVo.setLedgerDetails(ledgerDetailsVoLists);
        }

        //收放款执行
        if (refundManagement.getQuotaDisburseBatch() != null && refundManagement.getContractNumber() != null) {
            List<PaymentCollectionPlanFactoring> allPlans = findPlanBySop(refundManagement.getBusinessNumber(),
                    refundManagement.getContractNumber(), refundManagement.getQuotaDisburseBatch(), null);
            List<PaymentCollectionPlanFactoring> supportPlans = autoFlag(allPlans, refundManagement.getId());
            refundManagementVo.setPaymentCollectionPlanFactorings(supportPlans);
        }

        //申请内容
        List<RefundsApplyDetails> applyDetailsList = refundsApplyDetailsService.lambdaQuery().eq(RefundsApplyDetails::getStatus, 2).list();
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            applyDetailsList.forEach(apply -> {
                if (apply.getPaymentMatter() == null) {
                    apply.setOverdue(true);
                } else {
                    Dictionary paymentMatterMatterDic = dictionaryService.getByCode(apply.getPaymentMatter());
                    apply.setPaymentMatterDic(paymentMatterMatterDic);
                    Dictionary projectTypeDic = dictionaryService.getByCode(apply.getProjectType());
                    apply.setProjectTypeDic(projectTypeDic);

                    List<RefundsApplyAccountInfo> accountInfoList = refundsApplyAccountInfoService
                            .lambdaQuery().eq(RefundsApplyAccountInfo::getRefundsApplyDetailsId, apply.getId()).list();
                    if (CollectionUtil.isNotEmpty(accountInfoList)) {
                        apply.setAccountInfoList(accountInfoList);
                    }
                }

            });
        }
        refundManagementVo.setRefundsApplyDetails(applyDetailsList);


        return refundManagementVo;
    }

    @Override
    public List<RefundsApplyDetails> findBySelectAmountType(RefundManagementVo refundManagementVo) {

        if (refundManagementVo == null) {
            throw new ValidatorException(CodeUtil.FAIL, "选中的应退明细或收放款执行不能为空！");
        }

        if (CollectionUtil.isEmpty(refundManagementVo.getLedgerDetails()) &&
                CollectionUtil.isEmpty(refundManagementVo.getPaymentCollectionPlanFactorings())) {
            throw new ValidatorException(CodeUtil.FAIL, "选中的应退明细或收放款执行不能为空！");
        }

        if (refundManagementVo.getBusinessNumber() == null) {
            throw new ValidatorException(CodeUtil.FAIL, "业务编号不能为空！");
        }


        List<RefundsApplyDetails> applyDetailsList = new ArrayList<>();

        Boolean isOverdue = false;

        //已逾期只能选择抵扣 无其他字段
        // 以供应商维度，融资申请存在已逾期时，退款置灰，只支持选中抵扣
        //判断融资申请逾期->sop逾期管理 供应商下是否存在已逾期的数据
        ProjectInformation projectInformation = projectInformationService
                .lambdaQuery().eq(ProjectInformation::getBusinessNumber, refundManagementVo.getBusinessNumber()).one();
        if (projectInformation != null) {
            SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
            Enterprise enterprise = enterpriseService.getById(supplierInfo.getcEnterpriseId());
            if (enterprise == null) {
                throw new ValidatorException(CodeUtil.FAIL, "未查询到该供应商信息！");
            }
            isOverdue = restTemplate.getForObject(judgeOverdueBySocialCreditCodeUrl + "?socialCreditCode=" + enterprise.getSocialCreditCode(), Boolean.class);
        }


        //选中的 履约保证金/质保金
        List<LedgerDetailsVo> otherSelected = new ArrayList<>();
        //选中的收支计划
        List<PaymentCollectionPlanFactoring> plansSelected = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(refundManagementVo.getPaymentCollectionPlanFactorings())) {
            plansSelected.addAll(refundManagementVo.getPaymentCollectionPlanFactorings().stream()
                    .filter(plan -> plan.getSelected()).collect(Collectors.toList()));
        }

        if (CollectionUtil.isNotEmpty(refundManagementVo.getLedgerDetails())) {
            //选中的实退金额
            List<LedgerDetailsVo> actualWithdrawalSelected = new ArrayList<>();
            refundManagementVo.getLedgerDetails().stream().forEach(ledgerDetailsVos -> {
                List<LedgerDetailsVo> detailsVoList = ledgerDetailsVos.stream()
                        .filter(ledgerDetailsVo -> ledgerDetailsVo.getSelected()).filter(ledgerDetailsVo ->
                                CashFlowOutTypeDict.ChildEnum.DISCOUNT.getCode()
                                        .equals(ledgerDetailsVo.getAmountType())).collect(Collectors.toList());
                actualWithdrawalSelected.addAll(detailsVoList);
            });


            if (CollectionUtil.isNotEmpty(actualWithdrawalSelected)) {
                //oa-上游货款支付
                RefundsApplyDetails applyDetails = autoUpstreamGoodsPayment(actualWithdrawalSelected, refundManagementVo.getBusinessNumber());
                applyDetails.setOverdue(isOverdue);
                applyDetailsList.add(applyDetails);
            }
        }

        refundManagementVo.getLedgerDetails().stream().forEach(ledgerDetails -> {
            List<LedgerDetailsVo> detailsVos = ledgerDetails.stream()
                    .filter(ledgerDetailsVo -> ledgerDetailsVo.getSelected())
                    .filter(ledgerDetailsVo ->
                            CashFlowOutTypeDict.ChildEnum.PERFORMANCE_BOND.getCode().equals(ledgerDetailsVo.getAmountType())
                                    || CashFlowOutTypeDict.ChildEnum.RETENTION_MONEY.getCode().equals(ledgerDetailsVo.getAmountType()))
                    .collect(Collectors.toList());
            //履约保证金/质保金
            otherSelected.addAll(detailsVos);
        });
        if (CollectionUtil.isNotEmpty(otherSelected) || CollectionUtil.isNotEmpty(plansSelected)) {

            //金额类型：履约保证金、质保金、收放款计划 对应OA付款申请为-其他款项支付-退款类（包含退利息管理费、（履约）保证金、支付保证金等）
            RefundsApplyDetails refundsApplyDetails = autoRefundPayment(otherSelected, plansSelected, refundManagementVo.getBusinessNumber());
            refundsApplyDetails.setOverdue(isOverdue);
            applyDetailsList.add(refundsApplyDetails);
        }


        return applyDetailsList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doEdit(RefundManagementVo refundManagementVo) {

        if (refundManagementVo == null || CollectionUtil.isEmpty(refundManagementVo.getRefundsApplyDetails())) {
            throw new ValidatorException(CodeUtil.FAIL, "申请内容不能为空！");
        }

        //保存历史
        RefundManagementHis his = new RefundManagementHis();
        RefundManagement refundManagement = getById(refundManagementVo.getBusinessKey());
        //更新状态
        refundManagement.setRefundStatus(ProjectInitiationStatusDict.ChildEnum.PROCESSING.getCode());
        refundManagement.setStage("退款审核");
        updateById(refundManagement);

        BeanUtil.copyProperties(refundManagement, his);
        his.setId(null);
        his.setRefundManagementId(refundManagementVo.getBusinessKey());
        refundManagementHisService.save(his);

        //删除退回的应退明细
        refundDetailsService.remove(new QueryWrapper<RefundDetails>().eq("status", 2));
        //保存选中的应退明细
        List<List<LedgerDetailsVo>> ledgerDetails = refundManagementVo.getLedgerDetails();
        if (CollectionUtil.isNotEmpty(ledgerDetails)) {
            ledgerDetails.forEach(ledgerDetailsVoList -> {
                ledgerDetailsVoList.stream().filter(vo -> vo.getSelected()).forEach(vo -> {
                    RefundDetails refundDetails = new RefundDetails();
                    BeanUtil.copyProperties(vo, refundDetails);
                    refundDetails.setId(null);
                    refundDetails.setRefundManagementId(refundManagementVo.getBusinessKey());
                    refundDetails.setStatus(0);
                    refundDetailsService.save(refundDetails);

                    //历史
                    RefundDetailsHis refundDetailsHis = new RefundDetailsHis();
                    BeanUtil.copyProperties(refundDetails, refundDetailsHis);
                    refundDetailsHis.setRefundManagementHisId(his.getId());
                    refundDetailsHis.setId(null);
                    refundDetailsHisService.save(refundDetailsHis);
                });
            });
        }

        //删除退回的收放款计划关系
        refundManagementPayCollPlanFactoringRefService.remove(new QueryWrapper<RefundManagementPayCollPlanFactoringRef>().eq("status", 2));
        //保存选中的收放款执行
        List<PaymentCollectionPlanFactoring> planFactorings = refundManagementVo.getPaymentCollectionPlanFactorings();
        List<PaymentCollectionPlanFactoring> selectedPlans = planFactorings.stream().filter(plan -> plan.getSelected()).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(planFactorings)) {
            selectedPlans.forEach(plan -> {
                RefundManagementPayCollPlanFactoringRef refundPlanRef = new RefundManagementPayCollPlanFactoringRef();
                refundPlanRef.setRefundManagementId(refundManagementVo.getBusinessKey());
                refundPlanRef.setPayCollPlanFactoringId(plan.getId());
                refundPlanRef.setStatus(0);
                refundManagementPayCollPlanFactoringRefService.save(refundPlanRef);

                //历史
                RefundManagementPayCollPlanFactoringRefHis payCollPlanFactoringRefHis = new RefundManagementPayCollPlanFactoringRefHis();
                payCollPlanFactoringRefHis.setRefundManagementHisId(his.getId());
                payCollPlanFactoringRefHis.setPayCollPlanFactoringId(plan.getId());
                refundManagementPayCollPlanFactoringRefHisService.save(payCollPlanFactoringRefHis);

            });
        }

        //删除退回的收方账户信息
        refundsApplyAccountInfoService.remove(new QueryWrapper<RefundsApplyAccountInfo>().eq("status", 2));
        //删除退回的申请内容
        refundsApplyDetailsService.remove(new QueryWrapper<RefundsApplyDetails>().eq("status", 2));
        //保存申请内容
        List<RefundsApplyDetails> refundsApplyDetails = refundManagementVo.getRefundsApplyDetails();
        refundsApplyDetails.forEach(applyDetails -> {
            applyDetails.setRefundManagementId(refundManagementVo.getBusinessKey());
            applyDetails.setStatus(0);
            applyDetails.setUserId(ThreadLocalUtil.getUserId());
            applyDetails.setAmountCapitalization(NumberChineseFormatterUtils.format(applyDetails.getPaymentAmountTotal().doubleValue(), false, true));
            refundsApplyDetailsService.save(applyDetails);

            if (OaFlowPaymentMatterTypeDic.ChildEnum.OA_UPSTREAM_GOODS_PAYMENT_MATTER.getCode().equals(applyDetails.getPaymentMatter())
                    && CollectionUtil.isNotEmpty(selectedPlans)) {
                selectedPlans.forEach(plan -> {
                    RefundsApplyDetailsPayCollPlanRef applyDetailsPayCollPlanRef = new RefundsApplyDetailsPayCollPlanRef();
                    applyDetailsPayCollPlanRef.setRefundsApplyDetailsId(applyDetails.getId());
                    applyDetailsPayCollPlanRef.setPayCollPlanFactoringId(plan.getId());
                    refundsApplyDetailsPayCollPlanRefService.save(applyDetailsPayCollPlanRef);
                });

            }
            //历史
            RefundsApplyDetailsHis refundsApplyDetailsHis = new RefundsApplyDetailsHis();
            BeanUtil.copyProperties(applyDetails, refundsApplyDetailsHis);
            refundsApplyDetailsHis.setId(null);
            refundsApplyDetailsHis.setRefundManagementHisId(his.getId());
            refundsApplyDetailsHisService.save(refundsApplyDetailsHis);

            //保存收方账户信息
            List<RefundsApplyAccountInfo> accountInfoList = applyDetails.getAccountInfoList();
            if (CollectionUtil.isNotEmpty(accountInfoList)) {
                accountInfoList.forEach(account -> {
                    account.setRefundsApplyDetailsId(applyDetails.getId());
                    account.setStatus(0);
                    refundsApplyAccountInfoService.save(account);
                    RefundsApplyAccountInfoHis applyAccountInfoHis = new RefundsApplyAccountInfoHis();
                    BeanUtil.copyProperties(account, applyAccountInfoHis);
                    applyAccountInfoHis.setId(null);
                    applyAccountInfoHis.setRefundsApplyDetailsHisId(refundsApplyDetailsHis.getId());
                    refundsApplyAccountInfoHisService.save(applyAccountInfoHis);
                });
            }
        });

        refundManagement.setTaskId(refundManagementVo.getTaskId());
        //开启流程
        if (refundManagementVo.getTaskId() == null) {
            startProcess(refundManagement);
        }

        //处理流程
        handleProess(refundManagement, his);


    }

    @Override
    public Object getAllCompanyEntityBySop() {

        JSONObject json = restTemplate.getForObject(getAllOACompanyEntityUrl, JSONObject.class);

        if (json.get("code").equals("500")) {
            throw new BusinessException(CodeUtil.FAIL, json.get("msg").toString());
        }
        Object data = json.get("data");
        return data;
    }

    //填充收放款计划和金额
    void autoPlanAndAmount(List<PaymentCollectionBasicVo> paymentCollectionBasicVoList, List<BusinessProcessingTaskVo> rows) {
        //从sop拉取账后状态 和 收放款计划
        JSONObject json = restTemplate.postForObject(getPaymentCollBasicStatus, paymentCollectionBasicVoList, JSONObject.class);
        if (json.get("code").equals(CodeUtil.FAIL)) {
            throw new BusinessException(CodeUtil.FAIL, json.get("msg").toString());
        }
        String data = JSONArray.toJSONString(json.get("data"));
        List<PaymentCollectionBasicVo> requestList = JSON.parseArray(data
                , PaymentCollectionBasicVo.class);

        requestList.stream().forEach(paymentCollectionBasicVoSop -> {
            rows.forEach(taskVo -> {
                if (paymentCollectionBasicVoSop.getContractNo().equals(taskVo.getContractNumber()) &&
                        paymentCollectionBasicVoSop.getQuotaDisburseBatch().equals(taskVo.getQuotaDisburseBatch())) {
                    //账后状态
                    taskVo.setCoreStatusStr(paymentCollectionBasicVoSop.getBusinessStatus());
                    //收支计划
                    List<PaymentCollectionPlanFactoring> supportPlans = autoFlag(paymentCollectionBasicVoSop.getPaymentCollectionPlanFactorings(),
                            taskVo.getId());
                    taskVo.setPaymentCollectionPlanFactorings(supportPlans);

                    //计算应退金额
                    BigDecimal mustReturn = autoMustAmount(paymentCollectionBasicVoSop.getPaymentCollectionPlanFactorings(),
                            taskVo.getBusinessNumber(), taskVo.getContractNumber(), taskVo.getQuotaDisburseBatch());
                    taskVo.setSettlementAmount(mustReturn);

                    //已退金额（审核通过）
                    List<RefundsApplyDetails> applyDetailsList = refundsApplyDetailsService
                            .lambdaQuery().eq(RefundsApplyDetails::getRefundManagementId, taskVo.getId()).list();
                    if (CollectionUtil.isNotEmpty(applyDetailsList)) {
                        List<RefundsApplyDetails> passDetailsList = new ArrayList<>();
                        applyDetailsList.forEach(applyDetails -> {
                            RefundManagementApprovalApplyDetailsRef applyDetailsRef = refundManagementApprovalApplyDetailsRefService
                                    .lambdaQuery().eq(RefundManagementApprovalApplyDetailsRef::getRefundsApplyDetailsId, applyDetails.getId())
                                    .one();
                            if (applyDetailsRef != null) {
                                RefundManagementApproval approval = refundManagementApprovalService.getById(applyDetailsRef.getRefundManagementApprovalId());
                                if (ConstantConversionUtil.APPROVAL_RESULT_PASS.equals(approval.getApprovalConclusion())) {
                                    passDetailsList.add(applyDetails);
                                }
                            }
                        });
                        BigDecimal alreadyAmount = BigDecimal.ZERO;
                        for (RefundsApplyDetails detalis : passDetailsList) {
                            alreadyAmount = alreadyAmount.add(detalis.getPaymentAmountTotal());
                        }
                        taskVo.setOpenAmount(alreadyAmount);
                    } else {
                        taskVo.setOpenAmount(BigDecimal.ZERO);
                    }

                    //剩余应退
                    BigDecimal residueAmount = mustReturn.subtract(taskVo.getOpenAmount());
                    taskVo.setFinancingAmount(residueAmount);

                }
            });
        });
    }

    //填充执行人
    void autoExecutor(BusinessProcessingTaskVo taskVo) {
        if (taskVo != null) {
//            if (taskVo.getTaskName())
        }
    }

    private RefundsApplyDetails autoUpstreamGoodsPayment(List<LedgerDetailsVo> ledgerDetailsVoSelected, String businessNumber) {

        ProjectInformation projectInformation = projectInformationService
                .lambdaQuery().eq(ProjectInformation::getBusinessNumber, businessNumber).one();
        SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
        Enterprise supplier = enterpriseService.getById(supplierInfo.getcEnterpriseId());

        //金额类型：实退金额 对应OA付款申请为-其他款项支付-上游货款支付
        List<LedgerDetailsVo> detailsVoList = ledgerDetailsVoSelected.stream().filter(ledgerDetailsVo ->
                CashFlowOutTypeDict.ChildEnum.DISCOUNT.getCode()
                        .equals(ledgerDetailsVo.getAmountType())).collect(Collectors.toList());
        RefundsApplyDetails applyDetails = new RefundsApplyDetails();
        if (CollectionUtil.isNotEmpty(detailsVoList)) {

            //付款事项
            applyDetails.setPaymentMatterDic(dictionaryService
                    .getByCode(OaFlowPaymentMatterTypeDic.ChildEnum.OA_UPSTREAM_GOODS_PAYMENT_MATTER.getCode()));
            applyDetails.setPaymentMatter(OaFlowPaymentMatterTypeDic.ChildEnum.OA_UPSTREAM_GOODS_PAYMENT_MATTER.getCode());

            //付款总金额
            BigDecimal amountTotal = BigDecimal.ZERO;
            for (LedgerDetailsVo detailsVo : detailsVoList) {
                amountTotal = amountTotal.add(detailsVo.getAmount());
            }
            applyDetails.setPaymentAmountTotal(amountTotal);
            Dictionary projectTypeDic = dictionaryService.getByCode(ProjectTypeDict.ChildEnum.FACTORING_BUSINESS.getCode());
            applyDetails.setProjectTypeDic(projectTypeDic);
            applyDetails.setProjectType(projectTypeDic.getCode());
            applyDetails.setCurrency("CNY");

            //收方账户信息
            List<LedgerFundGoodsAssign> fundGoodsAssignList = ledgerFundGoodsAssignService
                    .lambdaQuery().eq(LedgerFundGoodsAssign::getBusinessNumber, businessNumber).list();
            if (CollectionUtil.isNotEmpty(fundGoodsAssignList)) {
                List<LedgerAccountBasicInfo> ledgerAccountBasicInfos = fundGoodsAssignList.stream().map(fundGoodsAssign -> {
                    return ledgerAccountBasicInfoService.getById(fundGoodsAssign.getLedgerAccountBasicInfoId());
                }).sorted(Comparator.comparing(LedgerAccountBasicInfo::getGmtCreate).reversed()).collect(Collectors.toList());
                List<RefundsApplyAccountInfo> accountInfoList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(ledgerAccountBasicInfos)) {
                    LedgerAccountBasicInfo accountBasicInfo = ledgerAccountBasicInfos.get(0);
                    SupplierBankCardInfo supplierBankCardInfo = supplierBankCardInfoService
                            .lambdaQuery().eq(SupplierBankCardInfo::getLedgerAccountBasicInfoId, accountBasicInfo.getId())
                            .eq(SupplierBankCardInfo::getSupplierId, supplier.getId())
                            .one();
                    if (supplierBankCardInfo != null) {
                        RefundsApplyAccountInfo applyAccountInfo = new RefundsApplyAccountInfo();
                        applyAccountInfo.setCollectionAccount(supplierBankCardInfo.getAccountNumber());
                        applyAccountInfo.setCollectionAccountName(supplierBankCardInfo.getAccountName());
                        applyAccountInfo.setCollectionBankName(supplierBankCardInfo.getBankName());
                        accountInfoList.add(applyAccountInfo);
                    }
                }
                applyDetails.setAccountInfoList(accountInfoList);
            }


        }
        return applyDetails;
    }

    /**
     * @param ledgerDetailsVoSelected 选中的应退明细
     * @param plansSelecteds          选中的收放款计划
     * @return
     */
    private RefundsApplyDetails autoRefundPayment(List<LedgerDetailsVo> ledgerDetailsVoSelected,
                                                  List<PaymentCollectionPlanFactoring> plansSelecteds,
                                                  String businessNumber) {

        ProjectInformation projectInformation = projectInformationService
                .lambdaQuery().eq(ProjectInformation::getBusinessNumber, businessNumber).one();
        SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
        Enterprise supplier = enterpriseService.getById(supplierInfo.getcEnterpriseId());

        //付款总金额
        BigDecimal amountTotal = BigDecimal.ZERO;

        // 收支计划
        if (CollectionUtil.isNotEmpty(plansSelecteds)) {
            for (PaymentCollectionPlanFactoring plansSelected : plansSelecteds) {
                amountTotal = amountTotal.add(plansSelected.getAmount().abs());
            }
        }

        if (CollectionUtil.isNotEmpty(ledgerDetailsVoSelected)) {
            for (LedgerDetailsVo ledgerDetailsVo : ledgerDetailsVoSelected) {
                amountTotal = amountTotal.add(ledgerDetailsVo.getAmount());
            }
        }

        RefundsApplyDetails applyDetails = new RefundsApplyDetails();
        //收方账户信息
        List<LedgerFundGoodsAssign> fundGoodsAssignList = ledgerFundGoodsAssignService
                .lambdaQuery().eq(LedgerFundGoodsAssign::getBusinessNumber, businessNumber)
                .list();
        if (CollectionUtil.isNotEmpty(fundGoodsAssignList)) {
            List<LedgerAccountBasicInfo> ledgerAccountBasicInfos = fundGoodsAssignList.stream().map(fundGoodsAssign -> {
                return ledgerAccountBasicInfoService.getById(fundGoodsAssign.getLedgerAccountBasicInfoId());
            }).sorted(Comparator.comparing(LedgerAccountBasicInfo::getGmtCreate).reversed()).collect(Collectors.toList());
            List<RefundsApplyAccountInfo> accountInfoList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(ledgerAccountBasicInfos)) {
                LedgerAccountBasicInfo accountBasicInfo = ledgerAccountBasicInfos.get(0);
                SupplierBankCardInfo supplierBankCardInfo = supplierBankCardInfoService
                        .lambdaQuery().eq(SupplierBankCardInfo::getLedgerAccountBasicInfoId, accountBasicInfo.getId())
                        .eq(SupplierBankCardInfo::getSupplierId, supplier.getId())
                        .one();
                if (supplierBankCardInfo != null) {
                    RefundsApplyAccountInfo applyAccountInfo = new RefundsApplyAccountInfo();
                    applyAccountInfo.setCollectionAccount(supplierBankCardInfo.getAccountNumber());
                    applyAccountInfo.setCollectionAccountName(supplierBankCardInfo.getAccountName());
                    applyAccountInfo.setCollectionBankName(supplierBankCardInfo.getBankName());
                    accountInfoList.add(applyAccountInfo);
                }
            }
            applyDetails.setAccountInfoList(accountInfoList);
        }
        applyDetails.setPaymentMatterDic(dictionaryService
                .getByCode(OaFlowPaymentMatterTypeDic.ChildEnum.OA_REFUND_MATTER.getCode()));
        applyDetails.setPaymentMatter(OaFlowPaymentMatterTypeDic.ChildEnum.OA_REFUND_MATTER.getCode());

        Dictionary projectTypeDic = dictionaryService.getByCode(ProjectTypeDict.ChildEnum.FACTORING_BUSINESS.getCode());
        applyDetails.setProjectTypeDic(projectTypeDic);
        applyDetails.setProjectType(projectTypeDic.getCode());
        applyDetails.setCurrency("CNY");


        //付款总金额
        applyDetails.setPaymentAmountTotal(amountTotal);
        applyDetails.setAmountCapitalization(NumberChineseFormatterUtils.format(amountTotal.doubleValue(), false));

        return applyDetails;
    }

    /**
     * 计算应退金额
     *
     * @param paymentCollectionPlanFactorings
     * @param businessNumber
     * @return
     */
    private BigDecimal autoMustAmount(List<PaymentCollectionPlanFactoring> paymentCollectionPlanFactorings, String businessNumber,
                                      String contractNo, Integer quotaDisburseBatch) {

        BigDecimal mustReturn = BigDecimal.ZERO;

        //融资：履约保证金+质保金+实退金额+收款且金额类型负数 保证金（放款）：此处金额均取绝对值
        if (CollectionUtil.isNotEmpty(paymentCollectionPlanFactorings)) {
            for (PaymentCollectionPlanFactoring plan : paymentCollectionPlanFactorings) {
                if (plan.getAmount().compareTo(BigDecimal.ZERO) < 0
                        && ConstantConversionUtil.PAY_COLL_COLLECTION.equals(plan.getPaymentCollectionType())) {
                    mustReturn = mustReturn.add(plan.getAmount().abs());
                }

                //保证金（放款）
                if (IncomeExpenditureTypeDict.ChildEnum.MARGIN.getCode().equals(plan.getAmountType().getCode())
                        && ConstantConversionUtil.PAY_COLL_PAYMENT.equals(plan.getPaymentCollectionType())) {
                    mustReturn = mustReturn.add(plan.getAmount().abs());
                }
            }

        }

        //贸易：履约保证金+质保金+实退金额
        List<LedgerFundGoodsAssign> fundGoodsAssigns = ledgerFundGoodsAssignService
                .lambdaQuery().eq(LedgerFundGoodsAssign::getBusinessNumber, businessNumber)
                .eq(LedgerFundGoodsAssign::getContractNo, contractNo)
                .eq(LedgerFundGoodsAssign::getQuotaDisburseBatch, quotaDisburseBatch).list();
        if (CollectionUtil.isNotEmpty(fundGoodsAssigns)) {
            for (LedgerFundGoodsAssign fundGoodsAssign : fundGoodsAssigns) {
                mustReturn = mustReturn.add(fundGoodsAssign.getAccrualAmount().add(fundGoodsAssign.getDiscountAmount())
                        .add(fundGoodsAssign.getGuarantee()));
            }
        }
        return mustReturn;
    }

    /**
     * 填充支持选中标识
     *
     * @param allPlans
     */
    List<PaymentCollectionPlanFactoring> autoFlag(List<PaymentCollectionPlanFactoring> allPlans, Long refundId) {
        //支持选中的计划
        List<PaymentCollectionPlanFactoring> supportPlans = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(allPlans)) {
            //历史选中通过的计划
            List<Long> planIdsSelected = null;
            //历史选中退回的计划
            List<Long> planaIdsReturn = null;
            List<RefundManagementPayCollPlanFactoringRef> planFactoringRefs = refundManagementPayCollPlanFactoringRefService
                    .lambdaQuery().eq(RefundManagementPayCollPlanFactoringRef::getRefundManagementId, refundId)
                    .eq(RefundManagementPayCollPlanFactoringRef::getStatus, 1).list();
            List<RefundManagementPayCollPlanFactoringRef> planFactoringRefReturn = refundManagementPayCollPlanFactoringRefService
                    .lambdaQuery().eq(RefundManagementPayCollPlanFactoringRef::getRefundManagementId, refundId)
                    .eq(RefundManagementPayCollPlanFactoringRef::getStatus, 2).list();
            if (CollectionUtil.isNotEmpty(planFactoringRefs)) {
                planIdsSelected = planFactoringRefs.stream()
                        .map(RefundManagementPayCollPlanFactoringRef::getPayCollPlanFactoringId).collect(Collectors.toList());
            }
            if (CollectionUtil.isNotEmpty(planFactoringRefReturn)) {
                planaIdsReturn = planFactoringRefReturn.stream()
                        .map(RefundManagementPayCollPlanFactoringRef::getPayCollPlanFactoringId).collect(Collectors.toList());
            }
            for (PaymentCollectionPlanFactoring plan : allPlans) {

                //填充字段
                Boolean flag = false;
                plan.setAmountTypeName(plan.getAmountType().getName());
                plan.setPaymentCollectionTypeName(ConstantConversionUtil.paymentCollectionMap.get(plan.getPaymentCollectionType()));
                plan.setStatusStr(plan.getStatus().getName());

                if (ConstantConversionUtil.PAY_COLL_COLLECTION.equals(plan.getPaymentCollectionType())
                        && plan.getAmount().compareTo(BigDecimal.ZERO) < 0) {
                    if (CollectionUtil.isEmpty(planIdsSelected) || !planIdsSelected.contains(plan.getId())) {
                        //其一：收放款类型为收款 且 约定金额为 负数，历史没有选中
                        if (CollectionUtil.isNotEmpty(planaIdsReturn)) {
                            if (planaIdsReturn.contains(plan.getId())) {
                                //选中退回
                                flag = true;
                            }
                        }
                        plan.setSelected(flag);
                        supportPlans.add(plan);
                    }

                }

                if (ConstantConversionUtil.PAY_COLL_PAYMENT.equals(plan.getPaymentCollectionType())
                        && IncomeExpenditureTypeDict.ChildEnum.MARGIN.getCode().equals(plan.getAmountType().getCode())) {
                    if (CollectionUtil.isEmpty(planIdsSelected) || !planIdsSelected.contains(plan.getId())) {
                        //其二：收放款类型为放款，金额类型为 保证金，历史没有选中。
                        if (CollectionUtil.isNotEmpty(planaIdsReturn)) {
                            if (planaIdsReturn.contains(plan.getId())) {
                                //选中退回
                                flag = true;
                            }
                        }
                        plan.setSelected(flag);
                        supportPlans.add(plan);
                    }
                }
            }

        }
        return supportPlans;
    }

    private void startProcess(RefundManagement refundManagement) {

        ProjectInformation projectInformation = projectInformationService
                .lambdaQuery().eq(ProjectInformation::getBusinessNumber, refundManagement.getBusinessNumber()).one();
        SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
        Enterprise supplier = enterpriseService.getById(supplierInfo.getcEnterpriseId());
        ProjectCoreEnterprise projectCoreEnterprise = projectCoreEnterpriseService.getByProjectInfoId(projectInformation.getId());
        Enterprise enterprise = enterpriseService.getById(projectCoreEnterprise.getcEnterpriseId());

        //开启流程
        Map<String, Object> procVariables = new HashMap<>();
        procVariables.put(ConstantUtil.REFUND_APPLY + ConstantUtil.ASSIGNEE, ThreadLocalUtil.getUserId());
        //查询条件：业务编号 项目名称 主企业名称 核心企业名称
        String queryBusiness = projectInformation.getBusinessNumber() + FlowableUtil.splitChar + projectInformation.getProjectName()
                + FlowableUtil.splitChar + refundManagement.getContractNumber() + FlowableUtil.splitChar +
                supplier.getCorporateName() + FlowableUtil.splitChar + enterprise.getCorporateName();
        //开启流程
        ProcessInstance processInst = flowableService.startProcessInstance(refundManagement, procVariables,
                FlowableUtil.generateBusinessKey(refundManagement, ConstantUtil.REFUND_MANAGEMENT, queryBusiness),
                null, ConstantUtil.REFUND_MANAGEMENT);
        if (processInst == null) {
            throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
        }
    }

    private void handleProess(RefundManagement refundManagement, RefundManagementHis his) {

        //退款审核处理人 风控经理
        List<Long> riskControllerlists = userService.findUserIdByRole(ConstantUtil.RISK_CONTROL_MANAGER);
        String ids = riskControllerlists.stream().map(c -> c.toString()).collect(Collectors.joining(","));
        Map<String, Object> procVariables = new HashMap<>();
        procVariables.put(ConstantUtil.REFUND_APPROVAL + ConstantUtil._CANDIDATE, ids);

        Map<String, Object> msgVariables = new HashMap<>();
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "项目名称：" + refundManagement.getProjectName());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "项目名称为“" + refundManagement.getProjectName() + "”的项目已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.REFUND_MANAGEMENT) + "—退款审核，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        BusinessProcessingLog businessProcessingLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.REFUND_MANAGEMENT, refundManagement.getId());
        flowableService.completeMyTask(businessProcessingLog.getHistoricTaskId(), refundManagement, procVariables, null, his.getId(), msgVariables,
                ConstantUtil.REFUND_MANAGEMENT, riskControllerlists);
    }

    /**
     * 应退明细分组
     *
     * @param ledgerDetailsVos
     * @return
     */
    List<List<LedgerDetailsVo>> groupRefundDetails(List<LedgerDetailsVo> ledgerDetailsVos) {
        Map<String, List<LedgerDetailsVo>> listMap = ledgerDetailsVos.stream()
                .collect(Collectors.groupingBy(LedgerDetailsVo::getLedgerNumber));

        List<List<LedgerDetailsVo>> ledgerDetailsVoLists = new ArrayList<>();
        for (Map.Entry<String, List<LedgerDetailsVo>> map : listMap.entrySet()) {
            ledgerDetailsVoLists.add(map.getValue());
        }
        return ledgerDetailsVoLists;
    }

    @Override
    public List<PaymentCollectionPlanFactoring> findPlanBySop(String businessNumber, String contractNo, Integer quotaDisburseBatch,
                                                              RefundManagement refundManagement) {

        List<PaymentCollectionPlanFactoring> allPlans = new ArrayList<>();

        PaymentCollectionBasicVo paymentCollectionBasicVo = new PaymentCollectionBasicVo();
        paymentCollectionBasicVo.setBusinessNo(businessNumber);
        paymentCollectionBasicVo.setContractNo(contractNo);
        paymentCollectionBasicVo.setQuotaDisburseBatch(quotaDisburseBatch);

        //货款分配数据
        List<LedgerFundGoodsAssign> ledgerFundGoodsAssignList = ledgerFundGoodsAssignService.lambdaQuery()
                .eq(LedgerFundGoodsAssign::getBusinessNumber, businessNumber)
                .eq(LedgerFundGoodsAssign::getContractNo, contractNo)
                .eq(LedgerFundGoodsAssign::getQuotaDisburseBatch, quotaDisburseBatch).list();

        if (CollectionUtil.isNotEmpty(ledgerFundGoodsAssignList)) {
            LedgerFundGoodsAssign ledgerFundGoodsAssign = ledgerFundGoodsAssignList.get(0);
            FactoringBusinessLoanRecordAccountsReceivableVo factoringBusinessLoanRecordAccountsReceivableVo = new FactoringBusinessLoanRecordAccountsReceivableVo();
            factoringBusinessLoanRecordAccountsReceivableVo.setSopAccountsReceivableId(ledgerFundGoodsAssign.getSopAccountsReceivableId());
            factoringBusinessLoanRecordAccountsReceivableVo.setBillingFactoringBusinessLoanRecordId(ledgerFundGoodsAssign.getBillingFactoringBusinessLoanRecordId());
            paymentCollectionBasicVo.setFactoringBusinessLoanRecordAccountsReceivableVo(factoringBusinessLoanRecordAccountsReceivableVo);
        }

        JSONObject jsonObject = restTemplate.postForObject(getPaymentCollBasicOneStatusUrl, paymentCollectionBasicVo, JSONObject.class);
        if (jsonObject != null) {
            if (CodeUtil.FAIL.equals(jsonObject.get("code"))) {
                throw new BusinessException(CodeUtil.FAIL, jsonObject.get("msg").toString());
            }
            String data = JSONArray.toJSONString(jsonObject.get("data"));
            PaymentCollectionBasicVo paymentCollectionBasicVoSop = JSON.parseObject(data, PaymentCollectionBasicVo.class);
            allPlans = paymentCollectionBasicVoSop.getPaymentCollectionPlanFactorings();
            //账后状态
            if (refundManagement != null) {
                refundManagement.setCoreStatusStr(paymentCollectionBasicVoSop.getBusinessStatus());
            }
        }
        return allPlans;
    }

}
