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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.ConstantConversionUtil;
import com.sunxung.factoring.dict.impl.CashFlowOutTypeDict;
import com.sunxung.factoring.dict.impl.IncomeExpenditureTypeDict;
import com.sunxung.factoring.dict.impl.LedgerStatusDict;
import com.sunxung.factoring.dict.impl.PaymentCollectionPlanStatusDict;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.ResponseJson;
import com.sunxung.factoring.entity.cashflowmanage.CashFlowManageBasicInfo;
import com.sunxung.factoring.entity.cashflowmanage.sop.BankAccountInfo;
import com.sunxung.factoring.entity.cashflowmanage.sop.BillingNonbusinessManageFactoringentry;
import com.sunxung.factoring.entity.cashflowmanage.sop.BillingRecordBasic;
import com.sunxung.factoring.entity.customerinformation.Customer;
import com.sunxung.factoring.entity.customerinformation.SupplierBankCardInfo;
import com.sunxung.factoring.entity.ledger.*;
import com.sunxung.factoring.entity.ledger.vo.*;
import com.sunxung.factoring.entity.purchcontractmanagement.PurchContractBasicInfo;
import com.sunxung.factoring.entity.purchcontractmanagement.PurchContractManagement;
import com.sunxung.factoring.entity.settlement.SettlementBasicInfo;
import com.sunxung.factoring.entity.settlement.SettlementGoodsInfo;
import com.sunxung.factoring.entity.sys.Dictionary;
import com.sunxung.factoring.entity.underlying.UnderlyingBasicInfo;
import com.sunxung.factoring.entity.underlying.sop.PayCollPlanFactoringAmountAllocation;
import com.sunxung.factoring.entity.underlying.sop.PaymentCollectionPlanFactoring;
import com.sunxung.factoring.mapper.ledger.LedgerManagementMapper;
import com.sunxung.factoring.service.async.AsyncService;
import com.sunxung.factoring.service.businessmanagement.BusinessBasicInfoService;
import com.sunxung.factoring.service.cashflowmanage.CashFlowManageBasicInfoService;
import com.sunxung.factoring.service.customerinformation.CustomerService;
import com.sunxung.factoring.service.customerinformation.SupplierBankCardInfoService;
import com.sunxung.factoring.service.ledger.*;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractBasicInfoService;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractService;
import com.sunxung.factoring.service.settlement.SettlementBasicInfoService;
import com.sunxung.factoring.service.settlement.SettlementGoodsInfoService;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import com.sunxung.factoring.service.underlying.UnderlyingAccountsReceivableInfoService;
import com.sunxung.factoring.service.underlying.UnderlyingBasicInfoService;
import com.sunxung.factoring.service.underlying.UnderlyingGoodsInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 分账管理service实现类
 *
 * @author LiuJia
 * @date 2021.11.11
 */
@Service
@PropertySource("classpath:config.properties")
public class LedgerManagementServiceImpl implements LedgerManagementService {

    @Autowired
    private LedgerAccountBasicInfoService ledgerAccountBasicInfoService;

    @Autowired
    private LedgerFundGoodsAssignService ledgerFundGoodsAssignService;

    @Autowired
    private LedgerFundPossessionCostService ledgerFundPossessionCostService;

    @Autowired
    private LedgerSupplierBankRefService ledgerSupplierBankRefService;

    @Autowired
    private SupplierBankCardInfoService supplierBankCardInfoService;

    @Autowired
    private DictionaryService dictService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LedgerManagementMapper ledgerManagementMapper;

    @Autowired
    private BusinessBasicInfoService businessBasicInfoService;

    @Autowired
    private SettlementGoodsInfoService settlementGoodsInfoService;

    @Autowired
    private SettlementBasicInfoService settlementBasicInfoService;

    @Autowired
    private LedgerPlanFactoringAssignService planFactoringAssignService;

    @Autowired
    private CashFlowManageBasicInfoService cashFlowManageBasicInfoService;

    @Autowired
    private UnderlyingBasicInfoService underlyingBasicInfoService;

    @Autowired
    private UnderlyingGoodsInfoService underlyingGoodsInfoService;

    @Autowired
    private UnderlyingAccountsReceivableInfoService underlyingAccountsReceivableInfoService;

    @Autowired
    private PurchContractService purchContractService;

    @Autowired
    private PurchContractBasicInfoService purchContractBasicInfoService;

    @Autowired
    private PlatformService platformService;

    @Autowired
    private AsyncService asyncService;

    @Value("${config.ledger.findPayCollPlanFactoringList.url}")
    private String payCollPlanFactoringListUrl;

    @Value("${config.ledger.findUnCompletePayCollPlanFactoringList.url}")
    private String unCompletePayCollPlanFactoringList;

    @Value("${config.ledger.findAllPayCollPlanFactoringList.url}")
    private String allPayCollPlanFactoringList;

    @Value("${config.ledger.findPrepaymentInterestCal.url}")
    private String findPrepaymentInterestCalUrl;

    @Value("${config.ledger.findGoodsAssignInfoByReceivableId.url}")
    private String findGoodsAssignInfoUrl;

    @Value("${config.planInfo.add.url}")
    private String planInfoAddUrl;

    @Value("${config.billingRecordBasic.add.url}")
    private String billingRecordBasicAddUrl;

    @Value("${config.ledger.findPlanFactoringId.url}")
    private String findPlanFactoringIdUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(LedgerAccountInfoVo ledgerAccountInfoVo) {
        if (ledgerAccountInfoVo == null || ledgerAccountInfoVo.getLedgerAccountBasicInfo() == null) {
            throw new ValidatorException(CodeUtil.FAIL, "分账信息不能为空");
        }

        Boolean submit = ledgerAccountInfoVo.getSubmit();
        if (submit == null) {
            throw new ValidatorException(CodeUtil.FAIL, "暂存或提交标识不能为空");
        }

        //数据合法性校验
        LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountInfoVo.getLedgerAccountBasicInfo();
        if (submit) {
            validatorData(ledgerAccountInfoVo);
            //修改分账管理状态为已完成
            ledgerAccountBasicInfo.setLedgerStatus(LedgerStatusDict.ChildEnum.COMPLETE.getCode());
        }
        ledgerAccountBasicInfoService.updateById(ledgerAccountBasicInfo);

        //保存货款分配信息(先删后增，因为可能暂存过)
        List<LedgerFundGoodsAssign> ledgerFundGoodsAssignList = ledgerFundGoodsAssignService.findByBasicId(ledgerAccountBasicInfo.getId());
        if (CollectionUtil.isNotEmpty(ledgerFundGoodsAssignList)) {
            ledgerFundGoodsAssignService.remove(new QueryWrapper<LedgerFundGoodsAssign>().eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        }
        List<LedgerPlanFactoringAssign> planFactoringAssignList = planFactoringAssignService.findByBasicInfoId(ledgerAccountBasicInfo.getId());
        if (CollectionUtil.isNotEmpty(planFactoringAssignList)) {
            planFactoringAssignService.remove(new QueryWrapper<LedgerPlanFactoringAssign>().eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        }

        List<LedgerFundGoodsAssign> goodsAssignList = ledgerAccountInfoVo.getGoodsAssignList();
        if (goodsAssignList != null && goodsAssignList.size() > 0) {
            for (LedgerFundGoodsAssign ledgerFundGoodsAssign : goodsAssignList) {
                ledgerFundGoodsAssign.setLedgerAccountBasicInfoId(ledgerAccountBasicInfo.getId());
                ledgerFundGoodsAssign.setGoodsAssignId(ledgerFundGoodsAssign.getId());
                ledgerFundGoodsAssign.setId(null);
                ledgerFundGoodsAssign.setSubmit(submit);
                ledgerFundGoodsAssignService.save(ledgerFundGoodsAssign);

                if (StringUtils.isNotBlank(ledgerFundGoodsAssign.getPlanFactoringAssignListStr())) {
                    String planFactoringAssignListStr = ledgerFundGoodsAssign.getPlanFactoringAssignListStr();
                    JSONArray jsonArray = JSONUtil.parseArray(planFactoringAssignListStr);
                    List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList = JSONUtil.toList(jsonArray, LedgerPlanFactoringAssign.class);
                    if (ledgerPlanFactoringAssignList != null && ledgerPlanFactoringAssignList.size() > 0) {
                        for (LedgerPlanFactoringAssign planFactoringAssign : ledgerPlanFactoringAssignList) {
                            planFactoringAssign.setLedgerAccountBasicInfoId(ledgerAccountBasicInfo.getId());
                            planFactoringAssign.setLedgerFundGoodsAssignId(ledgerFundGoodsAssign.getId());
                            planFactoringAssignService.save(planFactoringAssign);
                        }
                    }
                }
            }
        }

        //保存资金占用费(先删后增，因为可能暂存过)
        List<LedgerFundPossessionCost> ledgerFundPossessionCostList = ledgerFundPossessionCostService.findByBasicId(ledgerAccountBasicInfo.getId());
        if (CollectionUtil.isNotEmpty(ledgerFundPossessionCostList)) {
            ledgerFundPossessionCostService.remove(new QueryWrapper<LedgerFundPossessionCost>().eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        }

        List<LedgerFundPossessionCost> possessionCostList = ledgerAccountInfoVo.getLedgerFundPossessionCostList();
        if (possessionCostList != null && possessionCostList.size() > 0) {
            for (LedgerFundPossessionCost ledgerFundPossessionCost : possessionCostList) {
                ledgerFundPossessionCost.setLedgerAccountBasicInfoId(ledgerAccountBasicInfo.getId());
                ledgerFundPossessionCostService.save(ledgerFundPossessionCost);
            }
        }

        //保存关联收款账号(先删后增，因为可能暂存过)
        List<LedgerSupplierBankRef> ledgerSupplierBankRefList = ledgerSupplierBankRefService.list(new QueryWrapper<LedgerSupplierBankRef>().eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        if (CollectionUtil.isNotEmpty(ledgerSupplierBankRefList)) {
            ledgerSupplierBankRefService.remove(new QueryWrapper<LedgerSupplierBankRef>().eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        }

        List<LedgerSupplierBankRef> supplierBankRefList = ledgerAccountInfoVo.getLedgerSupplierBankRefList();
        if (supplierBankRefList != null && supplierBankRefList.size() > 0) {
            for (LedgerSupplierBankRef ledgerSupplierBankRef : supplierBankRefList) {
                ledgerSupplierBankRef.setLedgerAccountBasicInfoId(ledgerAccountBasicInfo.getId());
                ledgerSupplierBankRefService.save(ledgerSupplierBankRef);
            }
        }

        //完成后添加现金流数据
        //修改现金流入账信息状态为已分配
        if (submit) {
            CashFlowManageBasicInfo cashFlowManageBasicInfo = cashFlowManageBasicInfoService.getById(ledgerAccountBasicInfo.getCashFlowManageBasicInfoId());
            cashFlowManageBasicInfo.setCashStatus(2);
            cashFlowManageBasicInfoService.updateById(cashFlowManageBasicInfo);

            //调用sop变更收放款计划接口
            planFactoringAssignList = planFactoringAssignService.findByBasicInfoId(ledgerAccountBasicInfo.getId());
            if (CollectionUtil.isNotEmpty(planFactoringAssignList)) {
                ResponseEntity<String> responseEntity = restTemplate.postForEntity(planInfoAddUrl, planFactoringAssignList, String.class);
                ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
                if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || !responseJson.isSuccess()) {
                    throw new BusinessException(CodeUtil.FAIL, "分账失败--变更sop收放款计划失败：" + responseJson.getMsg());
                }
            }

            //添加现金流出账数据
            //融资本息、折扣金额
            List<LedgerFundGoodsAssign> fundGoodsAssignList = ledgerFundGoodsAssignService.findByBasicId(ledgerAccountBasicInfo.getId());
            if (fundGoodsAssignList != null && fundGoodsAssignList.size() > 0) {
                Map<Long, List<LedgerFundGoodsAssign>> listMap = fundGoodsAssignList.stream().collect(Collectors.groupingBy(LedgerFundGoodsAssign::getSupplierId));
                for (Long supplierId : listMap.keySet()) {
                    List<LedgerFundGoodsAssign> list = listMap.get(supplierId);
                    //融资本金
                    BigDecimal financingPrincipal = list.stream().map(LedgerFundGoodsAssign::getFinancingPrincipal).reduce(BigDecimal.ZERO, BigDecimal::add);
//                    Dictionary principalDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FACTORING_PRINCIPAL.getCode());
//                    if (financingPrincipal.compareTo(BigDecimal.ZERO) == 1) {
//                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, principalDict.getId(), supplierId, financingPrincipal, list);
//                    }
                    //融资逾期利息
                    BigDecimal financingOverdueInterest = list.stream().map(LedgerFundGoodsAssign::getFinancingOverdueInterest).reduce(BigDecimal.ZERO, BigDecimal::add);
//                    Dictionary overDueDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_OVERDUE_INTEREST.getCode());
//                    if (financingOverdueInterest.compareTo(BigDecimal.ZERO) == 1) {
//                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, overDueDict.getId(), supplierId, financingOverdueInterest, list);
//                    }

                    //融资管理费
                    BigDecimal financingManagementFee = list.stream().map(LedgerFundGoodsAssign::getFinancingManagementFee).reduce(BigDecimal.ZERO, BigDecimal::add);
//                    Dictionary managementFeeDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_MANAGEMENT_FEE.getCode());
//                    if (financingManagementFee.compareTo(BigDecimal.ZERO) == 1) {
//                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, managementFeeDict.getId(), supplierId, financingManagementFee, list);
//                    }

                    //融资利息
                    BigDecimal financingInterest = list.stream().map(LedgerFundGoodsAssign::getFinancingInterest).reduce(BigDecimal.ZERO, BigDecimal::add);
//                    Dictionary interestDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FACTORING_INTEREST.getCode());
//                    if (financingInterest.compareTo(BigDecimal.ZERO) == 1) {
//                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, interestDict.getId(), supplierId, financingInterest, list);
//                    }
                    //本金、利息、管理费、逾期利息合成保理融资款项
                    BigDecimal financingAmount = financingPrincipal.add(financingOverdueInterest).add(financingManagementFee).add(financingInterest);
                    Dictionary financingAmountDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_AMOUNT.getCode());
                    if (financingAmount.compareTo(BigDecimal.ZERO) == 1) {
                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, financingAmountDict.getCode(), supplierId, financingAmount, list);
                    }

                    //实退金额
                    BigDecimal discountAmount = list.stream().map(LedgerFundGoodsAssign::getDiscountAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                    Dictionary discountDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.DISCOUNT.getCode());
                    if (discountAmount.compareTo(BigDecimal.ZERO) == 1) {
                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, discountDict.getCode(), supplierId, discountAmount, null);
                    }
                    // 平台利润
                    BigDecimal platformProfit = list.stream().map(LedgerFundGoodsAssign::getPlatformProfit).reduce(BigDecimal.ZERO, BigDecimal::add);
                    Dictionary profitDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.PROFIT.getCode());
                    if (platformProfit.compareTo(BigDecimal.ZERO) == 1) {
                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, profitDict.getCode(), supplierId, platformProfit, null);
                    }
                }
                //同步sop发送通知消息
                asyncService.sendMsg(fundGoodsAssignList);
            }
            //资金占用费
            List<LedgerFundPossessionCost> fundPossessionCostList = ledgerFundPossessionCostService.findByBasicId(ledgerAccountBasicInfo.getId());
            if (fundPossessionCostList != null && fundPossessionCostList.size() > 0) {
                Map<Long, List<LedgerFundPossessionCost>> listMap = fundPossessionCostList.stream().collect(Collectors.groupingBy(LedgerFundPossessionCost::getSupplierId));
                for (Long supplierId : listMap.keySet()) {
                    List<LedgerFundPossessionCost> list = listMap.get(supplierId);
                    BigDecimal fundPossessionCost = list.stream().map(LedgerFundPossessionCost::getFundPossessionCost).reduce(BigDecimal.ZERO, BigDecimal::add);
                    Dictionary costDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FUNDS_USED_COST.getCode());
                    if (fundPossessionCost.compareTo(BigDecimal.ZERO) == 1) {
                        addCashFlowManageBasicInfo(ledgerAccountBasicInfo, costDict.getCode(), supplierId, fundPossessionCost, null);
                    }
                }
            }
        }
    }

    /**
     * 生成现金流出账数据
     *
     * @param ledgerAccountBasicInfo
     * @param cashTypeCode
     * @param supplierId
     * @param amount
     */
    private void addCashFlowManageBasicInfo(LedgerAccountBasicInfo ledgerAccountBasicInfo, String cashTypeCode, Long supplierId,
                                            BigDecimal amount, List<LedgerFundGoodsAssign> goodsAssignList) {
        CashFlowManageBasicInfo cashFlowManageBasicInfo = new CashFlowManageBasicInfo();
        cashFlowManageBasicInfo.setSupplierId(supplierId);

        //根据业务编号和供应商Id获取对应的采购合同编号
        //todo
        PurchContractManagement purchContractManagement = purchContractService.getOne(new QueryWrapper<PurchContractManagement>()
                //.eq("business_number", ledgerAccountBasicInfo.getBusinessNumber())
                .eq("supplier_id", supplierId));
        if (purchContractManagement == null) {
            throw new BusinessException(CodeUtil.FAIL, "根据业务编号和供应商Id获取不到对应采购合同信息");
        }
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.lambdaQuery().eq(PurchContractBasicInfo::getPurchContractManagementId, purchContractManagement.getId()).one();
        if (purchContractBasicInfo == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应采购合同信息");
        }

        cashFlowManageBasicInfo.setContractNumber(purchContractBasicInfo.getContractNumber());
        //出账默认为2
        cashFlowManageBasicInfo.setEntryOutType("2");
        //类型为保理融资本金、保理融资利息、保理融资管理费、保理融资逾期利息时添加贸易平台Id,为其它类型时、添加供应商Id
//        Dictionary principalDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FACTORING_PRINCIPAL.getCode());
//        if (principalDict == null || principalDict.getId() == null) {
//            throw new BusinessException(CodeUtil.FAIL, "款项类型-保理融资本金字典项不能为空!");
//        }
//        Dictionary interestDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FACTORING_INTEREST.getCode());
//        if (interestDict == null || interestDict.getId() == null) {
//            throw new BusinessException(CodeUtil.FAIL, "款项类型-保理融资利息字典项不能为空!");
//        }
//        Dictionary managementDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_MANAGEMENT_FEE.getCode());
//        if (managementDict == null || managementDict.getId() == null) {
//            throw new BusinessException(CodeUtil.FAIL, "款项类型-保理融资管理费字典项不能为空!");
//        }
//        Dictionary overdueInterestDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_OVERDUE_INTEREST.getCode());
//        if (overdueInterestDict == null || overdueInterestDict.getId() == null) {
//            throw new BusinessException(CodeUtil.FAIL, "款项类型-保理融资逾期利息字典项不能为空!");
//        }
//
        Dictionary profitDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.PROFIT.getCode());
        if (profitDict == null || profitDict.getId() == null) {
            throw new BusinessException(CodeUtil.FAIL, "款项类型-平台利润字典项不能为空!");
        }

        Dictionary financingAmountDict = dictService.getByCode(CashFlowOutTypeDict.ChildEnum.FINANCING_AMOUNT.getCode());
        if (financingAmountDict == null || financingAmountDict.getId() == null) {
            throw new BusinessException(CodeUtil.FAIL, "款项类型-保理融资款项不能为空!");
        }

