package com.sunxung.factoring.service.financing.apply.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunxung.factoring.component.enums.FinancingCurrentStageEnum;
import com.sunxung.factoring.component.enums.FinancingStatusEnum;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.entity.creditresolution.CreditResolution;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.financing.apply.*;
import com.sunxung.factoring.entity.financing.apply.vo.FinancingApplyVo;
import com.sunxung.factoring.entity.financing.review.*;
import com.sunxung.factoring.entity.project.BusinessAssignee;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.supplier.SupplierInfo;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.sys.FileStorageDO;
import com.sunxung.factoring.entity.sys.User;
import com.sunxung.factoring.entity.sys.UserDO;
import com.sunxung.factoring.entity.tradingPlatform.Platform;
import com.sunxung.factoring.service.creditresolution.ICreditResolutionService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.financing.apply.*;
import com.sunxung.factoring.service.financing.review.*;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.project.IProjectInformationService;
import com.sunxung.factoring.service.supplier.ISupplierInfoService;
import com.sunxung.factoring.service.sys.CUserService;
import com.sunxung.factoring.service.sys.FileService;
import com.sunxung.factoring.service.sys.FileStorageService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description :
 * @Author : L.Jia
 * @Date: 2023-12-18 11:08
 */
@Service("financing_applyService")
public class FinancingApplyServiceImpl implements FinancingApplyService {

