package com.gci.boot.modules.finance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.modules.finance.entity.BaseFinance;
import com.gci.boot.modules.finance.entity.FinanceVehicleCost;
import com.gci.boot.modules.finance.entity.MeasureResult;
import com.gci.boot.modules.finance.entity.VehicleCost;
import com.gci.boot.modules.finance.mapper.BaseFinanceMapper;
import com.gci.boot.modules.finance.service.IBaseFinanceService;
import com.gci.boot.modules.finance.service.IFinanceVehicleCostService;
import com.gci.boot.modules.finance.service.IMeasureResultService;
import com.gci.boot.modules.finance.vo.*;
import com.gci.boot.modules.vehicles.vo.RepairDetailVO;
import com.gci.boot.modules.vehicles.vo.RepairInfoListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BaseFinanceServiceImpl extends ServiceImpl<BaseFinanceMapper, BaseFinance> implements IBaseFinanceService {

    @Autowired
    private IFinanceVehicleCostService financeVehicleCostService;
    @Autowired
    private IMeasureResultService measureResultService;
    @Autowired
    private BaseFinanceMapper baseFinanceMapper;

    @Override
    public CalculateResultObjectVO calculate(BaseFinance baseFinance) {
        CalculateResultObjectVO object = new CalculateResultObjectVO();
        //融资费用--中间计算
        List<FinanceItemVO> financeList = calculateFinancing(baseFinance);
        //租金
        FinanceItemVO rentVO =  calculateRent(baseFinance.getVehicleCostList());
        //管理、运维、保险费用
        List<FinanceItemVO> manageCostList = calculateManage(baseFinance);
        //收入与税金
        FinanceItemVO incomeAndTax = calculateIncomeAndTax(baseFinance,rentVO,manageCostList);
        //成本与利润
        List<FinanceItemVO> costAndProfitList = calculateCostandProfit(baseFinance,rentVO,manageCostList,incomeAndTax,financeList);
        //结果
        CalculateResultVO resultVO = calculateResult(baseFinance,rentVO,incomeAndTax,manageCostList,costAndProfitList,financeList);
        object.setResult(Collections.singletonList(resultVO));
        object.setCostAndProfitList(costAndProfitList);
        object.setIncomeAndTax(Collections.singletonList(incomeAndTax));
        object.setManageCostList(manageCostList);
        object.setRentalIncome(Collections.singletonList(rentVO));
        return object;
    }

    @Override
    public FinanceItemVO calculateRent(List<FinanceVehicleCost> vehicleCostList) {
        //月租金*数量*12
        FinanceItemVO itemVO = new FinanceItemVO();
        itemVO.setItemName("租金收入");
        BigDecimal oneYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getOneYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal twoYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getTwoYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal threeYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getThreeYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal fourYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getFourYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal fiveYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getFiveYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal sixYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getSixYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal sevenYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getSevenYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal eightYearSum = vehicleCostList.stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getEightYear().multiply(new BigDecimal(y.getQuantity()*12))); }, BigDecimal::add);
        BigDecimal total = oneYearSum.add(twoYearSum).add(threeYearSum).add(fourYearSum)
                .add(fiveYearSum).add(sixYearSum).add(sevenYearSum).add(eightYearSum);

        itemVO.setOneYear(oneYearSum);
        itemVO.setTwoYear(twoYearSum);
        itemVO.setThreeYear(threeYearSum);
        itemVO.setFourYear(fourYearSum);
        itemVO.setFiveYear(fiveYearSum);
        itemVO.setSixYear(sixYearSum);
        itemVO.setSevenYear(sevenYearSum);
        itemVO.setEightYear(eightYearSum);
        itemVO.setTotal(total);
        log.info("计算租金 {} : ",itemVO);
        return itemVO;
    }

    @Override
    public List<FinanceItemVO> calculateManage(BaseFinance baseFinance) {
        /**
         * 管理费用分担.. 单价*数量*管理费分担比例/100
         * 保养费用.. 保养*数量
         * 维修费用.. 维修*数量
         * 上牌保险费用..  第一年：上牌费用*数量 + 保险*数量  年审*数量 + 保险*数量
         * 不可预计成本..
         */
        List<FinanceItemVO> result = new ArrayList<>();
        FinanceItemVO manageItem = new FinanceItemVO();
        manageItem.setItemName("管理费用分担");
        FinanceItemVO upkeepItem = new FinanceItemVO();
        upkeepItem.setItemName("保养费用");
        FinanceItemVO repairItem = new FinanceItemVO();
        repairItem.setItemName("维修费用");
        FinanceItemVO insuranceItem = new FinanceItemVO();
        insuranceItem.setItemName("上牌保险费用");
        FinanceItemVO unknownItem = new FinanceItemVO();
        unknownItem.setItemName("不可预计成本");
        FinanceItemVO totalItem = new FinanceItemVO();
        totalItem.setItemName("合计");
        if(1 <= baseFinance.getYearLimit()){
            BigDecimal manageSum = baseFinance.getVehicleCostList().stream()
                    .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add);
            manageItem.setOneYear(manageSum.multiply(baseFinance.getOverheadSharing()).divide(new BigDecimal(100),4, RoundingMode.HALF_UP));

            BigDecimal upkeepSum = baseFinance.getVehicleCostList().stream()
                    .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUpkeep().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add);
            upkeepItem.setOneYear(upkeepSum);

            BigDecimal repairSum = baseFinance.getVehicleCostList().stream()
                    .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getRepair().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add);
            repairItem.setOneYear(repairSum);

            BigDecimal insuranceSum = baseFinance.getVehicleCostList().stream()
                    .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getPurchaseTax().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add)
                    .add(baseFinance.getVehicleCostList().stream()
                            .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getInsurance().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add));
            insuranceItem.setOneYear(insuranceSum);

            unknownItem.setOneYear(BigDecimal.ZERO);
        }
        if( 2 <= baseFinance.getYearLimit()){
            manageItem.setTwoYear(manageItem.getOneYear());
            upkeepItem.setTwoYear(upkeepItem.getOneYear());
            repairItem.setTwoYear(repairItem.getOneYear());
            unknownItem.setTwoYear(unknownItem.getOneYear());

            BigDecimal insuranceSum = baseFinance.getVehicleCostList().stream()
                    .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getAnnualAudit().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add)
                    .add(baseFinance.getVehicleCostList().stream()
                            .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getInsurance().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add));
            insuranceItem.setTwoYear(insuranceSum);
        }
        if(3 <= baseFinance.getYearLimit()){
            manageItem.setThreeYear(manageItem.getOneYear());
            upkeepItem.setThreeYear(upkeepItem.getOneYear());
            repairItem.setThreeYear(repairItem.getOneYear());
            insuranceItem.setThreeYear(insuranceItem.getTwoYear());
            unknownItem.setThreeYear(unknownItem.getOneYear());
        }
        if(4 <= baseFinance.getYearLimit()){
            manageItem.setFourYear(manageItem.getOneYear());
            upkeepItem.setFourYear(upkeepItem.getOneYear());
            repairItem.setFourYear(repairItem.getOneYear());
            insuranceItem.setFourYear(insuranceItem.getTwoYear());
            unknownItem.setFourYear(unknownItem.getOneYear());
        }
        if(5 <= baseFinance.getYearLimit()){
            manageItem.setFiveYear(manageItem.getOneYear());
            upkeepItem.setFiveYear(upkeepItem.getOneYear());
            repairItem.setFiveYear(repairItem.getOneYear());
            insuranceItem.setFiveYear(insuranceItem.getTwoYear());
            unknownItem.setFiveYear(unknownItem.getOneYear());
        }
        if( 6 <= baseFinance.getYearLimit()){
            manageItem.setSixYear(manageItem.getOneYear());
            upkeepItem.setSixYear(upkeepItem.getOneYear());
            repairItem.setSixYear(repairItem.getOneYear());
            insuranceItem.setSixYear(insuranceItem.getTwoYear());
            unknownItem.setSixYear(unknownItem.getOneYear());
        }
        if(7 <= baseFinance.getYearLimit()){
            manageItem.setSevenYear(manageItem.getOneYear());
            upkeepItem.setSevenYear(upkeepItem.getOneYear());
            repairItem.setSevenYear(repairItem.getOneYear());
            insuranceItem.setSevenYear(insuranceItem.getTwoYear());
            unknownItem.setSevenYear(unknownItem.getOneYear());
        }
        if(8 <= baseFinance.getYearLimit()){
            manageItem.setEightYear(manageItem.getOneYear());
            upkeepItem.setEightYear(upkeepItem.getOneYear());
            repairItem.setEightYear(repairItem.getOneYear());
            insuranceItem.setEightYear(insuranceItem.getTwoYear());
            unknownItem.setEightYear(unknownItem.getOneYear());
        }
        manageItem.setTotal(manageItem.getOneYear().add(manageItem.getTwoYear()).add(manageItem.getThreeYear()).add(manageItem.getFourYear())
                .add(manageItem.getFiveYear()).add(manageItem.getSixYear()).add(manageItem.getSevenYear()).add(manageItem.getEightYear()));
        upkeepItem.setTotal(upkeepItem.getOneYear().add(upkeepItem.getTwoYear()).add(upkeepItem.getThreeYear()).add(upkeepItem.getFourYear())
                .add(upkeepItem.getFiveYear()).add(upkeepItem.getSixYear()).add(upkeepItem.getSevenYear()).add(upkeepItem.getEightYear()));
        repairItem.setTotal(repairItem.getOneYear().add(repairItem.getTwoYear()).add(repairItem.getThreeYear()).add(repairItem.getFourYear())
                .add(repairItem.getFiveYear()).add(repairItem.getSixYear()).add(repairItem.getSevenYear()).add(repairItem.getEightYear()));
        insuranceItem.setTotal(insuranceItem.getOneYear().add(insuranceItem.getTwoYear()).add(insuranceItem.getThreeYear()).add(insuranceItem.getFourYear())
                .add(insuranceItem.getFiveYear()).add(insuranceItem.getSixYear()).add(insuranceItem.getSevenYear()).add(insuranceItem.getEightYear()));
        unknownItem.setTotal(unknownItem.getOneYear().add(unknownItem.getTwoYear()).add(unknownItem.getThreeYear()).add(unknownItem.getFourYear())
                .add(unknownItem.getFiveYear()).add(unknownItem.getSixYear()).add(unknownItem.getSevenYear()).add(unknownItem.getEightYear()));

        result.add(manageItem);
        result.add(upkeepItem);
        result.add(repairItem);
        result.add(insuranceItem);
        result.add(unknownItem);

        BigDecimal oneYearSum = result.stream().map(FinanceItemVO::getOneYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal twoYearSum = result.stream().map(FinanceItemVO::getTwoYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal threeYearSum = result.stream().map(FinanceItemVO::getThreeYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal fourYearSum = result.stream().map(FinanceItemVO::getFourYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal fiveYearSum = result.stream().map(FinanceItemVO::getFiveYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal sixYearSum = result.stream().map(FinanceItemVO::getSixYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal sevenYearSum = result.stream().map(FinanceItemVO::getSevenYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal eightYearSum = result.stream().map(FinanceItemVO::getEightYear ).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalSum = result.stream().map(FinanceItemVO::getTotal ).reduce(BigDecimal.ZERO, BigDecimal::add);
        totalItem.setOneYear(oneYearSum);
        totalItem.setTwoYear(twoYearSum);
        totalItem.setThreeYear(threeYearSum);
        totalItem.setFourYear(fourYearSum);
        totalItem.setFiveYear(fiveYearSum);
        totalItem.setSixYear(sixYearSum);
        totalItem.setSevenYear(sevenYearSum);
        totalItem.setEightYear(eightYearSum);
        totalItem.setTotal(totalSum);

        result.add(totalItem);
        log.info("计算管理费用 {} : ",result);
        return result;
    }

    @Override
    public FinanceItemVO calculateIncomeAndTax(BaseFinance baseFinance,FinanceItemVO rentVO,List<FinanceItemVO> manageList) {
        List<FinanceItemVO> result = new ArrayList<>();
        FinanceItemVO paidVatAndSubjoinItem = new FinanceItemVO();
        paidVatAndSubjoinItem.setItemName("实缴增值税及附加");
        FinanceItemVO inputTaxItem = new FinanceItemVO();
        inputTaxItem.setItemName("进项税");
        FinanceItemVO deductibleItem = new FinanceItemVO();
        deductibleItem.setItemName("可抵扣(余)");
        FinanceItemVO addedTaxItem = new FinanceItemVO();
        addedTaxItem.setItemName("增值税");
        //增值税 租金/1.13*0.13
        addedTaxItem.setOneYear(rentVO.getOneYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setTwoYear(rentVO.getTwoYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setThreeYear(rentVO.getThreeYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setFourYear(rentVO.getFourYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setFiveYear(rentVO.getFiveYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setSixYear(rentVO.getSixYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setSevenYear(rentVO.getSevenYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setEightYear(rentVO.getEightYear().multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        addedTaxItem.setTotal(addedTaxItem.getOneYear().add(addedTaxItem.getTwoYear()).add(addedTaxItem.getThreeYear()).add(addedTaxItem.getFourYear())
                .add(addedTaxItem.getFiveYear()).add(addedTaxItem.getSixYear()).add(addedTaxItem.getSevenYear()).add(addedTaxItem.getEightYear()));
        result.add(addedTaxItem);
        //进项税 (保养+维修+上牌)/1.06*0.06
        manageList = manageList.stream().filter(item->"保养费用、维修费用、上牌保险费用".contains(item.getItemName())).collect(Collectors.toList());
        inputTaxItem.setOneYear(manageList.stream().map(FinanceItemVO::getOneYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setTwoYear(manageList.stream().map(FinanceItemVO::getTwoYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setThreeYear(manageList.stream().map(FinanceItemVO::getThreeYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setFourYear(manageList.stream().map(FinanceItemVO::getFourYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setFiveYear(manageList.stream().map(FinanceItemVO::getFiveYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setSixYear(manageList.stream().map(FinanceItemVO::getSixYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setSevenYear(manageList.stream().map(FinanceItemVO::getSevenYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        inputTaxItem.setEightYear(manageList.stream().map(FinanceItemVO::getEightYear ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(new BigDecimal(0.06)).divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP));
        //购车费用
        BigDecimal carCostSum = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add);
        inputTaxItem.setTotal(carCostSum.multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        result.add(inputTaxItem);

        //可抵扣(余)
        deductibleItem.setTotal(carCostSum.multiply(new BigDecimal(0.13)).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP));
        deductibleItem.setOneYear(inputTaxItem.getTotal().add(inputTaxItem.getOneYear()).subtract(addedTaxItem.getOneYear()));
        deductibleItem.setTwoYear(deductibleItem.getOneYear().add(inputTaxItem.getTwoYear()).subtract(addedTaxItem.getTwoYear()));
        deductibleItem.setThreeYear(deductibleItem.getTwoYear().add(inputTaxItem.getThreeYear()).subtract(addedTaxItem.getThreeYear()));
        deductibleItem.setFourYear(deductibleItem.getThreeYear().add(inputTaxItem.getFourYear()).subtract(addedTaxItem.getFourYear()));
        deductibleItem.setFiveYear(deductibleItem.getFourYear().add(inputTaxItem.getFiveYear()).subtract(addedTaxItem.getFiveYear()));
        deductibleItem.setSixYear(deductibleItem.getFiveYear().add(inputTaxItem.getSixYear()).subtract(addedTaxItem.getSixYear()));
        deductibleItem.setSevenYear(deductibleItem.getSixYear().add(inputTaxItem.getSevenYear()).subtract(addedTaxItem.getSevenYear()));
        deductibleItem.setEightYear(deductibleItem.getSevenYear().add(inputTaxItem.getEightYear()).subtract(addedTaxItem.getEightYear()));
        result.add(deductibleItem);

        //实缴增值税及附加
        paidVatAndSubjoinItem.setOneYear(deductibleItem.getOneYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getOneYear().subtract(addedTaxItem.getOneYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setTwoYear(deductibleItem.getTwoYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getTwoYear().subtract(addedTaxItem.getTwoYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setThreeYear(deductibleItem.getThreeYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getThreeYear().subtract(addedTaxItem.getThreeYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setFourYear(deductibleItem.getFourYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getFourYear().subtract(addedTaxItem.getFourYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setFiveYear(deductibleItem.getFiveYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getFiveYear().subtract(addedTaxItem.getFiveYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setSixYear(deductibleItem.getSixYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getSixYear().subtract(addedTaxItem.getSixYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setSevenYear(deductibleItem.getSevenYear().compareTo(BigDecimal.valueOf(0)) < 0
                ? (inputTaxItem.getSevenYear().subtract(addedTaxItem.getSevenYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setEightYear(deductibleItem.getEightYear().compareTo(BigDecimal.valueOf(0)) < 0
                ?(inputTaxItem.getEightYear().subtract(addedTaxItem.getEightYear())).multiply(new BigDecimal(-1.12)).setScale(4, RoundingMode.HALF_UP)
                : BigDecimal.ZERO);
        paidVatAndSubjoinItem.setTotal(paidVatAndSubjoinItem.getOneYear().add(paidVatAndSubjoinItem.getTwoYear()).add(paidVatAndSubjoinItem.getThreeYear()).add(paidVatAndSubjoinItem.getFourYear())
                .add(paidVatAndSubjoinItem.getFiveYear()).add(paidVatAndSubjoinItem.getSixYear()).add(paidVatAndSubjoinItem.getSevenYear()).add(paidVatAndSubjoinItem.getEightYear()));
        result.add(paidVatAndSubjoinItem);
        log.info("计算收入与税金 {} : ",result);
        return paidVatAndSubjoinItem;
    }

    @Override
    public List<FinanceItemVO> calculateFinancing(BaseFinance baseFinance) {
        List<FinanceItemVO> result = new ArrayList<>();
        FinanceItemVO originalPrincipalItem = new FinanceItemVO();
        originalPrincipalItem.setItemName("期初融资本金收入");
        FinanceItemVO principalExpendItem = new FinanceItemVO();
        principalExpendItem.setItemName("融资本金支出");
        FinanceItemVO remainCostItem = new FinanceItemVO();
        remainCostItem.setItemName("融资本金余额");
        FinanceItemVO interestCostItem = new FinanceItemVO();
        interestCostItem.setItemName("利息费用");
        FinanceItemVO interestTotalItem = new FinanceItemVO();
        interestTotalItem.setItemName("利息费用累计");
        //购车费用
        BigDecimal carCostSum = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice().multiply(new BigDecimal(y.getQuantity()))); }, BigDecimal::add);
        //期初融资本金收入
        originalPrincipalItem.setOneYear(baseFinance.getFinancingRatio().divide(new BigDecimal(100)).multiply(carCostSum));
        originalPrincipalItem.setTotal(originalPrincipalItem.getOneYear());
        result.add(originalPrincipalItem);
        //融资本金支出
        //目前融资为五年
        int year = 5;
        if(year > baseFinance.getYearLimit()){
            year = baseFinance.getYearLimit();
        }
        BigDecimal eachYearExpend = originalPrincipalItem.getTotal().divide(new BigDecimal(year),4, RoundingMode.HALF_UP);
        if(1 <= year){
            principalExpendItem.setOneYear(eachYearExpend);
        }
        if(2 <= year){
            principalExpendItem.setTwoYear(eachYearExpend);
        }
        if(3 <= year){
            principalExpendItem.setThreeYear(eachYearExpend);
        }
        if(4 <= year){
            principalExpendItem.setFourYear(eachYearExpend);
        }
        if(5 <= year){
            principalExpendItem.setFiveYear(eachYearExpend);
        }
        if(6 <= year){
            principalExpendItem.setSixYear(eachYearExpend);
        }
        if(7 <= year){
            principalExpendItem.setSevenYear(eachYearExpend);
        }
        if(8 <= year){
            principalExpendItem.setEightYear(eachYearExpend);
        }
        principalExpendItem.setTotal(principalExpendItem.getOneYear().add(principalExpendItem.getTwoYear()).add(principalExpendItem.getThreeYear()).add(principalExpendItem.getFourYear())
                .add(principalExpendItem.getFiveYear()).add(principalExpendItem.getSixYear()).add(principalExpendItem.getSevenYear()).add(principalExpendItem.getEightYear()));
        result.add(principalExpendItem);
        //融资本金余额
        if(1 <= year){
            remainCostItem.setOneYear(originalPrincipalItem.getOneYear().subtract(principalExpendItem.getOneYear()));
        }
        if(2 <= year){
            remainCostItem.setTwoYear(remainCostItem.getOneYear().subtract(principalExpendItem.getTwoYear()));
        }
        if(3 <= year){
            remainCostItem.setThreeYear(remainCostItem.getTwoYear().subtract(principalExpendItem.getThreeYear()));
        }
        if(4 <= year){
            remainCostItem.setFourYear(remainCostItem.getThreeYear().subtract(principalExpendItem.getFourYear()));
        }
        if(5 <= year){
            remainCostItem.setFiveYear(remainCostItem.getFourYear().subtract(principalExpendItem.getFiveYear()));
        }
        if(6 <= year){
            remainCostItem.setSixYear(remainCostItem.getFiveYear().subtract(principalExpendItem.getSixYear()));
        }
        if(7 <= year){
            remainCostItem.setSevenYear(remainCostItem.getSixYear().subtract(principalExpendItem.getSevenYear()));
        }
        if(8 <= year){
            remainCostItem.setSevenYear(remainCostItem.getSevenYear().subtract(principalExpendItem.getEightYear()));
        }
//        remainCostItem.setTotal(remainCostItem.getOneYear().add(remainCostItem.getTwoYear()).add(remainCostItem.getThreeYear()).add(remainCostItem.getFourYear())
//                .add(remainCostItem.getFiveYear()).add(remainCostItem.getSixYear()).add(remainCostItem.getSevenYear()).add(remainCostItem.getEightYear()));
        result.add(remainCostItem);
        //利息费用
        if(1 <= year){
            interestCostItem.setOneYear((originalPrincipalItem.getOneYear().add(remainCostItem.getOneYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(2 <= year){
            interestCostItem.setTwoYear((remainCostItem.getOneYear().add(remainCostItem.getTwoYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(3 <= year){
            interestCostItem.setThreeYear((remainCostItem.getTwoYear().add(remainCostItem.getThreeYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(4 <= year){
            interestCostItem.setFourYear((remainCostItem.getThreeYear().add(remainCostItem.getFourYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(5 <= year){
            interestCostItem.setFiveYear((remainCostItem.getFourYear().add(remainCostItem.getFiveYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(6 <= year){
            interestCostItem.setSixYear((remainCostItem.getFiveYear().add(remainCostItem.getSixYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(7 <=year){
            interestCostItem.setSevenYear((remainCostItem.getSixYear().add(remainCostItem.getSevenYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        if(8 <= year){
            interestCostItem.setSevenYear((remainCostItem.getSevenYear().add(remainCostItem.getEightYear()))
                    .multiply(baseFinance.getFinancingRate()).multiply(new BigDecimal(0.005)).setScale(4, RoundingMode.HALF_UP));
        }
        interestCostItem.setTotal(interestCostItem.getOneYear().add(interestCostItem.getTwoYear()).add(interestCostItem.getThreeYear()).add(interestCostItem.getFourYear())
                .add(interestCostItem.getFiveYear()).add(interestCostItem.getSixYear()).add(interestCostItem.getSevenYear()).add(interestCostItem.getEightYear()));
        result.add(interestCostItem);
        //利息费用累计
        if(1 <= year){
            interestTotalItem.setOneYear(interestCostItem.getOneYear());
        }
        if(2 <= year){
            interestTotalItem.setTwoYear(interestTotalItem.getOneYear().add(interestCostItem.getTwoYear()));
        }
        if(3 <= year){
            interestTotalItem.setThreeYear(interestTotalItem.getTwoYear().add(interestCostItem.getThreeYear()));
        }
        if(4 <= year){
            interestTotalItem.setFourYear(interestTotalItem.getThreeYear().add(interestCostItem.getFourYear()));
        }
        if(5 <= year){
            interestTotalItem.setFiveYear(interestTotalItem.getFourYear().add(interestCostItem.getFiveYear()));
        }
        if(6 <= year){
            interestTotalItem.setSixYear(interestTotalItem.getFiveYear().add(interestCostItem.getSixYear()));
        }
        if(7 <= year){
            interestTotalItem.setSevenYear(interestTotalItem.getSixYear().add(interestCostItem.getSevenYear()));
        }
        if(8 <= year){
            interestTotalItem.setSevenYear(interestTotalItem.getSevenYear().add(interestCostItem.getEightYear()));
        }
        interestTotalItem.setTotal(interestTotalItem.getOneYear().add(interestTotalItem.getTwoYear()).add(interestTotalItem.getThreeYear()).add(interestTotalItem.getFourYear())
                .add(interestTotalItem.getFiveYear()).add(interestTotalItem.getSixYear()).add(interestTotalItem.getSevenYear()).add(interestTotalItem.getEightYear()));
        result.add(interestTotalItem);
        log.info("计算融资费用 {} : ",result);
        return result;
    }

    @Override
    public List<FinanceItemVO> calculateCostandProfit(BaseFinance baseFinance,FinanceItemVO rentVO, List<FinanceItemVO> manageList,
                                                      FinanceItemVO incomeAndTaxVO,List<FinanceItemVO> financeList) {
        List<FinanceItemVO> result = new ArrayList<>();
        FinanceItemVO incomeTaxItem = new FinanceItemVO();
        incomeTaxItem.setItemName("所得税");
        FinanceItemVO netProfitItem = new FinanceItemVO();
        netProfitItem.setItemName("净利润");
        FinanceItemVO totalProfitItem = new FinanceItemVO();
        totalProfitItem.setItemName("利润总额");

        //利润总额 A8/1.13-C3*R3/S3/1.13-B18/1.06-B32-D22
        //年租金/1.13 - 车单价*数量/租赁年限/1.13 - 年管理合计/1.06 - 年利息费用 - 实缴增值税及附加
        //年管理合计
        FinanceItemVO manageVO = manageList.stream().filter(item -> "合计".equals(item.getItemName())).findFirst().get();
        //年利息费用
        FinanceItemVO financeVO = financeList.stream().filter(item -> "利息费用".equals(item.getItemName())).findFirst().get();
        //车辆单价、数量、年限
        BigDecimal carCost = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice().multiply(new BigDecimal(y.getQuantity())));}, BigDecimal::add)
                .divide(new BigDecimal(baseFinance.getYearLimit()),4, RoundingMode.HALF_UP).divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP);
        //F3*U3/V3/1.13
        BigDecimal manageCost = baseFinance.getVehicleCostList().stream().map(FinanceVehicleCost::getRepair ).reduce(BigDecimal.ZERO, BigDecimal::add)
                .multiply(baseFinance.getFinancingRate()).divide(baseFinance.getOverheadSharing().multiply(new BigDecimal(1.13)),4, RoundingMode.HALF_UP);
        //实缴增值税及附加
        //利润总额
        if(1 <= baseFinance.getYearLimit()){
            totalProfitItem.setOneYear(rentVO.getOneYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getOneYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getOneYear()).subtract(incomeAndTaxVO.getOneYear()));
        }else{
//            totalProfitItem.setOneYear(rentVO.getOneYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getOneYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getOneYear()).subtract(incomeAndTaxVO.getOneYear()));
            totalProfitItem.setOneYear(BigDecimal.ZERO);
        }
        if(2 <= baseFinance.getYearLimit()){
            totalProfitItem.setTwoYear(rentVO.getTwoYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getTwoYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getTwoYear()).subtract(incomeAndTaxVO.getTwoYear()));
        }else{
//            totalProfitItem.setTwoYear(rentVO.getTwoYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getTwoYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getTwoYear()).subtract(incomeAndTaxVO.getTwoYear()));
            totalProfitItem.setTwoYear(BigDecimal.ZERO);
        }
        if(3 <= baseFinance.getYearLimit()){
            totalProfitItem.setThreeYear(rentVO.getThreeYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getThreeYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getThreeYear()).subtract(incomeAndTaxVO.getThreeYear()));
        }else{
//            totalProfitItem.setThreeYear(rentVO.getThreeYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getThreeYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getThreeYear()).subtract(incomeAndTaxVO.getThreeYear()));
            totalProfitItem.setThreeYear(BigDecimal.ZERO);
        }
        if(4 <= baseFinance.getYearLimit()){
            totalProfitItem.setFourYear(rentVO.getFourYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getFourYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getFourYear()).subtract(incomeAndTaxVO.getFourYear()));
        }else{
//            totalProfitItem.setFourYear(rentVO.getFourYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getFourYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getFourYear()).subtract(incomeAndTaxVO.getFourYear()));
            totalProfitItem.setFourYear(BigDecimal.ZERO);
        }
        if(5 <= baseFinance.getYearLimit()){
            totalProfitItem.setFiveYear(rentVO.getFiveYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getFiveYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getFiveYear()).subtract(incomeAndTaxVO.getFiveYear()));
        }else{
//            totalProfitItem.setFiveYear(rentVO.getFiveYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getFiveYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getFiveYear()).subtract(incomeAndTaxVO.getFiveYear()));
            totalProfitItem.setFiveYear(BigDecimal.ZERO);
        }
        if(6 <= baseFinance.getYearLimit()){
            totalProfitItem.setSixYear(rentVO.getSixYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getSixYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getSixYear()).subtract(incomeAndTaxVO.getSixYear()));
        }else{
//            totalProfitItem.setSixYear(rentVO.getSixYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getSixYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getSixYear()).subtract(incomeAndTaxVO.getSixYear()));
            totalProfitItem.setSixYear(BigDecimal.ZERO);
        }
        if(7 <= baseFinance.getYearLimit()){
            totalProfitItem.setSevenYear(rentVO.getSevenYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getSevenYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getSevenYear()).subtract(incomeAndTaxVO.getSevenYear()));
        }else{
//            totalProfitItem.setSevenYear(rentVO.getSevenYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getSevenYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getSevenYear()).subtract(incomeAndTaxVO.getSevenYear()));
            totalProfitItem.setSevenYear(BigDecimal.ZERO);
        }
        if(8 <= baseFinance.getYearLimit()){
            totalProfitItem.setEightYear(rentVO.getEightYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
                    .subtract(carCost).subtract(manageVO.getEightYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
                    .subtract(financeVO.getEightYear()).subtract(incomeAndTaxVO.getEightYear()));
        }else{
//            totalProfitItem.setEightYear(rentVO.getEightYear().divide(new BigDecimal(1.13),4, RoundingMode.HALF_UP)
//                    .subtract(manageCost).subtract(manageVO.getEightYear().divide(new BigDecimal(1.06),4, RoundingMode.HALF_UP))
//                    .subtract(financeVO.getEightYear()).subtract(incomeAndTaxVO.getEightYear()));
            totalProfitItem.setEightYear(BigDecimal.ZERO);
        }
        totalProfitItem.setTotal(totalProfitItem.getOneYear().add(totalProfitItem.getTwoYear()).add(totalProfitItem.getThreeYear()).add(totalProfitItem.getFourYear())
                .add(totalProfitItem.getFiveYear()).add(totalProfitItem.getSixYear()).add(totalProfitItem.getSevenYear()).add(totalProfitItem.getEightYear()));
//        result.add(totalProfitItem);

        //所得税
        if(1 <= baseFinance.getYearLimit()){
            incomeTaxItem.setOneYear(totalProfitItem.getOneYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getOneYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setOneYear(BigDecimal.ZERO);
        }
        if(2 <= baseFinance.getYearLimit()){
            incomeTaxItem.setTwoYear(totalProfitItem.getTwoYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getTwoYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setTwoYear(BigDecimal.ZERO);
        }
        if(3 <= baseFinance.getYearLimit()){
            incomeTaxItem.setThreeYear(totalProfitItem.getThreeYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getThreeYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setThreeYear(BigDecimal.ZERO);
        }
        if(4 <= baseFinance.getYearLimit()){
            incomeTaxItem.setFourYear(totalProfitItem.getFourYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getFourYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setFourYear(BigDecimal.ZERO);
        }
        if(5 <= baseFinance.getYearLimit()){
            incomeTaxItem.setFiveYear(totalProfitItem.getFiveYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getFiveYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setFiveYear(BigDecimal.ZERO);
        }
        if(6 <= baseFinance.getYearLimit()){
            incomeTaxItem.setSixYear(totalProfitItem.getSixYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getSixYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setSixYear(BigDecimal.ZERO);
        }
        if(7 <= baseFinance.getYearLimit()){
            incomeTaxItem.setSevenYear(totalProfitItem.getSevenYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getSevenYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setSevenYear(BigDecimal.ZERO);
        }
        if(8 <= baseFinance.getYearLimit()){
            incomeTaxItem.setEightYear(totalProfitItem.getEightYear().compareTo(BigDecimal.valueOf(0)) < 0
                    ? BigDecimal.ZERO : totalProfitItem.getEightYear().multiply(new BigDecimal(0.25)).setScale(4, RoundingMode.HALF_UP));
        }else{
            incomeTaxItem.setEightYear(BigDecimal.ZERO);
        }
        incomeTaxItem.setTotal(incomeTaxItem.getOneYear().add(incomeTaxItem.getTwoYear()).add(incomeTaxItem.getThreeYear()).add(incomeTaxItem.getFourYear())
                .add(incomeTaxItem.getFiveYear()).add(incomeTaxItem.getSixYear()).add(incomeTaxItem.getSevenYear()).add(incomeTaxItem.getEightYear()));
        result.add(incomeTaxItem);

        //净利润
        netProfitItem.setOneYear(totalProfitItem.getOneYear().subtract(incomeTaxItem.getOneYear()));
        netProfitItem.setTwoYear(totalProfitItem.getTwoYear().subtract(incomeTaxItem.getTwoYear()));
        netProfitItem.setThreeYear(totalProfitItem.getThreeYear().subtract(incomeTaxItem.getThreeYear()));
        netProfitItem.setFourYear(totalProfitItem.getFourYear().subtract(incomeTaxItem.getFourYear()));
        netProfitItem.setFiveYear(totalProfitItem.getFiveYear().subtract(incomeTaxItem.getFiveYear()));
        netProfitItem.setSixYear(totalProfitItem.getSixYear().subtract(incomeTaxItem.getSixYear()));
        netProfitItem.setSevenYear(totalProfitItem.getSevenYear().subtract(incomeTaxItem.getSevenYear()));
        netProfitItem.setEightYear(totalProfitItem.getEightYear().subtract(incomeTaxItem.getEightYear()));
        netProfitItem.setTotal(totalProfitItem.getTotal().subtract(incomeTaxItem.getTotal()));
        result.add(netProfitItem);
        log.info("计算成本与利润 {} : ",result);
        return result;
    }

    @Override
    public List<FinanceItemVO> calculateOwnFunds(BaseFinance baseFinance,FinanceItemVO rentVO, List<FinanceItemVO> manageList,
                                                 FinanceItemVO incomeAndTaxVO,List<FinanceItemVO> financeList,List<FinanceItemVO> costAndProfitList) {
        List<FinanceItemVO> result = new ArrayList<>();
        FinanceItemVO cashOutflowItem = new FinanceItemVO();
        cashOutflowItem.setItemName("现金流出");
        FinanceItemVO netCashItem = new FinanceItemVO();
        netCashItem.setItemName("净现金流量");
        //现金流出  资本金+融资本金支出+利息费用+管理合计+实缴增值税及附加+所得税
        //成本与利润计算--所得税
        FinanceItemVO costandProfitVO = costAndProfitList.stream().filter(item -> "所得税".equals(item.getItemName())).findFirst().get();
        //融资费用计算--融资本金支出+利息费用
        FinanceItemVO capitalVO = financeList.stream().filter(item -> "融资本金支出".equals(item.getItemName())).findFirst().get();
        FinanceItemVO interestVO = financeList.stream().filter(item -> "利息费用".equals(item.getItemName())).findFirst().get();
        //管理、运维、保险费用计算 -- 合计
        FinanceItemVO manageVO = manageList.stream().filter(item -> "合计".equals(item.getItemName())).findFirst().get();
        //第0年为购车费用*(1-融资比例)
        BigDecimal carCost = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice().multiply(new BigDecimal(y.getQuantity())));}, BigDecimal::add)
                .multiply(new BigDecimal(1).subtract(baseFinance.getFinancingRatio().divide(new BigDecimal(100)))).setScale(4, RoundingMode.HALF_UP);
        cashOutflowItem.setTotal(carCost);
        cashOutflowItem.setOneYear(capitalVO.getOneYear().add(interestVO.getOneYear()).add(manageVO.getOneYear()).add(incomeAndTaxVO.getOneYear()).add(costandProfitVO.getOneYear()));
        cashOutflowItem.setTwoYear(capitalVO.getTwoYear().add(interestVO.getTwoYear()).add(manageVO.getTwoYear()).add(incomeAndTaxVO.getTwoYear()).add(costandProfitVO.getTwoYear()));
        cashOutflowItem.setThreeYear(capitalVO.getThreeYear().add(interestVO.getThreeYear()).add(manageVO.getThreeYear()).add(incomeAndTaxVO.getThreeYear()).add(costandProfitVO.getThreeYear()));
        cashOutflowItem.setFourYear(capitalVO.getFourYear().add(interestVO.getFourYear()).add(manageVO.getFourYear()).add(incomeAndTaxVO.getFourYear()).add(costandProfitVO.getFourYear()));
        cashOutflowItem.setFiveYear(capitalVO.getFiveYear().add(interestVO.getFiveYear()).add(manageVO.getFiveYear()).add(incomeAndTaxVO.getFiveYear()).add(costandProfitVO.getFiveYear()));
        cashOutflowItem.setSixYear(capitalVO.getSixYear().add(interestVO.getSixYear()).add(manageVO.getSixYear()).add(incomeAndTaxVO.getSixYear()).add(costandProfitVO.getSixYear()));
        cashOutflowItem.setSevenYear(capitalVO.getSevenYear().add(interestVO.getSevenYear()).add(manageVO.getSevenYear()).add(incomeAndTaxVO.getSevenYear()).add(costandProfitVO.getSevenYear()));
        cashOutflowItem.setEightYear(capitalVO.getEightYear().add(interestVO.getEightYear()).add(manageVO.getEightYear()).add(incomeAndTaxVO.getEightYear()).add(costandProfitVO.getEightYear()));
        result.add(cashOutflowItem);

        //净现金流量
        netCashItem.setTotal(BigDecimal.ZERO.subtract(cashOutflowItem.getTotal()));
        netCashItem.setOneYear(rentVO.getOneYear().subtract(cashOutflowItem.getOneYear()));
        netCashItem.setTwoYear(rentVO.getTwoYear().subtract(cashOutflowItem.getTwoYear()));
        netCashItem.setThreeYear(rentVO.getThreeYear().subtract(cashOutflowItem.getThreeYear()));
        netCashItem.setFourYear(rentVO.getFourYear().subtract(cashOutflowItem.getFourYear()));
        netCashItem.setFiveYear(rentVO.getFiveYear().subtract(cashOutflowItem.getFiveYear()));
        netCashItem.setSixYear(rentVO.getSixYear().subtract(cashOutflowItem.getSixYear()));
        netCashItem.setSevenYear(rentVO.getSevenYear().subtract(cashOutflowItem.getSevenYear()));
        netCashItem.setEightYear(rentVO.getEightYear().subtract(cashOutflowItem.getEightYear()));
        result.add(netCashItem);
        log.info("计算自有资金现金流量 {} : ",result);
        return result;
    }

    @Override
    public CalculateResultVO calculateResult(BaseFinance baseFinance,FinanceItemVO rentVO, FinanceItemVO incomeAndTax,
                                             List<FinanceItemVO> manageList,List<FinanceItemVO> costAndProfitList,List<FinanceItemVO> financeList) {
        CalculateResultVO resultVO = new CalculateResultVO();
        //购车成本回收期 =C3*R3/J3/12>>>>>> 1130>>C3/J3/12   单价/第一年月租金/12
        BigDecimal carCostRecovery = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getUnitPrice()
                .divide(y.getOneYear().multiply(new BigDecimal(12)),4,RoundingMode.HALF_UP)); }, BigDecimal::add);
        //融资费用计算--利息费用
        FinanceItemVO interestVO = financeList.stream().filter(item -> "利息费用".equals(item.getItemName())).findFirst().get();
        //融资成本
        BigDecimal financingCost = interestVO.getOneYear().add(interestVO.getTwoYear()).add(interestVO.getThreeYear()).add(interestVO.getFourYear())
                .add(interestVO.getFiveYear()).add(interestVO.getSixYear()).add(interestVO.getSevenYear()).add(interestVO.getEightYear());
        //内部收益率(%)
        List<FinanceItemVO> list = calculateOwnFunds(baseFinance,rentVO,manageList,incomeAndTax,financeList,costAndProfitList);
        FinanceItemVO netCashVO = list.stream().filter(item -> "净现金流量".equals(item.getItemName())).findFirst().get();
        double[] cashFlows = {netCashVO.getTotal().doubleValue(),
                netCashVO.getOneYear().doubleValue(),
                netCashVO.getTwoYear().doubleValue(),
                netCashVO.getThreeYear().doubleValue(),
                netCashVO.getFourYear().doubleValue(),
                netCashVO.getFiveYear().doubleValue(),
                netCashVO.getSixYear().doubleValue(),
                netCashVO.getSevenYear().doubleValue(),
                netCashVO.getEightYear().doubleValue()};

        double irr = calculateIRR(cashFlows);
        BigDecimal internalRate = null;
        if (Double.isNaN(irr)) {
        } else {
            internalRate = new BigDecimal(irr*100).setScale(2,RoundingMode.HALF_UP);
        }
        //实缴增值税及附加
        BigDecimal vatAndAdditional = incomeAndTax.getTotal();
        //所得税
        FinanceItemVO costandProfitVO = costAndProfitList.stream().filter(item -> "所得税".equals(item.getItemName())).findFirst().get();
        BigDecimal incomeTax = costandProfitVO.getTotal();
        //净利润
        FinanceItemVO netProfitVO = costAndProfitList.stream().filter(item -> "净利润".equals(item.getItemName())).findFirst().get();
        BigDecimal netProfit = netProfitVO.getTotal();
        //残值回收（万元）
        BigDecimal salvageValue = baseFinance.getVehicleCostList().stream()
                .reduce(BigDecimal.ZERO, (x, y) -> { return x.add(y.getSalvageValue().multiply(new BigDecimal(y.getQuantity())));}, BigDecimal::add);

        resultVO.setCarCostRecovery(carCostRecovery);
        resultVO.setFinancingCost(financingCost);
        resultVO.setInternalRate(internalRate);
        resultVO.setVatAndAdditional(vatAndAdditional);
        resultVO.setIncomeTax(incomeTax);
        resultVO.setNetProfit(netProfit);
        resultVO.setSalvageValue(salvageValue);
        log.info("计算结果 {} : ",resultVO);
        return resultVO;
    }

    @Transactional
    @Override
    public String addDetail(DetailObjectVO detail) {
        String baseId = StrUtil.uuid().replace("-","");
        //基本信息
        BaseFinance baseFinance = new BaseFinance();
        BeanUtil.copyProperties(detail,baseFinance);
        baseFinance.setId(baseId);
        //车辆情况
        List<FinanceVehicleCost> costList = detail.getVehicleCostList();
        costList.stream().forEach(item->item.setBaseId(baseId));
        //测算结果
        CalculateResultObjectVO object = detail.getCalculateObject();
        MeasureResult measureResult = new MeasureResult();
        measureResult.setBaseId(baseId);

        CalculateResultVO resultVO = object.getResult().get(0);
        BeanUtil.copyProperties(resultVO,measureResult);

        measureResult.setRentalIncomeJson(JSONUtil.toJsonPrettyStr(object.getRentalIncome()));
        measureResult.setManageCostJson(JSONUtil.toJsonPrettyStr(object.getManageCostList()));
        measureResult.setIncomeAndTaxJson(JSONUtil.toJsonPrettyStr(object.getIncomeAndTax()));
        measureResult.setCostAndProfitJson(JSONUtil.toJsonPrettyStr(object.getCostAndProfitList()));

        this.save(baseFinance);
        financeVehicleCostService.saveBatch(costList);
        measureResultService.save(measureResult);

        return baseId;
    }

    @Override
    public Page getCalcutatePage(Page page, CalculateParamVO paramVO) {
        List<CalculateListVO> list = new ArrayList<>();
        list = baseFinanceMapper.findCalcutateList(page,paramVO);
        page.setRecords(list);
        return page;
    }

    @Override
    public DetailObjectVO getDetailById(String id) {
        BaseFinance baseFinance = this.getById(id);

        LambdaQueryWrapper<FinanceVehicleCost> vehicleQuery = new LambdaQueryWrapper<>();
        vehicleQuery.eq(FinanceVehicleCost::getBaseId,baseFinance.getId());
        List<FinanceVehicleCost> vehicleList = financeVehicleCostService.list(vehicleQuery);

        LambdaQueryWrapper<MeasureResult> resultQuery = new LambdaQueryWrapper<>();
        resultQuery.eq(MeasureResult::getBaseId,baseFinance.getId()).last(" limit 1 ");
        MeasureResult measureResult = measureResultService.getOne(resultQuery);

        CalculateResultObjectVO calculateObjectVO = new CalculateResultObjectVO();
        CalculateResultVO calculateResultVO = new CalculateResultVO();
        BeanUtil.copyProperties(measureResult,calculateResultVO);
        calculateObjectVO.setResult(Collections.singletonList(calculateResultVO));
        calculateObjectVO.setRentalIncome(JSONUtil.toList(measureResult.getRentalIncomeJson(),FinanceItemVO.class));
        calculateObjectVO.setIncomeAndTax(JSONUtil.toList(measureResult.getIncomeAndTaxJson(),FinanceItemVO.class));
        calculateObjectVO.setManageCostList(JSONUtil.toList(measureResult.getManageCostJson(), FinanceItemVO.class));
        calculateObjectVO.setCostAndProfitList(JSONUtil.toList(measureResult.getCostAndProfitJson(), FinanceItemVO.class));

        DetailObjectVO objectVO = new DetailObjectVO();
        BeanUtil.copyProperties(baseFinance,objectVO);
        objectVO.setVehicleCostList(vehicleList);
        objectVO.setCalculateObject(calculateObjectVO);

        return objectVO;
    }

    @Override
    @Transactional
    public void deleteDetailById(String id) {
        this.removeById(id);

        LambdaQueryWrapper<FinanceVehicleCost> vehicleQuery = new LambdaQueryWrapper<>();
        vehicleQuery.eq(FinanceVehicleCost::getBaseId,id);
        financeVehicleCostService.remove(vehicleQuery);

        LambdaQueryWrapper<MeasureResult> resultQuery = new LambdaQueryWrapper<>();
        resultQuery.eq(MeasureResult::getBaseId,id);
        measureResultService.remove(resultQuery);
    }


    /**
     * IRR计算
     */
    private static double calculateIRR(double[] cashFlows) {
        double epsilon = 0.0001; // 精度要求
        int maxIterations = 100; // 最大迭代次数
        double irrGuess = 0.1; // IRR初始猜测值
        double irr = irrGuess;
        for (int i = 0; i < maxIterations; i++) {
            double npv = 0;
            double npvDerivative = 0;

            for (int t = 0; t < cashFlows.length; t++) {
                double factor = Math.pow(1 + irr, t);
                npv += cashFlows[t] / factor;
                npvDerivative -= t * cashFlows[t] / factor;
            }
            double newIRR = irr - npv / npvDerivative;
            if (Math.abs(newIRR - irr) <= epsilon) {
                if (Double.isInfinite(newIRR) || Double.isNaN(newIRR)) {
                    return Double.NaN; // 返回NaN表示无法计算IRR
                } else {
                    return newIRR;
                }
            }
            irr = newIRR;
        }
        return Double.NaN; // 返回NaN表示无法计算IRR
    }

}