//        if (cashTypeId.equals(financingAmountDict.getId())) {
//            //获取贸易平台ID
//            BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(ledgerAccountBasicInfo.getBusinessNumber());
//            if (businessBasicInfo != null && businessBasicInfo.getPlatform() != null && businessBasicInfo.getPlatform().getId() != null) {
//                Platform platform = platformService.getById(businessBasicInfo.getPlatform().getId());
//                if (platform != null) {
//                    cashFlowManageBasicInfo.setTradingPlatformId(platform.getId());
//                }
//            }
//        }
        else {
            cashFlowManageBasicInfo.setSupplierId(supplierId);
        }
        cashFlowManageBasicInfo.setEnterpriseCustomerInfoId(ledgerAccountBasicInfo.getEnterpriseCustomerInfoId());
        cashFlowManageBasicInfo.setCashType(cashTypeCode);
//        cashFlowManageBasicInfo.setCurrency(ledgerAccountBasicInfo.getCurrency());
        cashFlowManageBasicInfo.setAmount(amount);
        //状态为待处理
        if (profitDict.getCode().equals(cashTypeCode)) {
            cashFlowManageBasicInfo.setCashStatus(4);
        } else {
            cashFlowManageBasicInfo.setCashStatus(3);
        }

        cashFlowManageBasicInfo.setCashDate(new Date());
        cashFlowManageBasicInfo.setLedgerAccountBasicInfoId(ledgerAccountBasicInfo.getId());
        cashFlowManageBasicInfoService.save(cashFlowManageBasicInfo);

        if (cashTypeCode.equals(financingAmountDict.getCode())) {
            //类型为保理融资款项时,同步sop现金流保理入账信息
            if (goodsAssignList != null && goodsAssignList.size() > 0) {
                List<LedgerPlanFactoringAssign> planFactoringAssignList = new ArrayList<>();
                for (LedgerFundGoodsAssign ledgerFundGoodsAssign : goodsAssignList) {
                    List<LedgerPlanFactoringAssign> planFactoringAssigns = planFactoringAssignService.findByFundGoodsAssignId(ledgerFundGoodsAssign.getId());
                    planFactoringAssignList.addAll(planFactoringAssigns);
                }

                if (planFactoringAssignList != null && planFactoringAssignList.size() > 0) {
//                    if (cashTypeId.equals(principalDict.getId())) {
//                        //本金回款
//                        planFactoringAssignList = planFactoringAssignList.stream().filter(p -> p.getPrincipal() != null && p.getPrincipal().equals(1))
//                                .filter(p -> p.getActualDate() != null && DateUtil.compare(p.getActualDate(), ledgerAccountBasicInfo.getLedgerDate()) == 0)
//                                .filter(p -> p.getActualAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                    } else if (cashTypeId.equals(interestDict.getId())) {
//                        //利息回款
//                        planFactoringAssignList = planFactoringAssignList.stream().filter(p -> p.getPrincipal() != null && p.getPrincipal().equals(0))
//                                .filter(p -> IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode().equals(p.getAmountType()))
//                                .filter(p -> p.getActualDate() != null && DateUtil.compare(p.getActualDate(), ledgerAccountBasicInfo.getLedgerDate()) == 0)
//                                .filter(p -> p.getActualAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                    } else if (cashTypeId.equals(managementDict.getId())) {
//                        //管理费回款
//                        planFactoringAssignList = planFactoringAssignList.stream().filter(p -> p.getPrincipal() != null && p.getPrincipal().equals(0))
//                                .filter(p -> IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode().equals(p.getAmountType()))
//                                .filter(p -> p.getActualDate() != null && DateUtil.compare(p.getActualDate(), ledgerAccountBasicInfo.getLedgerDate()) == 0)
//                                .filter(p -> p.getActualAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                    } else if (cashTypeId.equals(overdueInterestDict.getId())) {
//                        //逾期利息回款
//                        planFactoringAssignList = planFactoringAssignList.stream().filter(p -> p.getPrincipal() != null && p.getPrincipal().equals(0))
//                                .filter(p -> IncomeExpenditureTypeDict.ChildEnum.OVERDUE_INTEREST.getCode().equals(p.getAmountType()))
//                                .filter(p -> p.getActualDate() != null && DateUtil.compare(p.getActualDate(), ledgerAccountBasicInfo.getLedgerDate()) == 0)
//                                .filter(p -> p.getActualAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                    }
                    if (cashTypeCode.equals(financingAmountDict.getCode())) {
                        planFactoringAssignList = planFactoringAssignList.stream().filter(p -> p.getActualDate() != null && DateUtil.compare(p.getActualDate(), ledgerAccountBasicInfo.getLedgerDate()) == 0)
                                .filter(p -> p.getActualAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
                    }
                    //向sop同步现金流入账数据
                    BillingNonbusinessManageFactoringentry nonbusinessManageFactoringentry = addCashFlowOutInfoToSop(ledgerAccountBasicInfo, planFactoringAssignList, supplierId);
                    if (nonbusinessManageFactoringentry != null) {
                        cashFlowManageBasicInfo.setBillingFactoringEntryId(nonbusinessManageFactoringentry.getId());
                        cashFlowManageBasicInfoService.updateById(cashFlowManageBasicInfo);
                    }
                }
            }
        }
    }


    /**
     * 向sop同步现金流入账数据
     *
     * @param ledgerAccountBasicInfo  现金流管理基础信息
     * @param planFactoringAssignList 关联的出账信息
     */
    private BillingNonbusinessManageFactoringentry addCashFlowOutInfoToSop(LedgerAccountBasicInfo ledgerAccountBasicInfo, List<LedgerPlanFactoringAssign> planFactoringAssignList, Long supplierId) {
        //组装数据
        BillingRecordBasic billingRecordBasic = new BillingRecordBasic();
        BillingNonbusinessManageFactoringentry nobusinessManage = new BillingNonbusinessManageFactoringentry();

//        if (ledgerAccountBasicInfo != null) {
//            BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(ledgerAccountBasicInfo.getBusinessNumber());
//            if (businessBasicInfo != null) {
//                Platform platform = platformService.getById(businessBasicInfo.getTradingPlatformId());
//                if (platform != null) {
//                    nobusinessManage.setFirstLevelProject(platform.getPlatformName());
//                    nobusinessManage.setPlatformSocialCreditCode(platform.getSocialCreditCode());
//                }
//            }
//
//            if (supplierId != null) {
//                Customer customer = customerService.getById(supplierId);
//                if (customer != null) {
//                    nobusinessManage.setSupplierSocialCreditCode(customer.getSocialCreditCode());
//                }
//            }
//
//            BigDecimal actualAmountTotal = planFactoringAssignList.stream().filter(p -> p.getActualAmount() != null)
//                    .map(LedgerPlanFactoringAssign::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//            nobusinessManage.setAmountMoney(actualAmountTotal);
//
//            Dictionary currencyDict = dictService.get(ledgerAccountBasicInfo.getCurrencyDict().getId());
//            if (currencyDict == null) {
//                throw new BusinessException(CodeUtil.FAIL, "币种字典项不能为空!");
//            }
//            nobusinessManage.setCurrency(currencyDict);
//        }

        nobusinessManage.setBillDate(ledgerAccountBasicInfo.getLedgerDate());
        BankAccountInfo bankAccountInfo = new BankAccountInfo();
        //贸理通临时同步数据账号
        bankAccountInfo.setBankCardNo("888888");
        nobusinessManage.setBankAccountInfo(bankAccountInfo);

        billingRecordBasic.setNobusinessManage(nobusinessManage);


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

        for (LedgerPlanFactoringAssign planFactoringAssign : planFactoringAssignList) {
            PaymentCollectionPlanFactoring planFactoring = new PaymentCollectionPlanFactoring();
            if (planFactoringAssign.getPlanFactoringId() == null) {
                ResponseEntity<String> responseEntity = restTemplate.getForEntity(findPlanFactoringIdUrl + "?ledgerPlanFactoringAssignId="
                        + planFactoringAssign.getId(), String.class);
                ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
                if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || !responseJson.isSuccess()) {
                    throw new BusinessException(CodeUtil.FAIL, "根据分账分配Id获取不到对应的收放款计划：" + responseJson.getMsg().toString());
                }
                PaymentCollectionPlanFactoring factoring = JSONUtil.toBean((JSONObject) responseJson.getData(), PaymentCollectionPlanFactoring.class);
                planFactoring.setId(factoring.getId());
            } else {
                planFactoring.setId(planFactoringAssign.getPlanFactoringId());
            }
            List<PayCollPlanFactoringAmountAllocation> amountAllocationList = new ArrayList<>();
            PayCollPlanFactoringAmountAllocation amountAllocation = new PayCollPlanFactoringAmountAllocation();
            amountAllocation.setActualAmount(planFactoringAssign.getActualAmount());
            amountAllocationList.add(amountAllocation);
            planFactoring.setAmountAllocationList(amountAllocationList);
            planFactoringList.add(planFactoring);
        }