    @Autowired
    private IProjectInformationService projectInformationService;
    @Autowired
    private ICreditResolutionService creditResolutionService;
    @Resource(name = "SupplierInfoService")
    private ISupplierInfoService supplierInfoService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private BusinessAssigneeService assigneeService;
    @Autowired
    private UserService userService;
    @Autowired
    private ICFinancingBasicInfoService financingBasicInfoService;
    @Autowired
    private ICFinancingAccountsReceivableInfoService financingAccountsReceivableInfoService;
    @Autowired
    private ICFinancingApplicantInfoService financingApplicantInfoService;
    @Autowired
    private CFinancingHisInfoService financingHisInfoService;
    @Autowired
    private CFinancingHisAccountsReceivableInfoService financingHisAccountsReceivableInfoService;
    @Autowired
    private CFinancingHisGoodsInfoService financingHisGoodsInfoService;
    @Autowired
    private CFinancingHisApplicantInfoService financingHisApplicantInfoService;
    @Autowired
    private ReviewQuotaDisburseService reviewQuotaDisburseService;
    @Autowired
    private ReviewFinancingInfoService reviewFinancingInfoService;
    @Autowired
    private ReviewIncomeExpenditurePlanService reviewIncomeExpenditurePlanService;
    @Autowired
    private ReviewRltRepayService reviewRltRepayService;
    @Autowired
    private ReviewMasterContractService reviewMasterContractService;
    @Autowired
    private ReviewMasterContractDebtorService reviewMasterContractDebtorService;
    @Autowired
    private CUserService cUserService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private IReviewGuaranteeFileService reviewGuaranteeFileService;
    @Autowired
    private IReviewRltRepayEstateService reviewRltRepayEstateService;
    @Autowired
    private IReviewRltRepayLandService reviewRltRepayLandService;
    @Autowired
    private IReviewRltRepayVehicleService reviewRltRepayVehicleService;
    @Autowired
    private IReviewRltRepayEquityAssetsService reviewRltRepayEquityAssetsService;
    @Autowired
    private IReviewRltRepayOtherAssetsService reviewRltRepayOtherAssetsService;
    @Autowired
    private ReviewMortgageBasicInfoService reviewMortgageBasicInfoService;
    @Autowired
    private ReviewMortgageCollateralInfoService collateralInfoService;
    @Autowired
    private ReviewMortgagePledgeInfoService pledgeInfoService;
    @Autowired
    private ReviewTransferReceivableService reviewTransferReceivableService;
    @Autowired
    private ReviewBasicContractService reviewBasicContractService;
    @Autowired
    private ReviewBasicContractChangeContentService reviewBasicContractChangeContentService;
    @Autowired
    private ICAcceptanceGoodsInfoService acceptanceGoodsInfoService;
    @Autowired
    private ICAcceptanceBasicInfoService acceptanceBasicInfoService;
    @Autowired
    private FileService fileService;
    @Autowired
    private BusinessProcessingLogService processingLogService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startProcess(CFinancingBasicInfo financingBasicInfo) {

        //判断是第一次进入额度支用还是退回后重新进入
        ReviewQuotaDisburse exist = reviewQuotaDisburseService.getOne(new QueryWrapper<ReviewQuotaDisburse>()
                .eq("c_financing_basic_info_id", financingBasicInfo.getId())
                .eq("approval_conclusion", ConstantConversionUtil.APPROVAL_RESULT_BACK));

        String key = ConstantUtil.FINANCING_APPLY;
        User admin = userService.getByLoginName(ConstantConversionUtil.ADMINISTORIES);
        String taskId;
        if (exist == null) {
            //新增流程办理人
            addAssignee(financingBasicInfo);
            //开启流程
            Map<String, Object> procVariables = new HashMap<>(1);
            procVariables.put(ConstantUtil.FINANCING_APPLY_ASSIGNEE, admin.getId());
            ProcessInstance processInst = flowableService.startProcessInstance(financingBasicInfo, procVariables,
                    FlowableUtil.generateBusinessKey(financingBasicInfo, key, null), null, key);
            if (null == processInst) {
                throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
            }
            String processInstId = processInst.getId();
            taskId = flowableService.findRuntimeTaskByProcessInstId(processInstId).get(0).getId();
        } else {
            BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(key, financingBasicInfo.getId());
            taskId = processingLog.getHistoricTaskId();
        }

        //完成流程第一步融资申请，开启下一步支用审批
        Map<String, Object> procVariables1 = new HashMap<>(1);
        Long projectManagerId = assigneeService.getIdByBusiness(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY, ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
        procVariables1.put(ConstantUtil.REVIEW_QUOTA_DISBURSE_ASSIGNEE, projectManagerId);
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "业务编号：" + financingBasicInfo.getBusinessNumber());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为“" + financingBasicInfo.getBusinessNumber() + "”的融资申请已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.FINANCING_APPLY) + "——formBusiness”阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        ThreadLocalUtil.setUser(admin);
        flowableService.completeMyTask(taskId, financingBasicInfo, procVariables1, null,
                financingBasicInfo.getFinancingHisInfoId(), msgVariables, ConstantUtil.FINANCING_APPLY, Arrays.asList(projectManagerId));
    }

    @Override
    public FinancingApplyVo getView(Long id) {
        FinancingApplyVo financingApplyVo = new FinancingApplyVo();

        //基础信息
        CFinancingHisInfo financingHisInfo = financingHisInfoService.getById(id);
        if (financingHisInfo.getCoreEnterpriseId() != null) {
            Enterprise enterprise = enterpriseService.getById(financingHisInfo.getCoreEnterpriseId());
            financingHisInfo.setCoreEnterpriseName(enterprise.getCorporateName());
        }
        if (financingHisInfo.getMainEnterpriseId() != null) {
            Enterprise enterprise = enterpriseService.getById(financingHisInfo.getMainEnterpriseId());
            financingHisInfo.setMainEnterpriseName(enterprise.getCorporateName());
        }
        if (financingHisInfo.getPlatformId() != null) {
            Platform platform = platformService.getById(financingHisInfo.getPlatformId());
            financingHisInfo.setPlatformName(platform.getPlatformName());
        }
        if (financingHisInfo.getBusinessNumber() != null) {
            ProjectInformation projectInformation = projectInformationService.getOne(new QueryWrapper<ProjectInformation>()
                    .eq("business_number", financingHisInfo.getBusinessNumber()));
            if (projectInformation != null) {
                financingHisInfo.setSupplierId(projectInformation.getcSupplierInfoId());
            }
        }

        financingApplyVo.setFinancingBasicInfo(financingHisInfo);

        //底层货物
        List<CFinancingHisGoodsInfo> goodsInfoList = financingHisGoodsInfoService.list(new QueryWrapper<CFinancingHisGoodsInfo>()
                .eq("c_financing_his_info_id", id));
        if (CollectionUtil.isNotEmpty(goodsInfoList)) {
            goodsInfoList.stream().forEach(goods -> {
                if (goods.getAcceptanceGoodsInfoId() != null) {
                    CAcceptanceGoodsInfo cAcceptanceGoodsInfo = acceptanceGoodsInfoService.getById(goods.getAcceptanceGoodsInfoId());
                    if (cAcceptanceGoodsInfo != null) {
                        goods.setGoodsName(cAcceptanceGoodsInfo.getGoodsName());
                        goods.setGoodsFactory(cAcceptanceGoodsInfo.getGoodsFactory());
                        goods.setGoodsType(cAcceptanceGoodsInfo.getGoodsType());
                        goods.setGoodsUnit(cAcceptanceGoodsInfo.getGoodsUnit());
                        goods.setGoodsQuantity(cAcceptanceGoodsInfo.getGoodsQuantity());
                        goods.setAcceptanceDate(cAcceptanceGoodsInfo.getAcceptanceDate());
                    }
                }
                if (goods.getAcceptanceBasicInfoId() != null) {
                    CAcceptanceBasicInfo cAcceptanceBasicInfo = acceptanceBasicInfoService.getById(goods.getAcceptanceBasicInfoId());
                    if (cAcceptanceBasicInfo != null) {
                        goods.setExpectedSettlementDate(cAcceptanceBasicInfo.getExpectedSettlementDate());
                    }
                }
            });
        }
        financingApplyVo.setFinancingGoodsInfoList(goodsInfoList);

        //底层信息
        List<CFinancingHisAccountsReceivableInfo> accountsReceivableInfoList = financingHisAccountsReceivableInfoService.list(new QueryWrapper<CFinancingHisAccountsReceivableInfo>()
                .eq("c_financing_his_info_id", id));
        financingApplyVo.setFinancingAccountsReceivableInfoList(accountsReceivableInfoList);

        //联系人信息
        CFinancingHisApplicantInfo financingApplicantInfo = financingHisApplicantInfoService.getOne(new QueryWrapper<CFinancingHisApplicantInfo>()
                .eq("c_financing_his_info_id", id));
        financingApplyVo.setFinancingApplicantInfo(financingApplicantInfo);

        //网价附件
        List<FileStorageDO> fileStorageList = fileService.findByBusinessId(id, "financing_net_price_his_file");
        financingApplyVo.setFileStorageDOList(fileStorageList);
        return financingApplyVo;
    }

    /**
     * 新增融资申请流程办理人
     *
     * @param financingBasicInfo
     */
    private void addAssignee(CFinancingBasicInfo financingBasicInfo) {

        //C端供应商-发起申请
        BusinessAssignee supplier = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        //C端用户在B端统一存admin
        User admin = userService.getByLoginName(ConstantConversionUtil.ADMINISTORIES);
        supplier.setAssigneeId(admin.getId());
        supplier.setAssigneeType(ConstantUtil.ASSIGNEE_C_SUPPLIER);
        assigneeService.add(supplier);

        //B端业务经理-额度支用
        BusinessAssignee projectManager = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        projectManager.setAssigneeId(financingBasicInfo.getProjectManagerId());
        projectManager.setAssigneeType(ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
        assigneeService.add(projectManager);

        //B端风控经理-支用审批
        BusinessAssignee riskManager = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        riskManager.setAssigneeId(financingBasicInfo.getRiskManagerId());
        riskManager.setAssigneeType(ConstantUtil.ASSIGNEE_RISK_MANAGER);
        assigneeService.add(riskManager);

        //B端法务专员-合同制作
        List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
        if (legalSpecialists == null || legalSpecialists.size() == 0) {
            throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.LEGAL_SPECIALIST + "角色内无任何用户！");
        }

        BusinessAssignee legalPerson = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        legalPerson.setCandidateId(StringUtils.join(legalSpecialists, ","));
        legalPerson.setAssigneeType(ConstantUtil.ASSIGNEE_LEGAL_SPECIALIST);
        assigneeService.add(legalPerson);

        //B端业务负责人
        List<Long> projectOwners = userService.findUserIdByRole(ConstantUtil.PROJECT_MANAGER_OWNER);
        if (CollectionUtil.isEmpty(projectOwners)) {
            throw new ValidatorException(CodeUtil.FAIL, "业务负责人角色下无任何用户");
        }
        BusinessAssignee projectManagerOwner = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        projectManagerOwner.setCandidateId(StringUtils.join(projectOwners, ","));
        projectManagerOwner.setAssigneeType(ConstantUtil.ASSIGNEE_PROJECT_MANAGER_OWNER);
        assigneeService.add(projectManagerOwner);

        //B端风控负责人
        List<Long> riskOwners = userService.findUserIdByRole(ConstantUtil.RISK_CONTROL_OWNER);
        if (CollectionUtil.isEmpty(riskOwners)) {
            throw new ValidatorException(CodeUtil.FAIL, "风控负责人角色下无任何用户");
        }
        BusinessAssignee riskOwner = new BusinessAssignee(financingBasicInfo.getId(), ConstantUtil.FINANCING_APPLY);
        riskOwner.setCandidateId(StringUtils.join(riskOwners, ","));
        riskOwner.setAssigneeType(ConstantUtil.ASSIGNEE_RISK_OWNER);
        assigneeService.add(riskOwner);
    }

    @Override
    public ReviewQuotaDisburse apply(Long id) {

        CFinancingBasicInfo financingBasicInfo = financingBasicInfoService.getById(id);
        //计算应收账款净额之和
        List<CFinancingAccountsReceivableInfo> accountsReceivableInfoList = financingAccountsReceivableInfoService.list(new QueryWrapper<CFinancingAccountsReceivableInfo>()
                .eq("c_financing_basic_info_id", financingBasicInfo.getId()));
        BigDecimal netAccountsReceivableAmountTotal = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(accountsReceivableInfoList)) {
            netAccountsReceivableAmountTotal = accountsReceivableInfoList.stream().filter(accountsReceivableInfo -> accountsReceivableInfo.getNetAccountsReceivableAmount() != null)
                    .map(CFinancingAccountsReceivableInfo::getNetAccountsReceivableAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        ReviewQuotaDisburse reviewQuotaDisburse = reviewQuotaDisburseService.getOne(new QueryWrapper<ReviewQuotaDisburse>()
                .eq("c_financing_basic_info_id", financingBasicInfo.getId())
                .orderByDesc("id").last("LIMIT 1"));

        if (reviewQuotaDisburse == null) {
            reviewQuotaDisburse = new ReviewQuotaDisburse();
            initQuotaDisburse(financingBasicInfo, netAccountsReceivableAmountTotal, reviewQuotaDisburse);
        } else {
            if (reviewQuotaDisburse.getApprovalConclusion().equals(ConstantConversionUtil.APPROVAL_RESULT_BACK)) {
                initQuotaDisburse(financingBasicInfo, netAccountsReceivableAmountTotal, reviewQuotaDisburse);
            } else {
                //填充IRR
                if (reviewQuotaDisburse.getPlanIrr() != null) {
                    reviewQuotaDisburse.setPlanIrrStr(PercentageUtil.convertPercentage(reviewQuotaDisburse.getPlanIrr().doubleValue()));
                }
                //填充主合同信息
                autoMasterContractInfo(reviewQuotaDisburse);
                //填充融资信息
                autoReviewFinancingInfo(reviewQuotaDisburse);
                //填充收支计划信息
                autoIncomeExpenditurePlan(reviewQuotaDisburse);
                //新增相关还款责任人
                autoReviewRltRepay(reviewQuotaDisburse);
                //新增抵质押信息
                autoMortgageInfo(reviewQuotaDisburse);
                //新增应收账款转让信息
                dealReviewTransferReceivableToEditPage(reviewQuotaDisburse);
                //基础交易合同信息
                autoBasicContract(reviewQuotaDisburse, financingBasicInfo);
            }
        }

        return reviewQuotaDisburse;
    }

    private void initQuotaDisburse(CFinancingBasicInfo financingBasicInfo, BigDecimal netAccountsReceivableAmountTotal, ReviewQuotaDisburse reviewQuotaDisburse) {
        reviewQuotaDisburse.setFinancingBasicInfoId(financingBasicInfo.getId());
        //计算业务占用的授信金额
        BigDecimal businessOccupyAmount = getBusinessOccupyAmount(financingBasicInfo);
        //计算供应商占用的授信金额
        BigDecimal supplierOccupyAmount = getSupplierOccupyAmount(financingBasicInfo);
        //计算业务综合授信余额和供应商授信余额
        ProjectInformation projectInformation = projectInformationService.getOne(new QueryWrapper<ProjectInformation>()
                .eq("business_number", financingBasicInfo.getBusinessNumber()));
        if (projectInformation == null) {
            throw new BusinessException(CodeUtil.FAIL, "根据业务编号获取不到对应项目信息");
        }

        CreditResolution creditResolution = creditResolutionService.getByProjectInformationId(projectInformation.getId());
        reviewQuotaDisburse.setBusinessNumber(financingBasicInfo.getBusinessNumber());
        reviewQuotaDisburse.setBusinessCreditBalance(creditResolution.getProposedCreditLine().subtract(businessOccupyAmount));

        SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
        reviewQuotaDisburse.setSupplierCreditBalance(supplierInfo.getCreditLimit().multiply(new BigDecimal("10000")).subtract(supplierOccupyAmount));
        reviewQuotaDisburse.setAccountsReceivableNetAmountTotal(netAccountsReceivableAmountTotal);

        //融资信息
        ReviewFinancingInfo reviewFinancingInfo = new ReviewFinancingInfo();
        reviewFinancingInfo.setFinancingAmount(netAccountsReceivableAmountTotal);
        reviewQuotaDisburse.setReviewFinancingInfo(reviewFinancingInfo);

        //主合同信息
        ReviewMasterContract masterContract = new ReviewMasterContract();
        masterContract.setDoubleFactoringType(0);
        masterContract.setFactoringName("长安银科商业保理有限公司");
        masterContract.setFactoringLegalPerson("郑海明");
        masterContract.setFactoringSocialCreditCode("91610132MA6U08HU0L");
        masterContract.setFactoringAddress("西安经济技术开发区凤城十二路凯瑞B座A2402");
        masterContract.setFactoringAccountName("长安银科商业保理有限公司");
        masterContract.setFactoringAccount("15000033148651");
        masterContract.setFactoringAccountBank("平安银行西安经济技术开发区支行");
        masterContract.setOurAccountName("长安银科商业保理有限公司");
        masterContract.setOurAccount("15000033148651");
        masterContract.setOurAccountBank("平安银行西安经济技术开发区支行");
        //保理商联系人、保理商联系人电话、保理商联系人邮箱拉去业务经理的信息
        User projectManager = getProjectManager(financingBasicInfo);
        if (projectManager != null) {
            masterContract.setFactoringAgentName(projectManager.getName());
            masterContract.setFactoringAgentEmail(projectManager.getEmail());
            masterContract.setFactoringAgentPhone(projectManager.getMobile());
        }
        //保理申请人信息拉去供应商
        Enterprise mainEnterprise = enterpriseService.getById(financingBasicInfo.getMainEnterpriseId());
        masterContract.setApplicantCompanyId(mainEnterprise.getId());
        masterContract.setApplicantSocialCreditCode(mainEnterprise.getSocialCreditCode());
        masterContract.setApplicantCompanyName(mainEnterprise.getCorporateName());
        masterContract.setApplicantCompanyLegalPerson(mainEnterprise.getLegalRepresentative());
        masterContract.setApplicantCompanyAddress(mainEnterprise.getAddress());

        //保理申请人联系人拉去融资申请时的联系信息
        CFinancingApplicantInfo financingApplicantInfo = financingApplicantInfoService.getOne(new QueryWrapper<CFinancingApplicantInfo>()
                .eq("c_financing_basic_info_id", financingBasicInfo.getId()));
        if (financingApplicantInfo != null) {
            masterContract.setApplicantContact(financingApplicantInfo.getApplicantContact());
            masterContract.setApplicantContactNumber(financingApplicantInfo.getApplicantContactNumber());
            masterContract.setApplicantEmail(financingApplicantInfo.getApplicantContactEmail());
            masterContract.setApplicantDesignatedAccount(financingApplicantInfo.getApplicantDesignatedAccount());
            masterContract.setApplicantDesignatedAccountName(financingApplicantInfo.getApplicantDesignatedAccountName());
            masterContract.setApplicantDesignatedBank(financingApplicantInfo.getApplicantDesignatedBank());
        }

        //债务人信息
        ReviewMasterContractDebtor debtor = new ReviewMasterContractDebtor();
        //债务人公司名称、债务人公司法人、债务人公司注册地址拉取贸易平台
        Platform platform = platformService.getById(financingBasicInfo.getPlatformId());
        if (platform != null) {
            debtor.setCompanyName(platform.getPlatformName());
            //todo
            debtor.setLegalPerson("郑海明");
            debtor.setAddress(platform.getAddress());
        }
        //债务人联系人、债务人联系电话、债务人邮箱
        if (projectManager != null) {
            debtor.setContact(projectManager.getName());
            debtor.setEmail(projectManager.getEmail());
            debtor.setContactNumber(projectManager.getMobile());
        }
        masterContract.setDebtorList(Arrays.asList(debtor));
        reviewQuotaDisburse.setReviewMasterContract(masterContract);

        //应收账款转让拉取转让方-供应商 、受让方-长安银科商业保理有限公司
        ReviewTransferReceivable reviewTransferReceivable = new ReviewTransferReceivable();
        reviewTransferReceivable.setTransferor(mainEnterprise.getCorporateName());
        reviewTransferReceivable.setTransferee("长安银科商业保理有限公司");
        reviewQuotaDisburse.setReviewTransferReceivable(reviewTransferReceivable);

        //三方协议
        ReviewBasicContract reviewBasicContract = new ReviewBasicContract();
        reviewBasicContract.setDebtorCompanyId(platform.getId());
        reviewBasicContract.setDebtorCompanyName(platform.getPlatformName());
        reviewBasicContract.setDebtorSocialCreditCode(platform.getSocialCreditCode());
        ReviewBasicContractChangeContent contractChangeContent = new ReviewBasicContractChangeContent();
        contractChangeContent.setContractNo(financingBasicInfo.getPurchContractNumber());
        contractChangeContent.setContractName(financingBasicInfo.getPurchContractName());
        reviewBasicContract.setContractContentList(Arrays.asList(contractChangeContent));
        reviewQuotaDisburse.setReviewBasicContractList(Arrays.asList(reviewBasicContract));
    }

    /**
     * 填充主合同信息
     *
     * @param reviewQuotaDisburse
     */
    private void autoMasterContractInfo(ReviewQuotaDisburse reviewQuotaDisburse) {
        ReviewMasterContract reviewMasterContract = reviewMasterContractService.getOne(new QueryWrapper<ReviewMasterContract>().eq("review_quota_disburse_id", reviewQuotaDisburse.getId()));
        if (reviewMasterContract != null) {
            List<ReviewMasterContractDebtor> debtorList = reviewMasterContractDebtorService.list(new QueryWrapper<ReviewMasterContractDebtor>()
                    .eq("review_master_contract_id", reviewMasterContract.getId()));
            reviewMasterContract.setDebtorList(debtorList);
            reviewQuotaDisburse.setReviewMasterContract(reviewMasterContract);
        }
    }

    /**
     * 获取项目经理
     *
     * @param financingBasicInfo
     * @return
     */
    private User getProjectManager(CFinancingBasicInfo financingBasicInfo) {
        UserDO userDO = cUserService.get(financingBasicInfo.getSysUserId());
        if (userDO != null) {
            Long projectManagerId = userDO.getProjectManager();
            if (projectManagerId != null) {
                User projectManager = userService.get(projectManagerId);
                return projectManager;
            }
        }
        return null;
    }

    /**
     * 计算供应商占用的授信金额
     *
     * @param financingBasicInfo
     */
    private BigDecimal getSupplierOccupyAmount(CFinancingBasicInfo financingBasicInfo) {
        BigDecimal supplierOccupyAmount = BigDecimal.ZERO;
        List<CFinancingBasicInfo> list1 = financingBasicInfoService.list(new QueryWrapper<CFinancingBasicInfo>()
                .eq("supplier_id", financingBasicInfo.getMainEnterpriseId())
                .ne("current_stage", FinancingCurrentStageEnum.REVIEW_QUOTA_DISBURSE.getCode())
                .ne("financing_status", FinancingStatusEnum.FINANCING_PROCESSING.getCode()));
        if (CollectionUtil.isNotEmpty(list1)) {
            BigDecimal occupyAmount = list1.stream().filter(basicInfo -> basicInfo.getFinancingAmount() != null).map(CFinancingBasicInfo::getFinancingAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            supplierOccupyAmount = supplierOccupyAmount.add(occupyAmount);
        }
        List<CFinancingBasicInfo> list2 = financingBasicInfoService.list(new QueryWrapper<CFinancingBasicInfo>()
                .eq("supplier_id", financingBasicInfo.getMainEnterpriseId())
                .ne("current_stage", "")
                .ne("financing_status", FinancingStatusEnum.FINANCING_TERMINATED.getCode()));
        if (CollectionUtil.isNotEmpty(list2)) {
            BigDecimal occupyAmount = list2.stream().filter(basicInfo -> basicInfo.getFinancingAmount() != null).map(CFinancingBasicInfo::getFinancingAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            supplierOccupyAmount = supplierOccupyAmount.add(occupyAmount);
        }
        return supplierOccupyAmount;
    }

    /**
     * 计算业务占用的授信金额
     *
     * @param financingBasicInfo
     */
    private BigDecimal getBusinessOccupyAmount(CFinancingBasicInfo financingBasicInfo) {
        BigDecimal businessOccupyAmount = BigDecimal.ZERO;
        List<CFinancingBasicInfo> list1 = financingBasicInfoService.list(new QueryWrapper<CFinancingBasicInfo>()
                .eq("business_number", financingBasicInfo.getBusinessNumber())
                .ne("current_stage", FinancingCurrentStageEnum.REVIEW_QUOTA_DISBURSE.getCode())
                .ne("financing_status", FinancingStatusEnum.FINANCING_PROCESSING.getCode()));
        if (CollectionUtil.isNotEmpty(list1)) {
            BigDecimal occupyAmount = list1.stream().filter(basicInfo -> basicInfo.getFinancingAmount() != null).map(CFinancingBasicInfo::getFinancingAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            businessOccupyAmount = businessOccupyAmount.add(occupyAmount);
        }
        List<CFinancingBasicInfo> list2 = financingBasicInfoService.list(new QueryWrapper<CFinancingBasicInfo>()
                .eq("business_number", financingBasicInfo.getBusinessNumber())
                .ne("current_stage", "")
                .ne("financing_status", FinancingStatusEnum.FINANCING_TERMINATED.getCode()));
        if (CollectionUtil.isNotEmpty(list2)) {
            BigDecimal occupyAmount = list2.stream().filter(basicInfo -> basicInfo.getFinancingAmount() != null).map(CFinancingBasicInfo::getFinancingAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            businessOccupyAmount = businessOccupyAmount.add(occupyAmount);
        }
        return businessOccupyAmount;
    }

    /**
     * 填充融资信息
     */
    private void autoReviewFinancingInfo(ReviewQuotaDisburse reviewQuotaDisburse) {
        if (null != reviewQuotaDisburse && null != reviewQuotaDisburse.getId()) {
            ReviewFinancingInfo financingInfo = reviewFinancingInfoService.getOne(new QueryWrapper<ReviewFinancingInfo>().eq("review_quota_disburse_id", reviewQuotaDisburse.getId()));
            if (null != financingInfo) {
                autoPercentageForFinancingInfo(financingInfo);
                autoTransferNoticeMethodName(financingInfo);
                autoServiceScopeName(financingInfo);
                //  autoRefinacingManagement(financingInfo);
                reviewQuotaDisburse.setReviewFinancingInfo(financingInfo);
            }
        }
    }

    /**
     * 填充收支计划信息
     */
    private void autoIncomeExpenditurePlan(ReviewQuotaDisburse quotaDisburse) {
        if (null != quotaDisburse && null != quotaDisburse.getId()) {
            List<ReviewIncomeExpenditurePlan> list = reviewIncomeExpenditurePlanService.list(new QueryWrapper<ReviewIncomeExpenditurePlan>()
                    .eq("review_quota_disburse_id", quotaDisburse.getId()));
            if (null != list && list.size() > 0) {
                quotaDisburse.setIncomeExpenditurePlanList(list);
            }
        }
    }

    /**
     * 填充相关还款责任人信息
     *
     * @param quota
     */
    private void autoReviewRltRepay(ReviewQuotaDisburse quota) {
        if (null != quota && null != quota.getId()) {
            List<ReviewRltRepay> list = reviewRltRepayService.list(new QueryWrapper<ReviewRltRepay>()
                    .eq("review_quota_disburse_id", quota.getId()));
            if (null != list && list.size() > 0) {
                list.stream().forEach(reviewRltRepay -> {
                    //填充证件照
                    if (reviewRltRepay.getGuaranteeCardFrontFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewRltRepay.getGuaranteeCardFrontFileStorageId());
                        reviewRltRepay.setGuaranteeCardFrontFileStorage(fileStorage);
                    }
                    if (reviewRltRepay.getGuaranteeCardReverseFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewRltRepay.getGuaranteeCardReverseFileStorageId());
                        reviewRltRepay.setGuaranteeCardReverseFileStorage(fileStorage);
                    }
                    if (reviewRltRepay.getSpouseCardFrontFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewRltRepay.getSpouseCardFrontFileStorageId());
                        reviewRltRepay.setSpouseCardFrontFileStorage(fileStorage);
                    }
                    if (reviewRltRepay.getSpouseCardReverseFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewRltRepay.getSpouseCardReverseFileStorageId());
                        reviewRltRepay.setSpouseCardReverseFileStorage(fileStorage);
                    }
                    //填充附件
                    List<ReviewGuaranteeFile> reviewGuaranteeFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewRltRepay.getId())
                            .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.GUARANTEEINFO_FILE).list();
                    if (CollectionUtil.isNotEmpty(reviewGuaranteeFiles)) {
                        List<FileStorage> fileStorages = reviewGuaranteeFiles.stream().map(reviewGuaranteeSecondFile -> fileStorageService.get(reviewGuaranteeSecondFile.getFileId())).collect(Collectors.toList());
                        reviewRltRepay.setFileStorages(fileStorages);
                    }
                    //填充房产信息
                    List<ReviewRltRepayEstate> reviewRltRepayEstates = reviewRltRepayEstateService.lambdaQuery().eq(ReviewRltRepayEstate::getReviewRltRepayId, reviewRltRepay.getId()).list();
                    reviewRltRepay.setReviewRltRepayEstates(reviewRltRepayEstates);
                    //填充土地信息
                    List<ReviewRltRepayLand> reviewRltRepayLands = reviewRltRepayLandService.lambdaQuery().eq(ReviewRltRepayLand::getReviewRltRepayId, reviewRltRepay.getId()).list();
                    reviewRltRepay.setReviewRltRepayLands(reviewRltRepayLands);
                    //填充车辆信息
                    List<ReviewRltRepayVehicle> reviewRltRepayVehicles = reviewRltRepayVehicleService.lambdaQuery().eq(ReviewRltRepayVehicle::getReviewRltRepayId, reviewRltRepay.getId()).list();
                    reviewRltRepay.setReviewRltRepayVehicles(reviewRltRepayVehicles);
                    //填充股权资产信息
                    List<ReviewRltRepayEquityAssets> reviewRltRepayEquityAssets = reviewRltRepayEquityAssetsService.lambdaQuery().eq(ReviewRltRepayEquityAssets::getReviewRltRepayId, reviewRltRepay.getId()).list();
                    if (CollectionUtil.isNotEmpty(reviewRltRepayEquityAssets)) {
                        reviewRltRepayEquityAssets.stream().forEach(equityAssets -> equityAssets.setRatio(equityAssets.getRatio().multiply(new BigDecimal("100"))));
                    }
                    reviewRltRepay.setReviewRltRepayEquityAssets(reviewRltRepayEquityAssets);
                    //填充其他资产信息
                    List<ReviewRltRepayOtherAssets> reviewRltRepayOtherAssets = reviewRltRepayOtherAssetsService.lambdaQuery().eq(ReviewRltRepayOtherAssets::getReviewRltRepayId, reviewRltRepay.getId()).list();
                    reviewRltRepay.setReviewRltRepayOtherAssets(reviewRltRepayOtherAssets);
                });
                quota.setRltRepayList(list);
            }
        }
    }

    /**
     * 填充抵质押信息
     *
     * @param quota
     */
    private void autoMortgageInfo(ReviewQuotaDisburse quota) {
        if (null != quota && null != quota.getId()) {
            List<ReviewMortgageBasicInfo> list = reviewMortgageBasicInfoService.findByQuotaDisburseId(quota.getId());
            if (null != list && list.size() > 0) {
                list.forEach(reviewMortgageBasicInfo -> {
                    //附件
                    List<ReviewGuaranteeFile> reviewGuaranteeFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgageBasicInfo.getId())
                            .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.MORTGAGEINFORMATION_FILE).list();
                    if (CollectionUtil.isNotEmpty(reviewGuaranteeFiles)) {
                        List<FileStorage> fileStorages = reviewGuaranteeFiles.stream().map(r -> fileStorageService.get(r.getFileId())).collect(Collectors.toList());
                        reviewMortgageBasicInfo.setFileStorageList(fileStorages);
                    }
                    //证件文件
                    if (reviewMortgageBasicInfo.getCardFrontFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewMortgageBasicInfo.getCardFrontFileStorageId());
                        reviewMortgageBasicInfo.setCardFrontFileStorage(fileStorage);
                    }
                    if (reviewMortgageBasicInfo.getCardReverseFileStorageId() != null) {
                        FileStorage fileStorage = fileStorageService.get(reviewMortgageBasicInfo.getCardReverseFileStorageId());
                        reviewMortgageBasicInfo.setCardReverseFileStorage(fileStorage);
                    }
                    //抵押信息填充
                    List<ReviewMortgageCollateralInfo> reviewMortgageCollateralInfos = collateralInfoService.list(new QueryWrapper<ReviewMortgageCollateralInfo>()
                            .eq("review_mortgage_basic_id", reviewMortgageBasicInfo.getId()));
                    if (CollectionUtil.isNotEmpty(reviewMortgageCollateralInfos)) {
                        reviewMortgageCollateralInfos.forEach(reviewMortgageCollateralInfo -> {
                            //行政区划
                            if (reviewMortgageCollateralInfo.getCollDistrict() != null) {
                                reviewMortgageCollateralInfo.setCollDistrictStr(StringUtil.separatorCharacter(reviewMortgageCollateralInfo.getCollDistrict()));
                            }

                            //附件
                            List<ReviewGuaranteeFile> chattelMortgageFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgageCollateralInfo.getId())
                                    .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.CHATTELMORTGAGE_FILE).list();
                            if (CollectionUtil.isNotEmpty(chattelMortgageFiles)) {
                                List<FileStorage> chattelMortgageFileStorages = chattelMortgageFiles.stream().map(r -> fileStorageService.get(r.getFileId())).collect(Collectors.toList());
                                reviewMortgageCollateralInfo.setFileStorageList(chattelMortgageFileStorages);
                            }
                        });
                    }
                    reviewMortgageBasicInfo.setMortgageCollateralInfoList(reviewMortgageCollateralInfos);
                    //质押物信息填充
                    List<ReviewMortgagePledgeInfo> reviewMortgagePledgeInfos = pledgeInfoService.list(new QueryWrapper<ReviewMortgagePledgeInfo>()
                            .eq("review_mortgage_basic_id", reviewMortgageBasicInfo.getId()));
                    if (CollectionUtil.isNotEmpty(reviewMortgagePledgeInfos)) {
                        reviewMortgagePledgeInfos.forEach(reviewMortgagePledgeInfo -> {
                            reviewMortgagePledgeInfo.setEquityRatio(reviewMortgagePledgeInfo.getEquityRatio().multiply(new BigDecimal("100")));
                            //附件
                            List<ReviewGuaranteeFile> pledgeInformationFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgagePledgeInfo.getId())
                                    .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.PLEDGEINFORMATION_FILE).list();
                            if (CollectionUtil.isNotEmpty(pledgeInformationFiles)) {
                                List<FileStorage> pledgeInformationFilesStorages = pledgeInformationFiles.stream().map(r -> fileStorageService.get(r.getFileId())).collect(Collectors.toList());
                                reviewMortgagePledgeInfo.setFileStorageList(pledgeInformationFilesStorages);
                            }
                        });
                    }
                    reviewMortgageBasicInfo.setMortgagePledgeInfoList(reviewMortgagePledgeInfos);
                });
                quota.setMortgageBasicInfoList(list);
            }
        }
    }

    /**
     * 应收转让信息：更新受让方到额度支用处理页面
     */
    private void dealReviewTransferReceivableToEditPage(ReviewQuotaDisburse quota) {
        if (null != quota && null != quota.getId()) {
            ReviewTransferReceivable transferReceivable = reviewTransferReceivableService
                    .getOne(new QueryWrapper<ReviewTransferReceivable>().eq("review_quota_disburse_id", quota.getId()));
            if (null == transferReceivable) {
                transferReceivable = new ReviewTransferReceivable();
            }
            transferReceivable.setTransferee("长安银科商业保理有限公司");
            if (transferReceivable.getConfirmMethod() != null) {
                transferReceivable.setConfirmMethodList(StringUtil.separatorCharacter(transferReceivable.getConfirmMethod()));
            }
            quota.setReviewTransferReceivable(transferReceivable);
        }
    }

    /**
     * 填充基础交易合同信息
     */
    private void autoBasicContract(ReviewQuotaDisburse quota, CFinancingBasicInfo financingBasicInfo) {
        if (null != quota && null != quota.getId()) {
            List<ReviewBasicContract> list = reviewBasicContractService
                    .list(new QueryWrapper<ReviewBasicContract>().eq("review_quota_disburse_id", quota.getId()));
            if (null != list && list.size() > 0) {
                list.stream().forEach(reviewBasicContract -> {
                    List<ReviewBasicContractChangeContent> changeContentList = reviewBasicContractChangeContentService.list(new QueryWrapper<ReviewBasicContractChangeContent>()
                            .eq("review_basic_contract_id", reviewBasicContract.getId()));
                    reviewBasicContract.setContractContentList(changeContentList);
                });
                quota.setReviewBasicContractList(list);
            } else {
                //如果查不到、需要给默认值
                ReviewBasicContract reviewBasicContract = new ReviewBasicContract();
                Platform platform = platformService.getById(financingBasicInfo.getPlatformId());
                reviewBasicContract.setDebtorCompanyId(platform.getId());
                reviewBasicContract.setDebtorCompanyName(platform.getPlatformName());
                reviewBasicContract.setDebtorSocialCreditCode(platform.getSocialCreditCode());
                ReviewBasicContractChangeContent contractChangeContent = new ReviewBasicContractChangeContent();
                contractChangeContent.setContractNo(financingBasicInfo.getPurchContractNumber());
                contractChangeContent.setContractName(financingBasicInfo.getPurchContractName());
                reviewBasicContract.setContractContentList(Arrays.asList(contractChangeContent));
                quota.setReviewBasicContractList(Arrays.asList(reviewBasicContract));
            }
        }
    }

    /**
     * 填充融资信息的比例
     */
    private void autoPercentageForFinancingInfo(ReviewFinancingInfo financingInfo) {
        if (null != financingInfo) {
            // 融资利率(年化)
            financingInfo.setFinancingRate(financingInfo.getFinancingRate().multiply(new BigDecimal("100")));
            // 融资比例
            financingInfo.setFinancingRatio(financingInfo.getFinancingRatio().multiply(new BigDecimal("100")));
            // 对外综合报价
            financingInfo.setComprehensiveQuotation(financingInfo.getComprehensiveQuotation().multiply(new BigDecimal("100")));
            // 管理费率(年化)
            financingInfo.setManagementFeeRatio(financingInfo.getManagementFeeRatio().multiply(new BigDecimal("100")));
            // 保证金比例
            financingInfo.setMarginRatio(financingInfo.getMarginRatio().multiply(new BigDecimal("100")));
            // 逾期利率
            financingInfo.setOverdueInterestRate(financingInfo.getOverdueInterestRate().multiply(new BigDecimal("100")));
            // 坏账担保比例
            financingInfo.setBadDebtGuaranteeRate(financingInfo.getBadDebtGuaranteeRate().multiply(new BigDecimal("100")));

        }
    }

    /**
     * 填充融资信息：转让通知方式
     */
    private void autoTransferNoticeMethodName(ReviewFinancingInfo info) {
        if (null != info && StringUtil.isNotEmpty(info.getTransferNoticeMethod())) {
            List<String> transferNoticeMethodList = StringUtil.separatorCharacter(info.getTransferNoticeMethod());
            info.setTransferNoticeMethodList(transferNoticeMethodList);
        }
    }

    /**
     * 填充融资信息：服务范围
     */
    private void autoServiceScopeName(ReviewFinancingInfo info) {
        if (null != info && StringUtil.isNotEmpty(info.getServiceScope())) {
            List<String> serviceScopeList = StringUtil.separatorCharacter(info.getServiceScope());
            info.setServiceScopeList(serviceScopeList);
        }
    }
}