//        billingRecordBasic.setPlanFactoringList(planFactoringList);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(billingRecordBasicAddUrl, billingRecordBasic, String.class);
        ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
        if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || !responseJson.isSuccess()) {
            throw new BusinessException(CodeUtil.FAIL, "数据同步到sop失败：" + responseJson.getMsg().toString());
        }
        return JSONUtil.toBean((JSONObject) responseJson.getData(), BillingNonbusinessManageFactoringentry.class);
    }


    /**
     * 分账数据提交校验
     *
     * @param ledgerAccountInfoVo
     */
    private void validatorData(LedgerAccountInfoVo ledgerAccountInfoVo) {
        LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountInfoVo.getLedgerAccountBasicInfo();

        if (ledgerAccountBasicInfo != null) {
            //货物金额+贴现费用+资金占用费总计 = 入账金额
            BigDecimal ledgerAmount = ledgerAccountBasicInfo.getLedgerAmount() == null ? BigDecimal.ZERO : ledgerAccountBasicInfo.getLedgerAmount();
            BigDecimal goodsAssignAmount = ledgerAccountBasicInfo.getGoodsAmount() == null ? BigDecimal.ZERO : ledgerAccountBasicInfo.getGoodsAmount();
            BigDecimal discountChargeAmount = ledgerAccountBasicInfo.getDiscountCharge() == null ? BigDecimal.ZERO : ledgerAccountBasicInfo.getDiscountCharge();

            List<LedgerFundPossessionCost> possessionCostList = ledgerAccountInfoVo.getLedgerFundPossessionCostList();
            BigDecimal possessionCostTotal = BigDecimal.ZERO;
            if (possessionCostList != null && possessionCostList.size() > 0) {
                possessionCostTotal = possessionCostList.stream().filter(p -> p.getFundPossessionCost() != null)
                        .map(LedgerFundPossessionCost::getFundPossessionCost).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if ((goodsAssignAmount.add(discountChargeAmount)).add(possessionCostTotal).compareTo(ledgerAmount) != 0) {
                throw new BusinessException(CodeUtil.FAIL, "货物金额+贴现费用+资金占用费总计必须等于入账金额");
            }

            //货物金额 = 各货物金额之和
            List<LedgerFundGoodsAssign> goodsAssignList = ledgerAccountInfoVo.getGoodsAssignList();
            BigDecimal goodsAssignTotal = BigDecimal.ZERO;
            if (goodsAssignList != null && goodsAssignList.size() > 0) {
                for (LedgerFundGoodsAssign goodsAssign : goodsAssignList) {
                    if (goodsAssign.getFinancingPrincipal() == null || goodsAssign.getFinancingInterest() == null
                            || goodsAssign.getPlatformProfit() == null || goodsAssign.getAccrualAmount() == null
                            || goodsAssign.getDiscountAmount() == null) {
                        throw new BusinessException(CodeUtil.FAIL, "需要一键计算出货物分配金额才能提交");
                    }
                }
                goodsAssignTotal = goodsAssignList.stream().filter(g -> g.getCurrentAssignAmount() != null)
                        .map(LedgerFundGoodsAssign::getCurrentAssignAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if (goodsAssignTotal.compareTo(goodsAssignAmount) != 0) {
                throw new BusinessException(CodeUtil.FAIL, "货物金额必须等于各货物金额之和");
            }
        }
    }

    @Override
    public LedgerAccountInfoVo getById(Long id) {

        LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountBasicInfoService.getDetail(id);
        if (ledgerAccountBasicInfo == null || ledgerAccountBasicInfo.getId() == null) {
            throw new ValidatorException(CodeUtil.FAIL, "分账基础信息不能为空");
        }

        LedgerAccountInfoVo ledgerAccountInfoVo = new LedgerAccountInfoVo();
        ledgerAccountInfoVo.setLedgerAccountBasicInfo(ledgerAccountBasicInfo);

        //货款分配
        List<LedgerFundGoodsAssign> goodsAssignList = ledgerFundGoodsAssignService.findByBasicId(ledgerAccountBasicInfo.getId());

        if (goodsAssignList != null && goodsAssignList.size() > 0) {
            ledgerAccountInfoVo.setGoodsAssignList(goodsAssignList);
        }

        //资金占用费
//        List<LedgerFundPossessionCost> fundPossessionCostList = ledgerFundPossessionCostService.findByBasicId(ledgerAccountBasicInfo.getId());
//        if (fundPossessionCostList != null && fundPossessionCostList.size() > 0) {
//            ledgerAccountInfoVo.setLedgerFundPossessionCostList(fundPossessionCostList);
//        }

        //关联的供应商账户
        List<LedgerSupplierBankRef> supplierBankRefList = ledgerSupplierBankRefService.list(new QueryWrapper<LedgerSupplierBankRef>()
                .eq("ledger_account_basic_info_id", ledgerAccountBasicInfo.getId()));
        if (supplierBankRefList != null && supplierBankRefList.size() > 0) {
            supplierBankRefList.stream().forEach(ledgerSupplierBankRef -> {
                if (ledgerSupplierBankRef != null && ledgerSupplierBankRef.getSupplierBankCardInfoId() != null) {
                    SupplierBankCardInfo supplierBankCardInfo = supplierBankCardInfoService.getById(ledgerSupplierBankRef.getSupplierBankCardInfoId());
                    if (supplierBankCardInfo != null && supplierBankCardInfo.getSupplierId() != null) {
                        Customer customer = customerService.getById(supplierBankCardInfo.getSupplierId());
                        supplierBankCardInfo.setSupplierName(customer.getEnterpriseName());
                    }
                    ledgerSupplierBankRef.setSupplierBankCardInfo(supplierBankCardInfo);
                }
            });
            ledgerAccountInfoVo.setLedgerSupplierBankRefList(supplierBankRefList);
        }
        return ledgerAccountInfoVo;
    }

    @Override
    public GridPage<LedgerFundGoodsAssign> findFinancingGoodsList(LedgerPlanFactoringSearch search) {

        //选择对应业务编号下的所有已开过票的结算单信息
        if (search.getLabel() == null) {
            throw new BusinessException(CodeUtil.FAIL, "标签不能为空");
        }

        //选择对应业务编号下的所有已开过票的底层编号  底层货物计算是需要用到
        List<Long> sopAccountsReceivableIds = new ArrayList<>();
        if (search.getLabel().equals(0)) {
            //下游回款、查询核心企业
            sopAccountsReceivableIds = ledgerManagementMapper.findAccountsReceivableIdsByEnterpriseId(search.getEnterpriseId());
        } else if (search.getLabel().equals(1)) {
            //上游回购、查询供应商
            sopAccountsReceivableIds = ledgerManagementMapper.findAccountsReceivableIdsBySupplierId(search.getEnterpriseId());
        }
        if (sopAccountsReceivableIds != null && sopAccountsReceivableIds.size() > 0) {
            search.setSopAccountsReceivableIds(sopAccountsReceivableIds);
            search.setLevel("all");
            ResponseEntity<List> responseEntity = restTemplate.postForEntity(findGoodsAssignInfoUrl, search, List.class);
            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                throw new BusinessException(CodeUtil.FAIL, "调用SOP接口获取货款分配信息失败");
            }
            if (responseEntity.getBody() != null) {
                List<Map<String, Object>> rows = responseEntity.getBody();
                //获取销售总价、采购总价、底层编号
                List<LedgerFundGoodsAssign> voList = new ArrayList<>();
                for (Map<String, Object> row : rows) {
                    LedgerFundGoodsAssign goodsAssignVo = BeanUtil.mapToBean(row, LedgerFundGoodsAssign.class, true);
                    voList.add(goodsAssignVo);
                }
                List<LedgerFundGoodsAssign> goodsAssignVoList = new ArrayList<>();
                for (LedgerFundGoodsAssign goodsAssignVo : voList) {
                    //该底层的实际放款金额
                    BigDecimal actualLoanAmount = BigDecimal.ZERO;
                    for (LedgerFundGoodsAssign ledgerFundGoodsAssign : voList) {
                        if (goodsAssignVo.getSopAccountsReceivableId().equals(ledgerFundGoodsAssign.getSopAccountsReceivableId())) {
                            actualLoanAmount = actualLoanAmount.add(ledgerFundGoodsAssign.getLoanAmount());
                        }
                    }
                    if (goodsAssignVo.getSopAccountsReceivableId() != null) {
                        UnderlyingBasicInfo basicInfo = underlyingBasicInfoService.getOne(new QueryWrapper<UnderlyingBasicInfo>()
                                .eq("sop_accounts_receivable_id", goodsAssignVo.getSopAccountsReceivableId()));
                        if (basicInfo != null) {
                            //     对于单笔底层多次放款，无法拆分 销售总价和采购总价 的情况，计算规则为：
                            //     单次放款的销售总价为：单次放款金额/该笔底层的实际放款金额  *  该笔底层的销售总价
                            //     单次放款的采购总价为：单次放款金额/该笔底层的实际放款金额  *  该笔底层的采购总价
                            goodsAssignVo.setReceivablesNumber(basicInfo.getReceivablesNumber());
                            BigDecimal salesTotalPriceSum = underlyingGoodsInfoService.sumSalesTotalPrice(basicInfo.getId());
                            salesTotalPriceSum = salesTotalPriceSum.multiply(goodsAssignVo.getLoanAmount()).divide(actualLoanAmount, 2, BigDecimal.ROUND_HALF_UP);
                            goodsAssignVo.setSalesTotalPrice(salesTotalPriceSum);

                            BigDecimal purchaseTotalPriceSum = underlyingGoodsInfoService.sumPurchaseTotalPrice(basicInfo.getId());
                            purchaseTotalPriceSum = purchaseTotalPriceSum.multiply(goodsAssignVo.getLoanAmount()).divide(actualLoanAmount, 2, BigDecimal.ROUND_HALF_UP);
                            goodsAssignVo.setPurchaseTotalPrice(purchaseTotalPriceSum);
                        }
                        //根据供应商名称获取供应商Id
                        Customer customer = customerService.getOne(new QueryWrapper<Customer>()
                                .eq("enterprise_name", goodsAssignVo.getSupplierName()));
                        if (customer == null || customer.getId() == null) {
                            throw new BusinessException(CodeUtil.FAIL, "根据供应商名称获取不到对应供应商信息");
                        }
                        goodsAssignVo.setSupplierId(customer.getId());

                        // 计算待分配金额 = 贸理通底层对应的销售总价-已分账金额
                        //计算销售总价
                        BigDecimal toAssignedAmount = BigDecimal.ZERO;
                        if (goodsAssignVo.getReceivablesNumber() != null) {
                            UnderlyingBasicInfo underlyingBasicInfo = underlyingBasicInfoService.getOne(new QueryWrapper<UnderlyingBasicInfo>()
                                    .eq("receivables_number", goodsAssignVo.getReceivablesNumber()));
                            if (underlyingBasicInfo != null) {
                                BigDecimal salesTotalPrice = underlyingGoodsInfoService.sumSalesTotalPrice(underlyingBasicInfo.getId());
                                //计算已分账金额
                                BigDecimal assignAmount = ledgerFundGoodsAssignService.calculateAssignAmount(goodsAssignVo.getSopAccountsReceivableId()
                                        , goodsAssignVo.getBillingFactoringBusinessLoanRecordId());
                                toAssignedAmount = salesTotalPrice.multiply(goodsAssignVo.getLoanAmount()).divide(actualLoanAmount, 2, BigDecimal.ROUND_HALF_UP).subtract(assignAmount);
                            }
                        }
                        goodsAssignVo.setToAssignedAmount(toAssignedAmount);
                    }
                    goodsAssignVoList.add(goodsAssignVo);
                }


                if (CollectionUtil.isNotEmpty(goodsAssignVoList) && StringUtils.isNotBlank(search.getFastSearch())) {
                    goodsAssignVoList = goodsAssignVoList.stream().filter(g -> g.getReceivablesNumber().contains(search.getFastSearch()) ||
                                    g.getContractNo().contains(search.getFastSearch()) || g.getSupplierName().contains(search.getFastSearch()))
                            .collect(Collectors.toList());
                }
                //前端列表只能用rows取数，因此此列表虽然不分页，但依然返回GridPage对象
                return new GridPage<>(search.getRows(), search.getPage(), 100, goodsAssignVoList);
            }
        }
        return null;
    }

    @Override
    public GridPage<LedgerFundGoodsAssign> findAcceptanceGoodsList(LedgerPlanFactoringSearch search) {

        //选择对应业务编号下的所有已开过票的结算单信息
        if (search.getLabel() == null) {
            throw new BusinessException(CodeUtil.FAIL, "标签不能为空");
        }

        List<LedgerFundGoodsAssign> goodsAssignVoList = new ArrayList<>();
        if (search.getLabel().equals(0)) {
            //下游回款、查询核心企业
            goodsAssignVoList = ledgerManagementMapper.findAcceptanceByEnterpriseId(search.getEnterpriseId());
        } else if (search.getLabel().equals(1)) {
            //上游回购、查询供应商
            goodsAssignVoList = ledgerManagementMapper.findAcceptanceBySupplierId(search.getEnterpriseId());
        }

        //获取销售总价、待分配金额
        if (goodsAssignVoList != null && goodsAssignVoList.size() > 0) {
            for (LedgerFundGoodsAssign ledgerFundGoodsAssign : goodsAssignVoList) {
                List<SettlementGoodsInfo> settlementGoodsInfos = settlementGoodsInfoService
                        .list(new QueryWrapper<SettlementGoodsInfo>().eq("settlement_basic_info_id", ledgerFundGoodsAssign.getId()));
                BigDecimal salesTotalPriceSum = BigDecimal.ZERO;
                BigDecimal purchaseTotalPriceSum = BigDecimal.ZERO;
                if (settlementGoodsInfos != null && settlementGoodsInfos.size() > 0) {
                    salesTotalPriceSum = settlementGoodsInfos.stream().filter(s -> s.getSalesTotalPrice() != null)
                            .map(SettlementGoodsInfo::getSalesTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                    purchaseTotalPriceSum = settlementGoodsInfos.stream().filter(s -> s.getPurchaseTotalPrice() != null)
                            .map(SettlementGoodsInfo::getPurchaseTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                }
                ledgerFundGoodsAssign.setSalesTotalPrice(salesTotalPriceSum);
                ledgerFundGoodsAssign.setPurchaseTotalPrice(purchaseTotalPriceSum);
                // 计算待分配金额 = 结算单对应的销售总价-已分账金额
                //计算销售总价
                BigDecimal toAssignedAmount = BigDecimal.ZERO;
                if (ledgerFundGoodsAssign.getSettlementNumber() != null) {
                    SettlementBasicInfo settlementBasicInfo = settlementBasicInfoService.getOne(new QueryWrapper<SettlementBasicInfo>()
                            .eq("settlement_number", ledgerFundGoodsAssign.getSettlementNumber()));
                    if (settlementBasicInfo != null) {
                        BigDecimal salesTotalPrice = settlementGoodsInfoService.sumSalesTotalPrice(settlementBasicInfo.getId());
                        //计算已分账金额
                        BigDecimal assignAmount = ledgerFundGoodsAssignService.calculateAssignAmount(ledgerFundGoodsAssign.getSettlementNumber());
                        toAssignedAmount = salesTotalPrice.subtract(assignAmount);
                    }
                }
                ledgerFundGoodsAssign.setToAssignedAmount(toAssignedAmount);
            }
        }
        //前端列表只能用rows取数，因此此列表虽然不分页，但依然返回GridPage对象
        return new GridPage<>(search.getRows(), search.getPage(), 100, goodsAssignVoList);
    }

    @Override
    public List<SupplierBankInfoVo> findSupplierBankInfoList(LedgerSupplierBankRef supplierBankRef) {

        if (supplierBankRef == null || supplierBankRef.getSupplierIdList() == null) {
            throw new BusinessException(CodeUtil.FAIL, "供应商Id不能为空");
        }

        List<Long> supplierIdList = supplierBankRef.getSupplierIdList();

        List<SupplierBankInfoVo> supplierBankInfoVoList = new ArrayList<>();
        if (supplierIdList.size() > 0) {
            for (Long supplierId : supplierIdList) {
                SupplierBankInfoVo supplierBankInfoVo = new SupplierBankInfoVo();
                supplierBankInfoVo.setSupplierId(supplierId);

                List<SupplierBankCardInfo> bankCardInfoList = supplierBankCardInfoService.findBySupplierId(supplierId);

                if (bankCardInfoList == null || bankCardInfoList.isEmpty()) {
                    throw new BusinessException(CodeUtil.FAIL, "该供应商尚未关联银行账号，请先去企业信息管理关联!");
                }

                supplierBankInfoVo.setBankCardInfoList(bankCardInfoList);

                Customer customer = customerService.getById(supplierId);
                if (customer == null) {
                    throw new BusinessException(CodeUtil.FAIL, "获取不到对应的供应商信息");
                }
                supplierBankInfoVo.setSupplierName(customer.getEnterpriseName());
                supplierBankInfoVoList.add(supplierBankInfoVo);
            }
        }

        return supplierBankInfoVoList;
    }


    @Override
    public GridPage<PaymentCollectionPlanFactoring> findPayCollPlanFactoringList(LedgerPlanFactoringSearch search) {

        if (search.getSopAccountsReceivableId() == null || search.getBillingFactoringBusinessLoanRecordId() == null) {
            throw new BusinessException(CodeUtil.FAIL, "参数不能为空");
        }

        ResponseEntity<GridPage> responseEntity = restTemplate.getForEntity(payCollPlanFactoringListUrl + "?rows=" + search.getRows() + "&page="
                + search.getPage() + "&accountsReceivableId=" + search.getSopAccountsReceivableId()
                + "&billingFactoringBusinessLoanRecordId=" + search.getBillingFactoringBusinessLoanRecordId(), GridPage.class);
        return responseEntity.getBody();
    }

    /**
     * 获取未完成的收放款计划
     *
     * @param sopAccountsReceivableId              sop应收账款Id
     * @param billingFactoringBusinessLoanRecordId sop放款记录Id
     * @return
     */
    public List<PaymentCollectionPlanFactoring> findUnCompletePayCollPlanFactoringList(Long sopAccountsReceivableId, Long billingFactoringBusinessLoanRecordId) {

        ResponseEntity<PaymentCollectionPlanFactoring[]> responseEntity = restTemplate
                .getForEntity(unCompletePayCollPlanFactoringList + "?accountsReceivableId=" + sopAccountsReceivableId
                        + "&billingFactoringBusinessLoanRecordId=" + billingFactoringBusinessLoanRecordId, PaymentCollectionPlanFactoring[].class);
        if (responseEntity.getBody() == null) {
            throw new BusinessException(CodeUtil.FAIL, "分配的货物有对应的在途业务：额度支用支用对应底层，但财务尚未确认付款未生成收放款计划");
        }
        return Arrays.asList(responseEntity.getBody());
    }

    /**
     * 获取所有的收放款计划
     *
     * @param sopAccountsReceivableId              sop应收账款Id
     * @param billingFactoringBusinessLoanRecordId sop放款记录Id
     * @return
     */
    public List<PaymentCollectionPlanFactoring> findAllPayCollPlanFactoringList(Long sopAccountsReceivableId, Long billingFactoringBusinessLoanRecordId) {

        ResponseEntity<PaymentCollectionPlanFactoring[]> responseEntity = restTemplate
                .getForEntity(allPayCollPlanFactoringList + "?accountsReceivableId=" + sopAccountsReceivableId
                        + "&billingFactoringBusinessLoanRecordId=" + billingFactoringBusinessLoanRecordId, PaymentCollectionPlanFactoring[].class);
        if (responseEntity.getBody() == null) {
            throw new BusinessException(CodeUtil.FAIL, "分配的货物有对应的在途业务：额度支用支用对应底层，但财务尚未确认付款未生成收放款计划");
        }
        return Arrays.asList(responseEntity.getBody());
    }

    /**
     * 获取利息计算方式、融资利率、利息是否计算投放日
     *
     * @param sopAccountsReceivableId sop应收账款Id
     * @return
     */
    private PrePaymentCalculateVo findPrepaymentInterestCal(Long sopAccountsReceivableId, Long billingFactoringBusinessLoanRecordId) {

        ResponseEntity<PrePaymentCalculateVo> responseEntity = restTemplate
                .getForEntity(findPrepaymentInterestCalUrl + "?accountsReceivableId=" + sopAccountsReceivableId
                        + "&billingFactoringBusinessLoanRecordId=" + billingFactoringBusinessLoanRecordId, PrePaymentCalculateVo.class);
        return responseEntity.getBody();
    }


//    @Override
//    public LedgerAccountInfoVo calculateAssign(LedgerAccountInfoVo ledgerAccountInfoVo) {
//        List<LedgerFundGoodsAssign> goodsAssignVoList = new ArrayList<>();
//        LedgerPlanFactoringSearch search = new LedgerPlanFactoringSearch();
//        search.setBusinessNumber(ledgerAccountInfoVo.getLedgerAccountBasicInfo().getBusinessNumber());
//
//        List<Long> sopAccountsReceivableIds = ledgerManagementMapper.findAccountsReceivableIdsByBusinessNumber(search.getBusinessNumber());
//        if (sopAccountsReceivableIds != null && sopAccountsReceivableIds.size() > 0) {
//            search.setSopAccountsReceivableIds(sopAccountsReceivableIds);
//            ResponseEntity<List> responseEntity = restTemplate.postForEntity(findGoodsAssignInfoUrl, search, List.class);
//            if (responseEntity.getStatusCode() != HttpStatus.OK) {
//                throw new BusinessException(CodeUtil.FAIL, "调用SOP接口获取货款分配信息失败");
//            }
//            if (responseEntity.getBody() != null) {
//                List<Map<String, Object>> rows = responseEntity.getBody();
//                //获取销售总价、采购总价、底层编号
//                for (Map<String, Object> row : rows) {
//                    LedgerFundGoodsAssign goodsAssignVo = BeanUtil.mapToBean(row, LedgerFundGoodsAssign.class, true);
//                    goodsAssignVoList.add(goodsAssignVo);
//                }
//            }
//        }
//        for (LedgerFundGoodsAssign goodsAssign : goodsAssignVoList) {
//            //该底层的实际放款金额
//            if (goodsAssign.getSopAccountsReceivableId() != null) {
//                UnderlyingBasicInfo basicInfo = underlyingBasicInfoService.getOne(new QueryWrapper<UnderlyingBasicInfo>()
//                        .eq("sop_accounts_receivable_id", goodsAssign.getSopAccountsReceivableId()));
//                if (basicInfo != null) {
//                    goodsAssign.setReceivablesNumber(basicInfo.getReceivablesNumber());
//                }
//            }
//        }
//
//        List<LedgerFundGoodsAssign> ledgerFundGoodsAssignList = ledgerAccountInfoVo.getGoodsAssignList();
//        if (ledgerFundGoodsAssignList == null || ledgerFundGoodsAssignList.isEmpty()) {
//            throw new BusinessException(CodeUtil.FAIL, "货物列表不能为空");
//        }
//
//        //计算业务下履约保证金上限
//        LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountInfoVo.getLedgerAccountBasicInfo();
//        if (ledgerAccountBasicInfo == null || ledgerAccountBasicInfo.getBusinessNumber() == null) {
//            throw new BusinessException(CodeUtil.FAIL, "分账基础信息-业务编号不能为空");
//        }
////        BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(ledgerAccountBasicInfo.getBusinessNumber());
//        //业务下的履约保证金上限
////        BigDecimal depositLimit = businessBasicInfo.getDepositLimit();
//        // 计算该业务已经占用的保证金
//        List<LedgerAccountBasicInfo> ledgerAccountBasicInfoList = ledgerAccountBasicInfoService.list(new QueryWrapper<LedgerAccountBasicInfo>()
//                .eq("business_number", ledgerAccountBasicInfo.getBusinessNumber()));
//        BigDecimal occupyAmount = BigDecimal.ZERO;
//        if (ledgerAccountBasicInfoList != null && ledgerAccountBasicInfoList.size() > 0) {
//            for (LedgerAccountBasicInfo basicInfo : ledgerAccountBasicInfoList) {
//                List<LedgerFundGoodsAssign> goodsAssignList = ledgerFundGoodsAssignService.findByBasicId(basicInfo.getId());
//                BigDecimal accrualAmount = goodsAssignList.stream().filter(l -> l.getAccrualAmount() != null && l.getSubmit() != null && l.getSubmit())
//                        .map(LedgerFundGoodsAssign::getAccrualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//                occupyAmount = occupyAmount.add(accrualAmount);
//            }
//        }
//
//        //该业务剩余可用计提金额
////        BigDecimal surplusAccrualAmount = depositLimit.subtract(occupyAmount);
//        //可分配计提金额
//        BigDecimal remaining = surplusAccrualAmount;
//
//        //底层编号
//        Set<String> underlyingNumbers = new HashSet<>();
//
//        if (ledgerFundGoodsAssignList != null && ledgerFundGoodsAssignList.size() > 0) {
//            for (LedgerFundGoodsAssign goodsAssignVo : ledgerFundGoodsAssignList) {
//                //本次分配金额
//                BigDecimal thisAssignAmount = goodsAssignVo.getCurrentAssignAmount() == null ? BigDecimal.ZERO
//                        : goodsAssignVo.getCurrentAssignAmount();
//                //待分配金额
//                BigDecimal toAssignedAmount = goodsAssignVo.getToAssignedAmount() == null ? BigDecimal.ZERO
//                        : goodsAssignVo.getToAssignedAmount();
//                if (thisAssignAmount.compareTo(toAssignedAmount) == 1) {
//                    throw new BusinessException(CodeUtil.FAIL, "本次分配金额不能大于待分配金额");
//                }
//
//                List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList = new ArrayList<>();
//
//                if (StringUtils.isBlank(goodsAssignVo.getReceivablesNumber()) && StringUtils.isNotBlank(goodsAssignVo.getSettlementNumber())) {
//                    //说明选的是结算单货物
//                    //该笔结算单已存在的货款分配
//                    List<LedgerFundGoodsAssign> oldLedgerFundGoodsAssignLists = ledgerFundGoodsAssignService.list(
//                            new QueryWrapper<LedgerFundGoodsAssign>().eq("settlement_number", goodsAssignVo.getSettlementNumber())
//                                    .eq("is_submit", true));
//                    //该次结算放款已有平台利润
//                    BigDecimal existingProfit = BigDecimal.ZERO;
//                    for (LedgerFundGoodsAssign oldLedgerFundGoodsAssignList : oldLedgerFundGoodsAssignLists) {
//                        //同一笔结算单的同一笔放款计提上限是否已经达到
//                        if (oldLedgerFundGoodsAssignList.getSettlementNumber().equals(goodsAssignVo.getSettlementNumber())) {
//                            existingProfit = existingProfit.add(oldLedgerFundGoodsAssignList.getPlatformProfit());
//                        }
//                    }
//                    //融资利息、融资本金置为0
//                    goodsAssignVo.setFinancingPrincipal(BigDecimal.ZERO);
//                    goodsAssignVo.setFinancingInterest(BigDecimal.ZERO);
//                    //最大平台利润= 销售总价-采购总价
//                    BigDecimal salesTotalPrice = goodsAssignVo.getSalesTotalPrice() == null ? BigDecimal.ZERO
//                            : goodsAssignVo.getSalesTotalPrice();
//                    BigDecimal purchaseTotalPrice = goodsAssignVo.getPurchaseTotalPrice() == null ? BigDecimal.ZERO
//                            : goodsAssignVo.getPurchaseTotalPrice();
//                    BigDecimal platformProfit = salesTotalPrice.subtract(purchaseTotalPrice);
//
//                    //最大平台利润和已有平台利润比较
//                    if (existingProfit.compareTo(platformProfit) == -1) {
//                        platformProfit = platformProfit.subtract(existingProfit);
//                    } else {
//                        platformProfit = BigDecimal.ZERO;
//                    }
//
//                    //平台利润和分配金额比较
//                    if (platformProfit.compareTo(thisAssignAmount) >= 0) {
//                        platformProfit = thisAssignAmount;
//                    }
//
//                    goodsAssignVo.setPlatformProfit(platformProfit);
//                    // 计提金额  结算货物 无计提金额
//                    BigDecimal accrualAmount = BigDecimal.ZERO;
//                    goodsAssignVo.setAccrualAmount(accrualAmount);
//                    //实退金额= 本次分配金额-保理融资利息-保理融资本金-计提金额-平台利润
//                    BigDecimal discountAmount = thisAssignAmount.subtract(accrualAmount).subtract(platformProfit);
//                    goodsAssignVo.setDiscountAmount(discountAmount);
//                    goodsAssignVo.setLedgerPlanFactoringAssignList(ledgerPlanFactoringAssignList);
//                }
//
//                if (StringUtils.isNotBlank(goodsAssignVo.getReceivablesNumber()) && StringUtils.isBlank(goodsAssignVo.getSettlementNumber())) {
//                    //说明选的是底层货物
//                    BigDecimal financePrincipal = BigDecimal.ZERO;
//                    BigDecimal financeInterest = BigDecimal.ZERO;
//                    BigDecimal financingManagementFee = BigDecimal.ZERO;
//                    BigDecimal financingOverdueInterest = BigDecimal.ZERO;
//                    BigDecimal refundInterest = BigDecimal.ZERO;
//                    BigDecimal refundManagement = BigDecimal.ZERO;
//
//                    //本次分配金额
//                    BigDecimal assignAmount = goodsAssignVo.getCurrentAssignAmount();
//                    //待回款本金
//                    BigDecimal returnedAmount = goodsAssignVo.getReturnedAmount() == null ? BigDecimal.ZERO : goodsAssignVo.getReturnedAmount();
//                    if (returnedAmount.compareTo(BigDecimal.ZERO) > 0) {
//                        if (goodsAssignVo.getSopAccountsReceivableId() == null || goodsAssignVo.getBillingFactoringBusinessLoanRecordId() == null) {
//                            throw new BusinessException(CodeUtil.FAIL, "传参异常");
//                        }
//
//                        //查询所有未完成的收放款计划
//                        List<PaymentCollectionPlanFactoring> planFactoringList = findUnCompletePayCollPlanFactoringList(goodsAssignVo.getSopAccountsReceivableId(),
//                                goodsAssignVo.getBillingFactoringBusinessLoanRecordId());
//                        planFactoringList.stream().filter(p -> p.getPlanDate() != null).forEach(p -> p.setPlanDate(DateUtil.beginOfDay(p.getPlanDate())));
//
//                        //入账日期
//                        Date ledgerDate = ledgerAccountBasicInfo.getLedgerDate();
//
//                        //判断还款方式
//                        Long sopAccountsReceivableId = goodsAssignVo.getSopAccountsReceivableId();
//                        Long billingFactoringBusinessLoanRecordId = goodsAssignVo.getBillingFactoringBusinessLoanRecordId();
//                        PrePaymentCalculateVo paymentCalculateVo = findPrepaymentInterestCal(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
//                        if (paymentCalculateVo.getPayBackMethod() == null || paymentCalculateVo.getPayBackMethod().getId() == null) {
//                            throw new BusinessException(CodeUtil.FAIL, "无法获取到该业务的还款方式");
//                        }
//                        Dictionary payBackMethod = paymentCalculateVo.getPayBackMethod();
//
//                        if (payBackMethod.getCode().equals("pre_interest") || payBackMethod.getCode().equals("after_interest")) {
//                            //查询所有的收放款计划
//                            List<PaymentCollectionPlanFactoring> allPlanFactoringList = findAllPayCollPlanFactoringList(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
//                            //获取所有的本金收款计划
//                            Dictionary principalDict = dictService.getByCode(IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode());
//                            if (principalDict == null || principalDict.getId() == null) {
//                                throw new BusinessException(CodeUtil.FAIL, "本金字典项不能为空!");
//                            }
//                            List<PaymentCollectionPlanFactoring> principalFactoringList = getFactoringByAmountType(allPlanFactoringList, principalDict);
//                            //判断已经分配的本金计划有没有分配完成
//                            if (CollectionUtil.isNotEmpty(principalFactoringList)) {
//                                principalFactoringList.stream().forEach(p -> {
//                                    List<PayCollPlanFactoringAmountAllocation> amountAllocationList = p.getAmountAllocationList();
//                                    if (CollectionUtil.isNotEmpty(amountAllocationList)) {
//                                        BigDecimal collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
//                                                .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//                                        if (collAmountSum.compareTo(p.getAmount()) != 0) {
//                                            throw new BusinessException(CodeUtil.FAIL, "尚有本金计划未分配完成、请先去sop修改收放款计划或者分配完再来分账");
//                                        }
//                                    }
//                                });
//                            }
//
//                            //1.查看计划是否有逾期利息
//                            List<PaymentCollectionPlanFactoring> overdueInterestList = planFactoringList.stream()
//                                    .filter(f -> f.getAmountType().getCode().equals("overdue_interest") && f.getPlanDate().before(ledgerDate))
//                                    .sorted(Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate)).collect(Collectors.toList());
//                            if (overdueInterestList != null && overdueInterestList.size() > 0) {
//                                for (PaymentCollectionPlanFactoring factoring : overdueInterestList) {
//                                    BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                    financingOverdueInterest = financingOverdueInterest.add(currentAssignAmount);
//                                    assignAmount = assignAmount.subtract(currentAssignAmount);
//                                    ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, currentAssignAmount, factoring, goodsAssignVo, 0));
//                                    if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                        //说明钱已经分完了，结束分配
//                                        break;
//                                    }
//                                }
//                            }
//
//                            //2.查看计划是否有其他费用
//                            List<PaymentCollectionPlanFactoring> otherFeeList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("other_fee")).collect(Collectors.toList());
//                            if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                if (otherFeeList != null && otherFeeList.size() > 0) {
//                                    for (PaymentCollectionPlanFactoring factoring : otherFeeList) {
//                                        BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                        financeInterest = financeInterest.add(currentAssignAmount);
//                                        assignAmount = assignAmount.subtract(currentAssignAmount);
//                                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, currentAssignAmount, factoring, goodsAssignVo, 0));
//                                        if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                            //说明钱已经分完了，结束分配
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                        Dictionary principalDict = dictService.getByCode(IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode());
//                        if (principalDict == null || principalDict.getId() == null) {
//                            throw new BusinessException(CodeUtil.FAIL, "本金字典项不能为空!");
//                        }
//                        Dictionary interestDict = dictService.getByCode(IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode());
//                        if (interestDict == null || interestDict.getId() == null) {
//                            throw new BusinessException(CodeUtil.FAIL, "利息字典项不能为空!");
//                        }
//                        Dictionary managementFeeDict = dictService.getByCode(IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode());
//                        if (managementFeeDict == null || managementFeeDict.getId() == null) {
//                            throw new BusinessException(CodeUtil.FAIL, "管理费字典项不能为空!");
//                        }
//                        Date latestCollDate = goodsAssignVo.getLatestCollDate();
//                        if (payBackMethod.getCode().equals("pre_interest")) {
//                            //校验前收息的延期利息、管理费状态是否已完成
////                            List<PaymentCollectionPlanFactoring> overdueInterestList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("overdue_interest")).filter(f -> f.getPlanDate().compareTo(new Date()) < 1).collect(Collectors.toList());
//                            List<PaymentCollectionPlanFactoring> interestList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("interest")).filter(f -> f.getAmount().compareTo(BigDecimal.ZERO) >= 0).collect(Collectors.toList());
//                            List<PaymentCollectionPlanFactoring> managementFeeList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("management_fee")).filter(f -> f.getAmount().compareTo(BigDecimal.ZERO) >= 0).collect(Collectors.toList());
//                            List<PaymentCollectionPlanFactoring> otherFeeList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("other_fee")).filter(f -> f.getPlanDate().compareTo(new Date()) < 1).collect(Collectors.toList());
////                            if (overdueInterestList != null && overdueInterestList.size() > 0) {
////                                throw new ValidatorException(CodeUtil.FAIL, "逾期利息没有完成，请先完成逾期利息");
////                            }
//                            if (interestList != null && interestList.size() > 0) {
//                                throw new ValidatorException(CodeUtil.FAIL, "利息没有完成，请先完成利息");
//                            }
//                            if (managementFeeList != null && managementFeeList.size() > 0) {
//                                throw new ValidatorException(CodeUtil.FAIL, "管理费没有完成，请先完成管理费");
//                            }
//                            if (otherFeeList != null && otherFeeList.size() > 0) {
//                                throw new ValidatorException(CodeUtil.FAIL, "其他费用没有完成，请先完成其他费用");
//                            }
//
//                            //还款方式为前收息
//                            //1.判断分配金额和待回款本金大小
//
//                            //查询所有的收放款计划
//                            List<PaymentCollectionPlanFactoring> allPlanFactoringList = findAllPayCollPlanFactoringList(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
//                            //获取所有已经收款的管理费之和
//                            BigDecimal actualManagementTotal = getActualAmountTotal(allPlanFactoringList, managementFeeDict);
//                            //获取所有的已经收款的利息之和
//                            BigDecimal actualInterestTotal = getActualAmountTotal(allPlanFactoringList, interestDict);
//                            //获取所有的本金收款计划
//                            List<PaymentCollectionPlanFactoring> principalFactoringList = getFactoringByAmountType(allPlanFactoringList, principalDict);
//
//                            //本金分配并生成新的计划
//                            List<PaymentCollectionPlanFactoring> newPrincipalFactoringList = principalAssign(assignAmount, principalFactoringList, ledgerDate, ledgerPlanFactoringAssignList, goodsAssignVo);
//
//                            //计算计划应收管理费总和
//                            BigDecimal planManagementTotal = getAllocatedAmountByPlanFactoring(newPrincipalFactoringList, managementFeeDict,
//                                    goodsAssignVo, paymentCalculateVo);
//                            //计算计划应收利息总和
//                            BigDecimal planInterestTotal = getAllocatedAmountByPlanFactoring(newPrincipalFactoringList, interestDict,
//                                    goodsAssignVo, paymentCalculateVo);
//
//                            //用已收管理费之和减去计划应收、判断需不需要退还
//                            refundManagement = actualManagementTotal.subtract(planManagementTotal);
//                            if (refundManagement.compareTo(BigDecimal.ZERO) > 0) {
//                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, refundManagement.negate(), refundManagement.negate(),
//                                        IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
//                            }
//                            //用已收利息之和减去计划应收、判断需不需要退还
//                            refundInterest = actualInterestTotal.subtract(planInterestTotal);
//                            if (refundInterest.compareTo(BigDecimal.ZERO) > 0) {
//                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, refundInterest.negate(), refundInterest.negate(),
//                                        IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode(), goodsAssignVo, 0));
//                            }
//                            if (assignAmount.compareTo(returnedAmount) >= 0) {
//                                //分配本金小于剩余本金
//                                financePrincipal = financePrincipal.add(returnedAmount);
//                                assignAmount = assignAmount.subtract(returnedAmount);
//                            } else {
//                                //分配本金大于剩余本金
//                                financePrincipal = financePrincipal.add(assignAmount);
//                                assignAmount = assignAmount.subtract(assignAmount);
//                            }
//                        } else if (payBackMethod.getCode().equals("after_interest")) {
//                            //校验后收息的延期利息、管理费状态是否已完成
////                            List<PaymentCollectionPlanFactoring> overdueInterestList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("overdue_interest")).filter(f -> f.getGraceType() != null && f.getGraceType() > 1).filter(f -> f.getPlanDate().compareTo(new Date()) < 1).collect(Collectors.toList());
////                            List<PaymentCollectionPlanFactoring> managementFeeList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("management_fee")).filter(f -> f.getGraceType() != null && f.getGraceType() > 1).filter(f -> f.getPlanDate().compareTo(new Date()) < 1).collect(Collectors.toList());
//                            List<PaymentCollectionPlanFactoring> otherFeeList = planFactoringList.stream().filter(f -> f.getAmountType().getCode().equals("other_fee")).filter(f -> f.getPlanDate().compareTo(new Date()) < 1).collect(Collectors.toList());
////                            if (overdueInterestList != null && overdueInterestList.size() > 0) {
////                                throw new ValidatorException(CodeUtil.FAIL, "二次延期及多次延期利息没有完成，请先完成二次延期及多次延期利息");
////                            }
////                            if (managementFeeList != null && managementFeeList.size() > 0) {
////                                throw new ValidatorException(CodeUtil.FAIL, "管理费没有完成，请先完成管理费");
////                            }
//                            if (otherFeeList != null && otherFeeList.size() > 0) {
//                                throw new ValidatorException(CodeUtil.FAIL, "其他费用没有完成，请先完成其他费用");
//                            }
//                            //还款方式是后收息
//                            //获取最后一期管理费收款计划
////                            PaymentCollectionPlanFactoring managementFactoring = getLastPrincipalFactoring(planFactoringList, managementFeeDict);
//                            //获取最后一期利息收款计划
////                            PaymentCollectionPlanFactoring interestFactoring = getLastPrincipalFactoring(planFactoringList, interestDict);
////                            //最后一期计划日期
////                            Date lastPlanDate = goodsAssignVo.getLastPlanDate();
//                            //最后一期剩余管理费
//                            //                           BigDecimal lastSurplusManagement = BigDecimal.ZERO;
//                            //最后一期剩余利息
//                            //                           BigDecimal lastSurplusInterest = BigDecimal.ZERO;
//                            List<PaymentCollectionPlanFactoring> allPlanFactoringList = findAllPayCollPlanFactoringList(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
//                            //获取所有已经收款的管理费之和
//                            BigDecimal actualManagementTotal = getActualAmountTotal(allPlanFactoringList, managementFeeDict);
//                            //获取所有的已经收款的利息之和
//                            BigDecimal actualInterestTotal = getActualAmountTotal(allPlanFactoringList, interestDict);
//                            //获取所有的本金收款计划
//                            List<PaymentCollectionPlanFactoring> principalFactoringList = getFactoringByAmountType(allPlanFactoringList, principalDict);
//
//                            //计算出应收的管理费 TODO 此处逻辑需要重构
//                            //2021.4.13 判断是否有过本金分配
//                            Boolean hasPrincipalAssign = hasPrincipalAssign(principalFactoringList);
//                            BigDecimal calculateManagementFee = calculateAssignInterest(returnedAmount, latestCollDate, ledgerDate,
//                                    !hasPrincipalAssign, paymentCalculateVo, IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode());
//                            BigDecimal currentAssignManagement = BigDecimal.ZERO;
//                            if (calculateManagementFee.compareTo(BigDecimal.ZERO) > 0) {
//                                //计算冲抵完成后的剩余管理费
//                                BigDecimal surplusManagement = calculateManagementFee.subtract(actualManagementTotal);
//                                if (surplusManagement.compareTo(BigDecimal.ZERO) >= 0) {
//                                    currentAssignManagement = surplusManagement;
//                                } else {
//                                    currentAssignManagement = calculateManagementFee;
//                                }
//                                //再用分配金额和本次应分做比较
//                                if (assignAmount.compareTo(currentAssignManagement) <= 0) {
//                                    currentAssignManagement = assignAmount;
//                                }
//
//                                financingManagementFee = financingManagementFee.add(currentAssignManagement);
//                                assignAmount = assignAmount.subtract(currentAssignManagement);
//                                if (currentAssignManagement.compareTo(BigDecimal.ZERO) > 0) {
//                                    ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, currentAssignManagement, currentAssignManagement,
//                                            IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
//                                }
//                                actualManagementTotal = actualManagementTotal.add(currentAssignManagement);
//                            }
//
//                            if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                //计算出应收的利息
//                                BigDecimal calculateInterest = calculateAssignInterest(returnedAmount, latestCollDate, ledgerDate,
//                                        !hasPrincipalAssign, paymentCalculateVo, IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode());
//                                BigDecimal currentAssignInterest = BigDecimal.ZERO;
//                                if (calculateInterest.compareTo(BigDecimal.ZERO) > 0) {
//                                    //如果有利息并且还有钱分
//                                    BigDecimal surplusInterest = calculateInterest.subtract(actualInterestTotal);
//                                    if (surplusInterest.compareTo(BigDecimal.ZERO) >= 0) {
//                                        currentAssignInterest = surplusInterest;
//                                    } else {
//                                        currentAssignInterest = calculateInterest;
//                                    }
//                                    //再用分配金额和本次应分做比较
//                                    if (assignAmount.compareTo(currentAssignInterest) <= 0) {
//                                        currentAssignInterest = assignAmount;
//                                    }
//
//                                    financeInterest = financeInterest.add(currentAssignInterest);
//                                    assignAmount = assignAmount.subtract(currentAssignInterest);
//                                    if (currentAssignInterest.compareTo(BigDecimal.ZERO) > 0) {
//                                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, currentAssignInterest, currentAssignInterest,
//                                                IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode(), goodsAssignVo, 0));
//                                    }
//                                    actualInterestTotal = actualInterestTotal.add(currentAssignInterest);
//                                }
//                            }
//
//                            if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                //本金分配并生成新的计划
//                                principalFactoringList = principalAssign(assignAmount, principalFactoringList, ledgerDate, ledgerPlanFactoringAssignList, goodsAssignVo);
//                            }
//                            //分配金额为0 也得判断是否要退回，因为可能在sop侧也有入账
//                            BigDecimal planManagementTotal = getAllocatedAmountByPlanFactoring(principalFactoringList, managementFeeDict,
//                                    goodsAssignVo, paymentCalculateVo);
//                            BigDecimal planInterestTotal = getAllocatedAmountByPlanFactoring(principalFactoringList, interestDict,
//                                    goodsAssignVo, paymentCalculateVo);
//
//                            //获取所有的管理费收款计划
//                            List<PaymentCollectionPlanFactoring> managementFeeFactoringList = getFactoringByAmountType(allPlanFactoringList, managementFeeDict);
//                            //获取所有的利息收款计划
//                            List<PaymentCollectionPlanFactoring> interestFactoringList = getFactoringByAmountType(allPlanFactoringList, interestDict);
//                            //获取最后一期本金收款计划
//                            PaymentCollectionPlanFactoring lastPlanFactoring = getLastPrincipalFactoring(planFactoringList, principalDict);
//
//                            //判断管理费、利息是否需要退款
//                            refundManagement = actualManagementTotal.subtract(planManagementTotal);
//                            if (refundManagement.compareTo(BigDecimal.ZERO) > 0) {
//                                //管理费需要退款
//                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, refundManagement.negate(), refundManagement.negate(),
//                                        IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
//                                //删除未分配的管理费
//                                deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                                //将部分分配的管理费计划金额改为实收金额
//                                updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                            } else if (refundManagement.compareTo(BigDecimal.ZERO) == 0) {
//                                //删除未分配的管理费
//                                deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                                //将部分分配的管理费计划金额改为实收金额
//                                updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                            } else if (refundManagement.compareTo(BigDecimal.ZERO) < 0) {
//                                interestOrManagementAssign(refundManagement.negate(), ledgerPlanFactoringAssignList,
//                                        managementFeeFactoringList, goodsAssignVo, lastPlanFactoring, managementFeeDict);
//                            }
//
//                            refundInterest = actualInterestTotal.subtract(planInterestTotal);
//                            if (refundInterest.compareTo(BigDecimal.ZERO) > 0) {
//                                //利息需要退款
//                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, refundInterest.negate(), refundInterest.negate(),
//                                        IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode(), goodsAssignVo, 0));
//                                //删除未分配的利息
//                                deleteUnAssignList(interestFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                                //将部分分配的利息计划金额改为实收金额
//                                updatePartAssignList(interestFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                            } else if (refundInterest.compareTo(BigDecimal.ZERO) == 0) {
//                                //删除未分配的管理费
//                                deleteUnAssignList(interestFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                                //将部分分配的管理费计划金额改为实收金额
//                                updatePartAssignList(interestFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
//                            } else if (refundInterest.compareTo(BigDecimal.ZERO) < 0) {
//                                interestOrManagementAssign(refundInterest.negate(), ledgerPlanFactoringAssignList,
//                                        interestFactoringList, goodsAssignVo, lastPlanFactoring, interestDict);
//                            }
//
//                            if (assignAmount.compareTo(goodsAssignVo.getReturnedAmount()) >= 0) {
//                                //如果可分配金额>=剩余本金
//                                financePrincipal = financePrincipal.add(goodsAssignVo.getReturnedAmount());
//                                assignAmount = assignAmount.subtract(goodsAssignVo.getReturnedAmount());
//                            } else if (assignAmount.compareTo(goodsAssignVo.getReturnedAmount()) < 0) {
//                                //如果可分配金额<剩余本金
//                                financePrincipal = financePrincipal.add(assignAmount);
//                                assignAmount = assignAmount.subtract(assignAmount);
//                            }
//
//                        } else if (payBackMethod.getCode().equals("manually_generated")) {
//                            //还款方式为手动生成
//                            //1.查询有没有分账当天及之前的还款计划、没有提示用户去修改计划、有的话只分配当天的计划
//                            List<PaymentCollectionPlanFactoring> filterList = planFactoringList.stream().filter(p -> DateUtil.compare(p.getPlanDate(), new Date()) < 1)
//                                    .collect(Collectors.toList());
//                            if (filterList == null || filterList.isEmpty()) {
//                                throw new BusinessException(CodeUtil.FAIL, "手动生成的收放款计划无入账日期的回款，请先前往sop手动修改计划");
//                            } else {
//                                //按照逾期利息->其它费用->管理费->利息->本金的顺序回款
//                                List<PaymentCollectionPlanFactoring> overdueList = filterList.stream().filter(f -> f.getAmountType().getCode().equals("overdue_interest")).collect(Collectors.toList());
//                                List<PaymentCollectionPlanFactoring> otherFeeList = filterList.stream().filter(f -> f.getAmountType().getCode().equals("other_fee")).collect(Collectors.toList());
//                                List<PaymentCollectionPlanFactoring> managementFeeList = filterList.stream().filter(f -> f.getAmountType().getCode().equals("management_fee") && f.getAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                                List<PaymentCollectionPlanFactoring> interestList = filterList.stream().filter(f -> f.getAmountType().getCode().equals("interest") && f.getAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//                                List<PaymentCollectionPlanFactoring> principalList = filterList.stream().filter(f -> f.getAmountType().getCode().equals("principal") && f.getAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
//
//                                if (overdueList != null && overdueList.size() > 0) {
//                                    for (PaymentCollectionPlanFactoring factoring : overdueList) {
//                                        BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                        financingOverdueInterest = financingOverdueInterest.add(currentAssignAmount);
//                                        assignAmount = assignAmount.subtract(currentAssignAmount);
//                                        if (currentAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, currentAssignAmount, factoring, goodsAssignVo, 0));
//                                        }
//                                        if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                            //说明钱已经分完了，结束分配
//                                            break;
//                                        }
//                                    }
//                                }
//
//                                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                    if (otherFeeList != null && otherFeeList.size() > 0) {
//                                        for (PaymentCollectionPlanFactoring factoring : otherFeeList) {
//                                            BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                            financeInterest = financeInterest.add(currentAssignAmount);
//                                            assignAmount = assignAmount.subtract(currentAssignAmount);
//                                            if (currentAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                                ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, currentAssignAmount, factoring, goodsAssignVo, 0));
//                                            }
//                                            if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                                //说明钱已经分完了，结束分配
//                                                break;
//                                            }
//                                        }
//                                    }
//                                }
//
//                                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                    if (managementFeeList != null && managementFeeList.size() > 0) {
//                                        for (PaymentCollectionPlanFactoring factoring : managementFeeList) {
//                                            BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                            financingManagementFee = financingManagementFee.add(currentAssignAmount);
//                                            assignAmount = assignAmount.subtract(currentAssignAmount);
//                                            if (currentAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                                manuallyGeneratedAssign(factoring, currentAssignAmount, goodsAssignVo,
//                                                        ledgerPlanFactoringAssignList, ledgerDate, 0, IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode());
//                                            }
//                                            if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                                //说明钱已经分完了，结束分配
//                                                break;
//                                            }
//                                        }
//                                    }
//                                }
//
//                                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                    //如果钱还有剩余继续分配利息费
//                                    if (interestList != null && interestList.size() > 0) {
//                                        for (PaymentCollectionPlanFactoring factoring : interestList) {
//                                            BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                            financeInterest = financeInterest.add(currentAssignAmount);
//                                            assignAmount = assignAmount.subtract(currentAssignAmount);
//                                            if (currentAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                                manuallyGeneratedAssign(factoring, currentAssignAmount, goodsAssignVo,
//                                                        ledgerPlanFactoringAssignList, ledgerDate, 0, IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode());
//                                            }
//                                            if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                                //说明钱已经分完了，结束分配
//                                                break;
//                                            }
//                                        }
//                                    }
//                                }
//
//                                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                    //如果钱还有剩余继续分配本金
//                                    if (principalList != null && principalList.size() > 0) {
//                                        for (PaymentCollectionPlanFactoring factoring : principalList) {
//                                            BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
//                                            financePrincipal = financePrincipal.add(currentAssignAmount);
//                                            assignAmount = assignAmount.subtract(currentAssignAmount);
//                                            if (currentAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                                                manuallyGeneratedAssign(factoring, currentAssignAmount, goodsAssignVo,
//                                                        ledgerPlanFactoringAssignList, ledgerDate, 1, IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode());
//                                            }
//                                            if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
//                                                //说明钱已经分完了，结束分配
//                                                break;
//                                            }
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                    goodsAssignVo.setFinancingPrincipal(financePrincipal);
//                    goodsAssignVo.setFinancingInterest(financeInterest);
//                    goodsAssignVo.setFinancingManagementFee(financingManagementFee);
//                    goodsAssignVo.setFinancingOverdueInterest(financingOverdueInterest);
//                    goodsAssignVo.setRefundInterest(refundInterest.compareTo(BigDecimal.ZERO) > 0 ? refundInterest : BigDecimal.ZERO);
//                    goodsAssignVo.setRefundManagementFee(refundManagement.compareTo(BigDecimal.ZERO) > 0 ? refundManagement : BigDecimal.ZERO);
//                    goodsAssignVo.setLedgerPlanFactoringAssignList(ledgerPlanFactoringAssignList);
//
//                    BigDecimal platformProfit = BigDecimal.ZERO;
//                    BigDecimal discountAmount = BigDecimal.ZERO;
//
//                    // 计提金额=贸理通底层对应的应收账款净额*5%   最大计提金额
//                    BigDecimal accrualAmount = BigDecimal.ZERO;
//                    if (goodsAssignVo.getReceivablesNumber() != null) {
//                        UnderlyingBasicInfo underlyingBasicInfo = underlyingBasicInfoService.getOne(new QueryWrapper<UnderlyingBasicInfo>()
//                                .eq("receivables_number", goodsAssignVo.getReceivablesNumber()));
//                        underlyingNumbers.add(goodsAssignVo.getReceivablesNumber());
//                        if (underlyingBasicInfo != null) {
//                            //应收账款净额之和
//                            BigDecimal netAmountTotal = underlyingAccountsReceivableInfoService.sumNetAmount(underlyingBasicInfo.getId());
//                            accrualAmount = netAmountTotal.multiply(new BigDecimal(5)).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
//                        }
//                    }
//                    //当前计提金额
//                    BigDecimal currentAccrualAmount = BigDecimal.ZERO;
//                    BigDecimal existingProfit = BigDecimal.ZERO;
//
//                    List<LedgerFundGoodsAssign> oldLedgerFundGoodsAssignLists = ledgerFundGoodsAssignService.list(
//                            new QueryWrapper<LedgerFundGoodsAssign>().eq("receivables_number", goodsAssignVo.getReceivablesNumber()));
//                    if (goodsAssignVo.getAccrual() != null && goodsAssignVo.getAccrual()) {
//                        //该业务剩余可用计提金额  大于等于 底层对应的最大计提金额
//                        if (surplusAccrualAmount.compareTo(accrualAmount) >= 0) {
//                            currentAccrualAmount = accrualAmount;
//                            //该业务剩余可用计提金额  小于 底层对应的最大计提金额
//                        } else if (surplusAccrualAmount.compareTo(accrualAmount) < 0) {
//                            currentAccrualAmount = surplusAccrualAmount;
//                        }
//                        //该笔业务已占用的计提金额
//                        BigDecimal businessOccupied = BigDecimal.ZERO;
//                        //该笔底层已占计提金额
//                        BigDecimal occupied = BigDecimal.ZERO;
//                        if (ledgerAccountBasicInfoList != null && ledgerAccountBasicInfoList.size() > 0) {
//                            for (LedgerAccountBasicInfo basicInfo : ledgerAccountBasicInfoList) {
//                                List<LedgerFundGoodsAssign> goodsAssignList = ledgerFundGoodsAssignService.findByBasicId(basicInfo.getId());
//                                for (LedgerFundGoodsAssign ledgerFundGoodsAssign : goodsAssignList) {
//                                    if (ledgerFundGoodsAssign.getSubmit() != null && ledgerFundGoodsAssign.getSubmit()) {
//                                        businessOccupied = businessOccupied.add(ledgerFundGoodsAssign.getAccrualAmount());
//                                        if (ledgerFundGoodsAssign.getReceivablesNumber().equals(goodsAssignVo.getReceivablesNumber())) {
//                                            occupied = occupied.add(ledgerFundGoodsAssign.getAccrualAmount());
//                                        }
//                                    }
//                                }
//                            }
//                        }
//
//                        //按比例拆分计提金额
//                        //该笔底层的放款总和
//                        BigDecimal sumLoanAmount = BigDecimal.ZERO;
//                        for (LedgerFundGoodsAssign ledgerFundGoodsAssign : goodsAssignVoList) {
//                            if (ledgerFundGoodsAssign.getReceivablesNumber().equals(goodsAssignVo.getReceivablesNumber())) {
//                                sumLoanAmount = sumLoanAmount.add(ledgerFundGoodsAssign.getLoanAmount());
//                            }
//                        }
//
//                        //该批货物  相同底层编号底层  预占用计提金额  加上  底层已占计提
//                        for (LedgerFundGoodsAssign ledgerFundGoodsAssign : ledgerFundGoodsAssignList) {
//                            businessOccupied = businessOccupied.add(ledgerFundGoodsAssign.getAccrualAmount() == null ? BigDecimal.ZERO : ledgerFundGoodsAssign.getAccrualAmount());
//                            if (ledgerFundGoodsAssign.getReceivablesNumber().equals(goodsAssignVo.getReceivablesNumber())) {
//                                occupied = occupied.add(ledgerFundGoodsAssign.getAccrualAmount() == null ? BigDecimal.ZERO : ledgerFundGoodsAssign.getAccrualAmount());
//                            }
//                        }
//
//                        //一笔底层多次放款的活  按每次放款金额的比例拆分计提金额   该次底层防款最大计提上限
//                        BigDecimal splitAccrualAmount = accrualAmount.multiply(goodsAssignVo.getLoanAmount()).divide(sumLoanAmount, 2, RoundingMode.HALF_UP);
//                        //该笔得层已存在的货款分配
//                        if (CollectionUtil.isNotEmpty(oldLedgerFundGoodsAssignLists)) {
//                            for (LedgerFundGoodsAssign oldLedgerFundGoodsAssign : oldLedgerFundGoodsAssignLists) {
//                                //同一笔底层的同一笔放款计提上限是否已经达到
//                                if (oldLedgerFundGoodsAssign.getReceivablesNumber().equals(goodsAssignVo.getReceivablesNumber())
//                                        && oldLedgerFundGoodsAssign.getBillingFactoringBusinessLoanRecordId().equals(goodsAssignVo.getBillingFactoringBusinessLoanRecordId())) {
//                                    if (oldLedgerFundGoodsAssign.getSubmit() != null && oldLedgerFundGoodsAssign.getSubmit()) {
//                                        splitAccrualAmount = splitAccrualAmount.subtract(oldLedgerFundGoodsAssign.getAccrualAmount());
//                                    }
//                                }
//                            }
//                        }
//
//                        // 该次底层放款最大计提上限
//                        if (splitAccrualAmount.compareTo(BigDecimal.ZERO) > -1) {
//                            if (splitAccrualAmount.compareTo(currentAccrualAmount) == -1) {
//                                currentAccrualAmount = splitAccrualAmount;
//                            }
//                        }
//
//                        //和剩余分配金额比较
//                        if (assignAmount.compareTo(currentAccrualAmount) == -1) {
//                            currentAccrualAmount = assignAmount;
//                        }
//
//                        //判断预占用计提金额加上已占用计提金额是否大于底层计提上限  如果大于的话 减少该笔的计提金额到合理大小
//                        occupied = occupied.add(currentAccrualAmount);
//                        if (occupied.compareTo(accrualAmount) == 1) {
//                            currentAccrualAmount = accrualAmount.subtract(occupied.subtract(currentAccrualAmount));
//                        }
//                        if (currentAccrualAmount.compareTo(remaining) < 1) {
//                            remaining = remaining.subtract(currentAccrualAmount);
//                        } else {
//                            currentAccrualAmount = remaining;
//                        }
//
//                        //判断业务预占用计提金额加上已占用计提金额是否大于业务计提上限  如果大于的话 减少该笔的计提金额到合理大小
//                        businessOccupied = businessOccupied.add(currentAccrualAmount);
//                        if (businessOccupied.compareTo(depositLimit) == 1) {
//                            currentAccrualAmount = depositLimit.subtract(businessOccupied.subtract(currentAccrualAmount));
//                        }
//
//                        //设置合理计提金额
//                        goodsAssignVo.setAccrualAmount(currentAccrualAmount);
//                        assignAmount = assignAmount.subtract(currentAccrualAmount);
//                    }
//
//                    if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                        //分配金额还有剩余，计算平台利润和实退金额
//                        //平台利润= 销售总价-采购总价
//                        BigDecimal salesTotalPrice = goodsAssignVo.getSalesTotalPrice() == null ? BigDecimal.ZERO
//                                : goodsAssignVo.getSalesTotalPrice();
//                        BigDecimal purchaseTotalPrice = goodsAssignVo.getPurchaseTotalPrice() == null ? BigDecimal.ZERO
//                                : goodsAssignVo.getPurchaseTotalPrice();
//                        platformProfit = salesTotalPrice.subtract(purchaseTotalPrice);
//
//                        if (CollectionUtil.isNotEmpty(oldLedgerFundGoodsAssignLists)) {
//                            for (LedgerFundGoodsAssign oldLedgerFundGoodsAssign : oldLedgerFundGoodsAssignLists) {
//                                //同一笔底层的同一笔放款计提上限是否已经达到
//                                if (oldLedgerFundGoodsAssign.getReceivablesNumber().equals(goodsAssignVo.getReceivablesNumber())
//                                        && oldLedgerFundGoodsAssign.getBillingFactoringBusinessLoanRecordId().equals(goodsAssignVo.getBillingFactoringBusinessLoanRecordId())) {
//                                    if (oldLedgerFundGoodsAssign.getSubmit() != null && oldLedgerFundGoodsAssign.getSubmit()) {
//                                        existingProfit = existingProfit.add(oldLedgerFundGoodsAssign.getPlatformProfit());
//                                    }
//                                }
//                            }
//                        }
//
//                        //最大平台利润和已有平台利润比较
//                        if (existingProfit.compareTo(platformProfit) == -1) {
//                            platformProfit = platformProfit.subtract(existingProfit);
//                        } else {
//                            platformProfit = BigDecimal.ZERO;
//                        }
//
//                        if (assignAmount.compareTo(platformProfit) == -1) {
//                            platformProfit = assignAmount;
//                            assignAmount = BigDecimal.ZERO;
//                        } else {
//                            assignAmount = assignAmount.subtract(platformProfit);
//                        }
//                        if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
//                            //实退金额 = 核心企业回款-保理融资本息-平台利润
//                            discountAmount = assignAmount;
//                        }
//                    }
//                    goodsAssignVo.setPlatformProfit(platformProfit);
//                    goodsAssignVo.setDiscountAmount(discountAmount);
//                }
//            }
//        }
//        return ledgerAccountInfoVo;
//    }

    /**
     * 手动生成分配
     *
     * @param factoring
     * @param currentAssignAmount
     * @param goodsAssignVo
     * @param ledgerPlanFactoringAssignList
     */
    private void manuallyGeneratedAssign(PaymentCollectionPlanFactoring factoring, BigDecimal currentAssignAmount,
                                         LedgerFundGoodsAssign goodsAssignVo, List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList,
                                         Date ledgerDate, Integer isPrincipal, String amountType) {
        //判断有没有分配过
        List<PayCollPlanFactoringAmountAllocation> amountAllocationList = factoring.getAmountAllocationList();
        if (CollectionUtil.isEmpty(amountAllocationList)) {
            //直接修改对应计划(需分配)
            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, currentAssignAmount, factoring,
                    goodsAssignVo, isPrincipal));
        } else {
            //做过分配需要将计划进行拆分
            BigDecimal collAmountSum = BigDecimal.ZERO;
            if (amountAllocationList != null && amountAllocationList.size() > 0) {
                collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                        .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            //将已分配的计划进行变更（不分配）
            BigDecimal planAmount = factoring.getAmount();
            factoring.setAmount(collAmountSum);
            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, BigDecimal.ZERO, factoring,
                    goodsAssignVo, isPrincipal));
            //未分配金额
            BigDecimal unCollAmount = planAmount.subtract(collAmountSum);
            if (currentAssignAmount.compareTo(unCollAmount) >= 0) {
                //如果本次分配大于等于未分配金额
                //生成一笔分配计划
                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, unCollAmount, unCollAmount,
                        amountType, goodsAssignVo, isPrincipal));
            } else if (currentAssignAmount.compareTo(unCollAmount) <= 0) {
                //如果本次分配小于未分配金额
                //生成一笔分配计划
                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, currentAssignAmount, currentAssignAmount,
                        amountType, goodsAssignVo, isPrincipal));
                //生成一笔未分配计划
                BigDecimal surplus = unCollAmount.subtract(currentAssignAmount);
                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(ledgerDate, surplus, BigDecimal.ZERO,
                        amountType, goodsAssignVo, isPrincipal));
            }
        }
    }

    /**
     * 利息或管理费分配
     *
     * @param diffAmount
     * @param planFactoringList
     * @param goodsAssign
     */
    private void interestOrManagementAssign(BigDecimal diffAmount, List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList,
                                            List<PaymentCollectionPlanFactoring> planFactoringList, LedgerFundGoodsAssign goodsAssign,
                                            PaymentCollectionPlanFactoring lastPrincipalFactoring, Dictionary dict) {
        if (CollectionUtil.isNotEmpty(planFactoringList)) {
            //获取部分分配的计划
            List<PaymentCollectionPlanFactoring> partAllocationList = planFactoringList.stream().filter(p -> {
                List<PayCollPlanFactoringAmountAllocation> amountAllocationList = p.getAmountAllocationList();
                if (CollectionUtil.isNotEmpty(amountAllocationList)) {
                    BigDecimal collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                            .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                    return collAmountSum.compareTo(p.getAmount()) < 0;
                }
                return false;
            }).sorted(Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate)).collect(Collectors.toList());
            //获取未分配的计划
            List<PaymentCollectionPlanFactoring> unAllocationList = planFactoringList.stream()
                    .filter(p -> CollectionUtil.isEmpty(p.getAmountAllocationList()) && p.getAmount().compareTo(BigDecimal.ZERO) > 0)
                    .sorted(Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate)).collect(Collectors.toList());

            if (CollectionUtil.isEmpty(partAllocationList)) {
                //如果没有部分分配的计划
                if (CollectionUtil.isNotEmpty(unAllocationList)) {
                    //删除掉未分配的计划
                    unAllocationList.stream().forEach(p -> ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(p, goodsAssign, 0)));
                }
                //生成一条管理费或利息计划（不分配）
                PaymentCollectionPlanFactoring newPlanFactoring = new PaymentCollectionPlanFactoring();
                if (lastPrincipalFactoring != null) {
                    newPlanFactoring.setPlanDate(lastPrincipalFactoring.getPlanDate());
                }
                newPlanFactoring.setAmount(diffAmount);
                newPlanFactoring.setAmountType(dict);
                newPlanFactoring.setPaymentCollectionType(ConstantConversionUtil.PAY_COLL_COLLECTION);
                ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(newPlanFactoring.getPlanDate(), BigDecimal.ZERO,
                        newPlanFactoring, goodsAssign, 0));
            } else {
                //如果有部分分配的计划
                BigDecimal planAmountTotal = partAllocationList.stream().filter(p -> p.getAmount() != null)
                        .map(PaymentCollectionPlanFactoring::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                BigDecimal actualAmountTotal = BigDecimal.ZERO;
                for (PaymentCollectionPlanFactoring planFactoring : partAllocationList) {
                    List<PayCollPlanFactoringAmountAllocation> amountAllocationList = planFactoring.getAmountAllocationList();
                    if (amountAllocationList != null && amountAllocationList.size() > 0) {
                        BigDecimal collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                                .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        actualAmountTotal = actualAmountTotal.add(collAmountSum);
                    }
                }
                //应收与实收的差值
                BigDecimal planAmountDiff = planAmountTotal.subtract(actualAmountTotal);
                if (diffAmount.compareTo(planAmountDiff) > 0) {
                    //如果大于应收实收差值,判断有没有 未分配的计划
                    if (CollectionUtil.isNotEmpty(unAllocationList)) {
                        BigDecimal diff = diffAmount.subtract(planAmountDiff);
                        for (PaymentCollectionPlanFactoring factoring : unAllocationList) {
                            if (diff.compareTo(BigDecimal.ZERO) == 0) {
                                //删除后续的计划
                                ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(factoring, goodsAssign, 0));
                            } else {
                                if (diff.compareTo(factoring.getAmount()) > 0) {
                                    diff = diff.subtract(factoring.getAmount());
                                } else if (diff.compareTo(factoring.getAmount()) < 0) {
                                    //修改本笔计划
                                    factoring.setAmount(diff);
                                    ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(factoring.getPlanDate(), BigDecimal.ZERO,
                                            factoring, goodsAssign, 0));
                                    diff = BigDecimal.ZERO;
                                }
                            }
                        }
                    } else {
                        //如果大于应收实收差值，生成一条管理费或利息计划（不分配）
                        if (lastPrincipalFactoring != null) {
                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(lastPrincipalFactoring.getPlanDate(),
                                    diffAmount.subtract(planAmountDiff), BigDecimal.ZERO, dict.getCode(), goodsAssign, 0));
                        }
                    }
                } else if (diffAmount.compareTo(planAmountDiff) < 0) {
                    //如果小于应收实收差值
                    for (PaymentCollectionPlanFactoring factoring : partAllocationList) {
                        BigDecimal planAmount = factoring.getAmount();

                        List<PayCollPlanFactoringAmountAllocation> amountAllocationList = factoring.getAmountAllocationList();
                        BigDecimal actualAmount = BigDecimal.ZERO;
                        if (CollectionUtil.isNotEmpty(amountAllocationList)) {
                            actualAmount = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                                    .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        }
                        BigDecimal planSurplus = planAmount.subtract(actualAmount);

                        if (diffAmount.compareTo(BigDecimal.ZERO) == 0) {
                            //修改计划应收=实收
                            factoring.setAmount(actualAmount);
                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(factoring.getPlanDate(), BigDecimal.ZERO,
                                    factoring, goodsAssign, 0));
                        } else {
                            if (diffAmount.compareTo(planSurplus) > 0) {
                                diffAmount = diffAmount.subtract(planSurplus);
                            } else if (diffAmount.compareTo(planSurplus) < 0) {
                                //修改计划
                                factoring.setAmount(diffAmount.add(actualAmount));
                                ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(factoring.getPlanDate(), BigDecimal.ZERO,
                                        factoring, goodsAssign, 0));
                                diffAmount = BigDecimal.ZERO;
                            }
                        }
                    }
                    if (CollectionUtil.isNotEmpty(unAllocationList)) {
                        //如果还有未分配的计划，需要删掉
                        for (PaymentCollectionPlanFactoring factoring : unAllocationList) {
                            ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(factoring, goodsAssign, 0));
                        }
                    }
                }
            }
        }
    }

    /**
     * 修改部分分配的计划，将计划金额改为实收金额
     *
     * @param planFactoringList
     * @param ledgerPlanFactoringAssignList
     */
    private void updatePartAssignList(List<PaymentCollectionPlanFactoring> planFactoringList,
                                      List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList, LedgerFundGoodsAssign goodsAssign) {
        if (CollectionUtil.isNotEmpty(planFactoringList)) {
            for (PaymentCollectionPlanFactoring planFactoring : planFactoringList) {
                List<PayCollPlanFactoringAmountAllocation> amountAllocationList = planFactoring.getAmountAllocationList();
                if (CollectionUtil.isNotEmpty(amountAllocationList)) {
                    BigDecimal collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                            .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                    if (collAmountSum.compareTo(planFactoring.getAmount()) < 0) {
                        //只改计划，不再分配
                        planFactoring.setAmount(collAmountSum);
                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(planFactoring.getPlanDate(), BigDecimal.ZERO,
                                planFactoring, goodsAssign, 0));
                    }
                }
            }
        }
    }

    /**
     * 删除未分配的计划
     *
     * @param planFactoringList
     */
    private void deleteUnAssignList(List<PaymentCollectionPlanFactoring> planFactoringList,
                                    List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList, LedgerFundGoodsAssign goodsAssign) {
        if (CollectionUtil.isNotEmpty(planFactoringList)) {
            //退款的数据虽然没有实际收付但也不能删除
            planFactoringList.stream().filter(p -> CollectionUtil.isEmpty(p.getAmountAllocationList()) && p.getAmount().compareTo(BigDecimal.ZERO) > 0)
                    .forEach(p -> ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(p, goodsAssign, 0)));
        }
    }

    /**
     * 判断计划是否做过分配
     *
     * @param principalFactoringList
     * @return true:做过 false:未做过
     */
    private Boolean hasPrincipalAssign(List<PaymentCollectionPlanFactoring> principalFactoringList) {
        if (CollectionUtil.isEmpty(principalFactoringList)) {
            return false;
        }
        for (PaymentCollectionPlanFactoring planFactoring : principalFactoringList) {
            List<PayCollPlanFactoringAmountAllocation> amountAllocationList = planFactoring.getAmountAllocationList();
            if (amountAllocationList != null && amountAllocationList.size() > 0) {
                for (PayCollPlanFactoringAmountAllocation amountAllocation : amountAllocationList) {
                    if (amountAllocation.getActualAmount() != null && amountAllocation.getActualAmount().compareTo(BigDecimal.ZERO) > 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 本金计划分配
     *
     * @param assignAmount                  分配金额
     * @param principalFactoringList        本金收放款计划
     * @param ledgerDate
     * @param ledgerPlanFactoringAssignList
     * @param goodsAssignVo
     */
    private List<PaymentCollectionPlanFactoring> principalAssign(BigDecimal assignAmount, List<PaymentCollectionPlanFactoring> principalFactoringList,
                                                                 Date ledgerDate, List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList,
                                                                 LedgerFundGoodsAssign goodsAssignVo) {
        BigDecimal principalAssignAmount = assignAmount;
        if (CollectionUtil.isNotEmpty(principalFactoringList)) {
            //按计划日期升序排列
            Collections.sort(principalFactoringList, Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate));

            List<PaymentCollectionPlanFactoring> newPrincipalFactoringList = new ArrayList<>();
            for (PaymentCollectionPlanFactoring planFactoring : principalFactoringList) {
                if (!PaymentCollectionPlanStatusDict.ChildEnum.COMPLETED.getCode().equals(planFactoring.getStatus().getCode()) &&
                        !PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE_COMPLETED.getCode().equals(planFactoring.getStatus().getCode())
                        && principalAssignAmount.compareTo(BigDecimal.ZERO) > 0) {
                    if (principalAssignAmount.compareTo(planFactoring.getAmount()) >= 0) {
                        if (ledgerDate.before(planFactoring.getPlanDate())) {
                            //分账日期早于计划日期
                            planFactoring.setPlanDate(ledgerDate);
                        }
                        //修改一笔本金收款记录
                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, planFactoring.getAmount(),
                                planFactoring, goodsAssignVo, 1));

                        principalAssignAmount = principalAssignAmount.subtract(planFactoring.getAmount());
                    } else {
                        Date planDate = planFactoring.getPlanDate();
                        BigDecimal amount = planFactoring.getAmount();
                        if (ledgerDate.before(planFactoring.getPlanDate())) {
                            //分账日期早于计划日期
                            planFactoring.setPlanDate(ledgerDate);
                        }
                        planFactoring.setAmount(principalAssignAmount);
                        planFactoring.setActualCashFlow(principalAssignAmount);

                        //修改一笔本金收款记录
                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(ledgerDate, principalAssignAmount,
                                planFactoring, goodsAssignVo, 1));

                        //增加一笔剩余本金计划
                        BigDecimal surplusAmount = amount.subtract(principalAssignAmount);
                        PaymentCollectionPlanFactoring newPlanFactoring = new PaymentCollectionPlanFactoring();
                        newPlanFactoring.setPlanDate(planDate);
                        newPlanFactoring.setAmount(surplusAmount);
                        newPlanFactoring.setAmountType(planFactoring.getAmountType());
                        newPlanFactoring.setPaymentCollectionType(ConstantConversionUtil.PAY_COLL_COLLECTION);
                        newPrincipalFactoringList.add(newPlanFactoring);

                        //增加一笔本次本金收款记录
                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(planDate, surplusAmount, BigDecimal.ZERO,
                                IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode(), goodsAssignVo, 1));

                        principalAssignAmount = BigDecimal.ZERO;
                    }
                }
                newPrincipalFactoringList.add(planFactoring);
            }

            return newPrincipalFactoringList;
        }
        return null;
    }

    /**
     * 计算已分配的利息或管理费之和
     *
     * @param planFactoringList
     * @param dict
     * @return
     */
    private BigDecimal getInterestTotal(List<PaymentCollectionPlanFactoring> planFactoringList, Dictionary dict) {
        if (planFactoringList == null || planFactoringList.isEmpty()) {
            return BigDecimal.ZERO;
        }
        //获取所有类型为利息或管理费的收款数据
        List<PaymentCollectionPlanFactoring> filterList = planFactoringList.stream().filter(p -> p.getAmountType().getId().equals(dict.getId())
                && p.getPaymentCollectionType().equals(ConstantConversionUtil.PAY_COLL_COLLECTION)
                && (PaymentCollectionPlanStatusDict.ChildEnum.COMPLETED.getCode().equals(p.getStatus().getCode())
                || PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE_COMPLETED.getCode().equals(p.getStatus().getCode()))).collect(Collectors.toList());
        //获取所有二次延期时已收款的利息或管理费
        List<PaymentCollectionPlanFactoring> graceList = filterList.stream().filter(p -> p.getGraceType() != null && p.getGraceType().compareTo(1) > 0)
                .collect(Collectors.toList());

        BigDecimal interestTotal = BigDecimal.ZERO;
        if (graceList != null && graceList.size() > 0) {
            for (PaymentCollectionPlanFactoring planFactoring : graceList) {
                List<PayCollPlanFactoringAmountAllocation> allocationList = planFactoring.getAmountAllocationList();
                if (allocationList != null && allocationList.size() > 0) {
                    for (PayCollPlanFactoringAmountAllocation amountAllocation : allocationList) {
                        BigDecimal actualAmount = amountAllocation.getActualAmount() == null ? BigDecimal.ZERO : amountAllocation.getActualAmount();
                        interestTotal = interestTotal.add(actualAmount);
                    }
                }
            }
        }
        //获取所有已退回给供应商的的利息或管理费
        List<PaymentCollectionPlanFactoring> returnedList = filterList.stream().filter(p -> p.getAmount() != null && p.getAmount().compareTo(BigDecimal.ZERO) < 0)
                .collect(Collectors.toList());
        BigDecimal returnedTotal = BigDecimal.ZERO;
        if (returnedList != null && returnedList.size() > 0) {
            for (PaymentCollectionPlanFactoring planFactoring : returnedList) {
                BigDecimal amount = planFactoring.getAmount() == null ? BigDecimal.ZERO : planFactoring.getAmount();
                returnedTotal = returnedTotal.add(amount);
            }
        }
        return interestTotal.add(returnedTotal);
    }

    /**
     * 获取计划中实际已收的利息或管理费总计
     *
     * @param planFactoringList
     * @param dict
     * @return
     */
    private BigDecimal getActualAmountTotal(List<PaymentCollectionPlanFactoring> planFactoringList, Dictionary dict) {

        if (planFactoringList == null || planFactoringList.isEmpty()) {
            return BigDecimal.ZERO;
        }

        List<PaymentCollectionPlanFactoring> filterList = planFactoringList.stream().filter(p -> p.getAmountType().getId().equals(dict.getId())
                && p.getPaymentCollectionType().equals(ConstantConversionUtil.PAY_COLL_COLLECTION)).collect(Collectors.toList());
        if (filterList == null || filterList.isEmpty()) {
            return BigDecimal.ZERO;
        } else {
            //计算已经收的利息或管理费
            BigDecimal planAmountTotal = BigDecimal.ZERO;
            for (PaymentCollectionPlanFactoring planFactoring : filterList) {
                BigDecimal collAmountSum = BigDecimal.ZERO;
                List<PayCollPlanFactoringAmountAllocation> amountAllocationList = planFactoring.getAmountAllocationList();
                if (amountAllocationList != null && amountAllocationList.size() > 0) {
                    collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                            .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                } else {
                    //退款的数据没有分配记录、所有应该从计划金额里取值
                    if (planFactoring.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                        collAmountSum = planFactoring.getAmount();
                    }
                }
                planAmountTotal = planAmountTotal.add(collAmountSum);
            }
            return planAmountTotal;
        }
    }

    /**
     * 获取对应金额类型的收款计划
     *
     * @param planFactoringList
     * @return
     */
    private List<PaymentCollectionPlanFactoring> getFactoringByAmountType(List<PaymentCollectionPlanFactoring> planFactoringList,
                                                                          Dictionary amountTypeDict) {

        if (planFactoringList == null || planFactoringList.isEmpty()) {
            return null;
        }

        List<PaymentCollectionPlanFactoring> filterList = planFactoringList.stream().filter(p -> p.getAmountType().getId().equals(amountTypeDict.getId())
                && p.getPaymentCollectionType().equals(ConstantConversionUtil.PAY_COLL_COLLECTION)).collect(Collectors.toList());
        if (filterList == null) {
            return new ArrayList<>();
        }
        return filterList;
    }


    /**
     * 获取计划中计算应收的利息或管理费总计
     *
     * @param principalList
     * @param dict
     * @param goodsAssign
     * @param paymentCalculateVo
     * @return
     */
    private BigDecimal getAllocatedAmountByPlanFactoring(List<PaymentCollectionPlanFactoring> principalList, Dictionary dict,
                                                         LedgerFundGoodsAssign goodsAssign, PrePaymentCalculateVo paymentCalculateVo) {
        //计算需要分配掉的利息或管理费
        if (principalList == null || principalList.isEmpty()) {
            return BigDecimal.ZERO;
        }

        //根据已收日期和金额生成新的计划
        List<PaymentCollectionPlanFactoring> newPrincipalList = new ArrayList<>();
        principalList.stream().forEach(p -> {
            List<PayCollPlanFactoringAmountAllocation> amountAllocationList = p.getAmountAllocationList();
            if (CollectionUtil.isNotEmpty(amountAllocationList)) {
                amountAllocationList.stream().forEach(a -> {
                    PaymentCollectionPlanFactoring factoring = new PaymentCollectionPlanFactoring();
                    if (a.getActualDate().before(p.getPlanDate())) {
                        factoring.setPlanDate(a.getActualDate());
                    } else {
                        factoring.setPlanDate(p.getPlanDate());
                    }
                    factoring.setAmount(a.getActualAmount());
                    newPrincipalList.add(factoring);
                });
            } else {
                PaymentCollectionPlanFactoring factoring = new PaymentCollectionPlanFactoring();
                factoring.setPlanDate(p.getPlanDate());
                factoring.setAmount(p.getAmount());
                newPrincipalList.add(factoring);
            }
        });

        //planDate 相同的需要合并处理
        List<PaymentCollectionPlanFactoring> mergeList = new ArrayList<>();
        newPrincipalList.stream().collect(Collectors.groupingBy(p -> DateUtil.beginOfDay(p.getPlanDate()), Collectors.toList())).forEach((id, transfer) -> {
            transfer.stream().reduce((a, b) -> new PaymentCollectionPlanFactoring(a.getPlanDate(), a.getAmount().add(b.getAmount()))).ifPresent(mergeList::add);
        });

        Collections.sort(mergeList, Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate));

        Date loanDate = goodsAssign.getLoanDate();
        BigDecimal surplusPrincipal = goodsAssign.getLoanAmount();

        BigDecimal allocatedAmountTotal = BigDecimal.ZERO;
        if (mergeList != null && mergeList.size() > 0) {
            Date start;
            Date end;
            BigDecimal allocatedAmount;
            for (int i = 0; i < mergeList.size(); i++) {
                if (i == 0) {
                    start = loanDate;
                    end = mergeList.get(i).getPlanDate();
                    allocatedAmount = calculateAssignInterest(surplusPrincipal, start, end, true, paymentCalculateVo, dict.getCode());
                } else {
                    start = mergeList.get(i - 1).getPlanDate();
                    end = mergeList.get(i).getPlanDate();
                    allocatedAmount = calculateAssignInterest(surplusPrincipal, start, end, false, paymentCalculateVo, dict.getCode());
                }
                surplusPrincipal = surplusPrincipal.subtract(mergeList.get(i).getAmount());
                allocatedAmountTotal = allocatedAmountTotal.add(allocatedAmount);
            }
        }
        return allocatedAmountTotal;
    }

    /**
     * 获取最后一期收款计划
     *
     * @param planFactoringList 计划
     * @param dict              金额类型字典项
     * @return
     */
    private PaymentCollectionPlanFactoring getLastPrincipalFactoring(List<PaymentCollectionPlanFactoring> planFactoringList, Dictionary dict) {
        if (planFactoringList == null || planFactoringList.isEmpty()) {
            throw new BusinessException(CodeUtil.FAIL, "收放款计划不能为空");
        }
        List<PaymentCollectionPlanFactoring> filterList = planFactoringList.stream().filter(p -> p.getAmountType().getId().equals(dict.getId())
                && p.getPaymentCollectionType().equals(ConstantConversionUtil.PAY_COLL_COLLECTION)).collect(Collectors.toList());
        if (filterList != null && filterList.size() > 0) {
            Date maxDate = filterList.stream().filter(p -> p.getPlanDate() != null).map(PaymentCollectionPlanFactoring::getPlanDate).distinct()
                    .max(DateUtil::compare).get();
            return filterList.stream().filter(p -> p.getPlanDate().equals(maxDate)).collect(Collectors.toList()).get(0);
        } else {
            return null;
        }
    }

    /**
     * 计算分配的利息或保证金
     *
     * @param amount
     * @param startDate
     * @param endDate
     * @param flag               判断是否记头 true:记头,false:不记头
     * @param paymentCalculateVo
     * @param amountType
     * @
     */
    private BigDecimal calculateAssignInterest(BigDecimal amount, Date startDate, Date endDate, Boolean flag,
                                               PrePaymentCalculateVo paymentCalculateVo, String amountType) {

        //判断是否计算投放日
        Integer interestCalculate = paymentCalculateVo.getInterestCalculate();
        long between = 0;
        if (interestCalculate == 1) {
            if (flag) {
                between = DateUtil.betweenDay(startDate, endDate, true) + 1;
            } else {
                between = DateUtil.betweenDay(startDate, endDate, true);
            }
        } else if (interestCalculate == 0) {
            between = DateUtil.betweenDay(startDate, endDate, true);
        }

        Double financingRate = paymentCalculateVo.getFinancingRate();
        Double managementFeeRatio = paymentCalculateVo.getManagementFeeRatio();
        BigDecimal rate = BigDecimal.ZERO;
        if (amountType.equals(IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode())) {
            rate = BigDecimal.valueOf(managementFeeRatio);
        } else if (amountType.equals(IncomeExpenditureTypeDict.ChildEnum.INTEREST.getCode())) {
            rate = BigDecimal.valueOf(financingRate);
        }

        //计算管理费或利息
        return amount.multiply(BigDecimal.valueOf(between))
                .multiply(rate).divide(new BigDecimal(360), 2, RoundingMode.HALF_UP);
    }

    /**
     * 添加对应sop收放款计划变更数据
     *
     * @param ledgerDate          入账日期
     * @param currentAssignAmount 本次分配金额
     * @param planFactoring       对应sop收放款计划
     * @param goodsAssign         货物分配信息
     * @param isPrincipal         是否本金类型
     * @return
     */
    private LedgerPlanFactoringAssign addPlanFactoringUpdateAssign(Date ledgerDate, BigDecimal currentAssignAmount,
                                                                   PaymentCollectionPlanFactoring planFactoring,
                                                                   LedgerFundGoodsAssign goodsAssign, Integer isPrincipal) {
        LedgerPlanFactoringAssign planFactoringAssign = new LedgerPlanFactoringAssign();
        planFactoringAssign.setPlanDate(planFactoring.getPlanDate());
        planFactoringAssign.setActualDate(ledgerDate);
        planFactoringAssign.setPlanAmount(planFactoring.getAmount());
        planFactoringAssign.setActualAmount(currentAssignAmount);
        planFactoringAssign.setPlanFactoringId(planFactoring.getId());
        planFactoringAssign.setAmountType(dictService.get(planFactoring.getAmountType().getId()).getCode());
        planFactoringAssign.setPrincipal(isPrincipal);
        planFactoringAssign.setSopAccountsReceivableId(goodsAssign.getSopAccountsReceivableId());
        planFactoringAssign.setBillingFactoringBusinessLoanRecordId(goodsAssign.getBillingFactoringBusinessLoanRecordId());
        planFactoringAssign.setPayCollBasicId(goodsAssign.getPayCollBasicId());
        planFactoringAssign.setDeleteFlag(false);
        return planFactoringAssign;
    }

    /**
     * 添加对应sop收放款计划删除数据
     *
     * @param planFactoring 收放款计划
     * @param goodsAssign   货物分配信息
     * @param isPrincipal   是否为本金分配
     * @return
     */
    private LedgerPlanFactoringAssign addPlanFactoringDeleteAssign(PaymentCollectionPlanFactoring planFactoring,
                                                                   LedgerFundGoodsAssign goodsAssign, Integer isPrincipal) {
        LedgerPlanFactoringAssign planFactoringAssign = new LedgerPlanFactoringAssign();
        planFactoringAssign.setPlanFactoringId(planFactoring.getId());
        planFactoringAssign.setPrincipal(isPrincipal);
        planFactoringAssign.setSopAccountsReceivableId(goodsAssign.getSopAccountsReceivableId());
        planFactoringAssign.setBillingFactoringBusinessLoanRecordId(goodsAssign.getBillingFactoringBusinessLoanRecordId());
        planFactoringAssign.setPayCollBasicId(goodsAssign.getPayCollBasicId());
        planFactoringAssign.setDeleteFlag(true);
        return planFactoringAssign;
    }

    /**
     * 添加对应sop收放款计划新增数据
     *
     * @param ledgerDate   入账日期
     * @param planAmount   计划金额
     * @param actualAmount 实际金额
     * @param amountType   金额类型
     * @param goodsAssign  货物分配信息
     * @param isPrincipal  是否为本金分配
     * @return
     */
    private LedgerPlanFactoringAssign addPlanFactoringInsertAssign(Date ledgerDate, BigDecimal
            planAmount, BigDecimal actualAmount, String amountType, LedgerFundGoodsAssign goodsAssign, Integer isPrincipal) {
        LedgerPlanFactoringAssign planFactoringAssign = new LedgerPlanFactoringAssign();
        planFactoringAssign.setPlanAmount(planAmount);
        planFactoringAssign.setActualAmount(actualAmount);
        planFactoringAssign.setActualDate(ledgerDate);
        planFactoringAssign.setAmountType(amountType);
        planFactoringAssign.setPrincipal(isPrincipal);
        planFactoringAssign.setSopAccountsReceivableId(goodsAssign.getSopAccountsReceivableId());
        planFactoringAssign.setBillingFactoringBusinessLoanRecordId(goodsAssign.getBillingFactoringBusinessLoanRecordId());
        planFactoringAssign.setPayCollBasicId(goodsAssign.getPayCollBasicId());
        planFactoringAssign.setDeleteFlag(false);
        return planFactoringAssign;
    }

    /**
     * 计算分配的金额
     *
     * @param assignAmount
     * @param factoring
     * @return
     */
    private BigDecimal assignAmount(BigDecimal assignAmount, PaymentCollectionPlanFactoring factoring) {
        //先获取已收款金额
        List<PayCollPlanFactoringAmountAllocation> amountAllocationList = factoring.getAmountAllocationList();
        BigDecimal collAmountSum = BigDecimal.ZERO;
        if (amountAllocationList != null && amountAllocationList.size() > 0) {
            collAmountSum = amountAllocationList.stream().filter(a -> a.getActualAmount() != null)
                    .map(PayCollPlanFactoringAmountAllocation::getActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        //剩余未分配
        BigDecimal surplus = factoring.getAmount().subtract(collAmountSum);

        //该笔收放款本次分配金额
        BigDecimal currentAssignAmount;
        if (assignAmount.compareTo(surplus) >= 0) {
            currentAssignAmount = surplus;
        } else {
            currentAssignAmount = assignAmount;
        }
        return currentAssignAmount;
    }

    @Override
    public List<SupplierListVo> getSupplierList(Long id) {
        LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountBasicInfoService.getById(id);
        List<SupplierListVo> supplierList = new ArrayList<>();
//        if (ledgerAccountBasicInfo != null && ledgerAccountBasicInfo.getBusinessNumber() != null) {
//            supplierList = ledgerAccountBasicInfoService.getSupplierList(ledgerAccountBasicInfo.getBusinessNumber());
//        }
        return supplierList;
    }
}
