package cn.palmte.work.service;

import cn.palmte.work.bean.*;
import cn.palmte.work.model.*;
import cn.palmte.work.utils.InterfaceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.jfunc.common.utils.CollectionUtil;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Yuanping Zhang
 * @date 2021/11/15
 */
@Service
public class ProjectSettleService {
    private static final Logger logger = LoggerFactory.getLogger(ProjectSettleService.class);

    @Autowired
    private ProjectSettleIncomeRepository projectSettleIncomeRepository;

    @Autowired
    private ProjectSettleCostRepository projectSettleCostRepository;

    @Autowired
    private ProjectSettleCostManageRepository projectSettleCostManageRepository;

    @Autowired
    private ProjectSettleProfitMarginRepository projectSettleProfitMarginRepository;

    @Autowired
    private ProjectSettleCashFlowRepository projectSettleCashFlowRepository;

    @Autowired
    private ProjectInstanceService projectInstanceService;

    @Autowired
    private ProjectService projectService;

    public void save(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        step(project, settleBean, budgetBean, estimateBean, time);

        projectService.updateStatusAndApproveStatus(project.getId(), StatusEnum.SETTLE_ACCOUNTS, ApproveStatusEnum.APPROVAL_UNCOMMIT, project.getOtherName());
    }

    public void saveAndApprove(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) throws Exception{
        step(project, settleBean, budgetBean, estimateBean, time);

        projectService.updateStatusAndApproveStatus(project.getId(), StatusEnum.SETTLE_ACCOUNTS, ApproveStatusEnum.APPROVAL_PENDING, project.getOtherName());

        //发起结算流程
        projectInstanceService.startSettleProcessInstance(project, InterfaceUtil.getAdmin());

    }

    private void step(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        //清除旧纪录
        clearSettle(project, time);
        //收入记录
        income(project, settleBean, budgetBean, estimateBean, time);
        //成本记录
        cost(project, settleBean, budgetBean, estimateBean, time);
        //管理记录
        costManage(project, settleBean, budgetBean, estimateBean, time);
        //利润记录
        profit(project, settleBean, budgetBean, estimateBean, time);
        //资金流量记录
        cashFlow(project, settleBean, budgetBean, time);
    }


    private void clearSettle(Project project, String time){
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(incomes)){
            projectSettleIncomeRepository.deleteInBatch(incomes);
        }

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costs)){
            projectSettleCostRepository.deleteInBatch(costs);
        }

        List<ProjectSettleCostManage> costManages = projectSettleCostManageRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costManages)){
            projectSettleCostManageRepository.deleteInBatch(costManages);
        }

        List<ProjectSettleProfitMargin> profitMargins = projectSettleProfitMarginRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(profitMargins)){
            projectSettleProfitMarginRepository.deleteInBatch(profitMargins);
        }

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(cashFlows)){
            projectSettleCashFlowRepository.deleteInBatch(cashFlows);
        }
    }

    private void cost(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        ProjectSettleCost projectSettleCostDevice = new ProjectSettleCost();
        projectSettleCostDevice.setProjectId(project.getId());
        projectSettleCostDevice.setFee(ProjectSettleCost.FEE_PURCHASE);
        projectSettleCostDevice.setType(ProjectSettleCost.TYPE_DEVICE);
        projectSettleCostDevice.setEstimate(estimateBean.getCostPurchaseDeviceEstimateTotal());
        projectSettleCostDevice.setBudget(budgetBean.getCostPurchaseDeviceBudgetTotal());
        projectSettleCostDevice.setCostTaxExclude(settleBean.getCostPurchaseDevice());
        projectSettleCostDevice.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostDevice);

        ProjectSettleCost projectSettleCostBuild = new ProjectSettleCost();
        projectSettleCostBuild.setProjectId(project.getId());
        projectSettleCostBuild.setFee(ProjectSettleCost.FEE_PURCHASE);
        projectSettleCostBuild.setType(ProjectSettleCost.TYPE_BUILDING);
        projectSettleCostBuild.setCostTaxExclude(settleBean.getCostPurchaseBuild());
        projectSettleCostBuild.setEstimate(estimateBean.getCostPurchaseBuildEstimateTotal());
        projectSettleCostBuild.setBudget(budgetBean.getCostPurchaseBuildBudgetTotal());
        projectSettleCostBuild.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostBuild);

        ProjectSettleCost projectSettleCostService = new ProjectSettleCost();
        projectSettleCostService.setProjectId(project.getId());
        projectSettleCostService.setFee(ProjectSettleCost.FEE_PURCHASE);
        projectSettleCostService.setType(ProjectSettleCost.TYPE_SERVICE);
        projectSettleCostService.setCostTaxExclude(settleBean.getCostPurchaseService());
        projectSettleCostService.setEstimate(estimateBean.getCostPurchaseServiceEstimateTotal());
        projectSettleCostService.setBudget(budgetBean.getCostPurchaseServiceBudgetTotal());
        projectSettleCostService.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostService);

        ProjectSettleCost projectSettleCostOther = new ProjectSettleCost();
        projectSettleCostOther.setProjectId(project.getId());
        projectSettleCostOther.setFee(ProjectSettleCost.FEE_PURCHASE);
        projectSettleCostOther.setType(ProjectSettleCost.TYPE_OTHER);
        projectSettleCostOther.setCostTaxExclude(settleBean.getCostPurchaseOther());
        projectSettleCostOther.setEstimate(estimateBean.getCostPurchaseOtherEstimateTotal());
        projectSettleCostOther.setBudget(budgetBean.getCostPurchaseOtherBudgetTotal());
        projectSettleCostOther.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostOther);

        ProjectSettleCost projectSettleCostProject = new ProjectSettleCost();
        projectSettleCostProject.setProjectId(project.getId());
        projectSettleCostProject.setFee(ProjectSettleCost.FEE_PROJECT_MANAGE);
        projectSettleCostProject.setType(ProjectSettleCost.TYPE_PROJECT_MANAGE);
        projectSettleCostProject.setCostTaxExclude(settleBean.getCostProjectManage());
        projectSettleCostProject.setEstimate(estimateBean.getCostProjectManageEstimateTotal());
        projectSettleCostProject.setBudget(budgetBean.getCostProjectManageBudgetTotal());
        projectSettleCostProject.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostProject);

        ProjectSettleCost projectSettleCostOtherOther = new ProjectSettleCost();
        projectSettleCostOtherOther.setProjectId(project.getId());
        projectSettleCostOtherOther.setFee(ProjectSettleCost.FEE_OTHER);
        projectSettleCostOtherOther.setType(ProjectSettleCost.TYPE_OTHER_OTHER);
        projectSettleCostOtherOther.setCostTaxExclude(settleBean.getCostOther());
        projectSettleCostOtherOther.setEstimate(estimateBean.getCostOtherEstimateTotal());
        projectSettleCostOtherOther.setBudget(budgetBean.getCostOtherBudgetTotal());
        projectSettleCostOtherOther.setTime(time);
        projectSettleCostRepository.saveAndFlush(projectSettleCostOtherOther);

    }

    private void costManage(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        ProjectSettleCostManage projectSettleCostExpro = new ProjectSettleCostManage();
        projectSettleCostExpro.setProjectId(project.getId());
        projectSettleCostExpro.setType(ProjectSettleCostManage.TYPE_EXPROPRIATION);
        projectSettleCostExpro.setCostTaxExclude(settleBean.getCostExpropriation());
        projectSettleCostExpro.setEstimate(estimateBean.getCostExpropriationEstimateTotal());
        projectSettleCostExpro.setBudget(budgetBean.getCostExpropriationBudgetTotal());
        projectSettleCostExpro.setTime(time);
        projectSettleCostManageRepository.saveAndFlush(projectSettleCostExpro);

        ProjectSettleCostManage projectSettleCostManage = new ProjectSettleCostManage();
        projectSettleCostManage.setProjectId(project.getId());
        projectSettleCostManage.setType(ProjectSettleCostManage.TYPE_COMPANY_MANAGE);
        projectSettleCostManage.setCostTaxExclude(settleBean.getCostCompanyManage());
        projectSettleCostManage.setEstimate(estimateBean.getCostCompanyManageEstimateTotal());
        projectSettleCostManage.setBudget(budgetBean.getCostCompanyManageBudgetTotal());
        projectSettleCostManage.setTime(time);
        projectSettleCostManageRepository.saveAndFlush(projectSettleCostManage);

        ProjectSettleCostManage projectSettleCostIncomeTaxManage = new ProjectSettleCostManage();
        projectSettleCostIncomeTaxManage.setProjectId(project.getId());
        projectSettleCostIncomeTaxManage.setType(ProjectSettleCostManage.TYPE_INCOME_TAX);
        projectSettleCostIncomeTaxManage.setCostTaxExclude(settleBean.getCostIncomeTax());
        projectSettleCostIncomeTaxManage.setEstimate(new BigDecimal(0));
        projectSettleCostIncomeTaxManage.setBudget(new BigDecimal(0));
        projectSettleCostIncomeTaxManage.setTime(time);
        projectSettleCostManageRepository.saveAndFlush(projectSettleCostIncomeTaxManage);
    }

    private void income(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        ProjectSettleIncome projectSettleIncomeDevice = new ProjectSettleIncome();
        projectSettleIncomeDevice.setProjectId(project.getId());
        projectSettleIncomeDevice.setType(ProjectSettleIncome.TYPE_DEVICE);
        projectSettleIncomeDevice.setIncomeTaxExclude(settleBean.getIncomeDevice());
        projectSettleIncomeDevice.setEstimate(estimateBean.getIncomeDeviceEstimateTotal());
        projectSettleIncomeDevice.setBudget(budgetBean.getIncomeDeviceBudgetTotal());
        projectSettleIncomeDevice.setTime(time);
        projectSettleIncomeRepository.saveAndFlush(projectSettleIncomeDevice);

        ProjectSettleIncome projectSettleIncomeEngineer = new ProjectSettleIncome();
        projectSettleIncomeEngineer.setProjectId(project.getId());
        projectSettleIncomeEngineer.setType(ProjectSettleIncome.TYPE_ENGINEER);
        projectSettleIncomeEngineer.setIncomeTaxExclude(settleBean.getIncomeEngineer());
        projectSettleIncomeEngineer.setEstimate(estimateBean.getIncomeEngineerEstimateTotal());
        projectSettleIncomeEngineer.setBudget(budgetBean.getIncomeEngineerBudgetTotal());
        projectSettleIncomeEngineer.setTime(time);
        projectSettleIncomeRepository.saveAndFlush(projectSettleIncomeEngineer);

        ProjectSettleIncome projectSettleIncomeService = new ProjectSettleIncome();
        projectSettleIncomeService.setProjectId(project.getId());
        projectSettleIncomeService.setType(ProjectSettleIncome.TYPE_SERVICE);
        projectSettleIncomeService.setIncomeTaxExclude(settleBean.getIncomeService());
        projectSettleIncomeService.setEstimate(estimateBean.getIncomeServiceEstimateTotal());
        projectSettleIncomeService.setBudget(budgetBean.getIncomeServiceBudgetTotal());
        projectSettleIncomeService.setTime(time);
        projectSettleIncomeRepository.saveAndFlush(projectSettleIncomeService);
    }

    private void profit(Project project, SettleBean settleBean, BudgetSettleBean budgetBean, EstimateSettleBean estimateBean, String time) {
        ProjectSettleProfitMargin projectSettleGrossProfit = new ProjectSettleProfitMargin();
        projectSettleGrossProfit.setProjectId(project.getId());
        projectSettleGrossProfit.setType(ProjectSettleProfitMargin.TYPE_GROSS_PROFIT);
        projectSettleGrossProfit.setAmount(settleBean.getGrossProfit());
        projectSettleGrossProfit.setBudget(budgetBean.getGrossProfitBudgetTotal());
        projectSettleGrossProfit.setEstimate(estimateBean.getGrossProfitEstimateTotal());
        projectSettleGrossProfit.setTime(time);
        projectSettleProfitMarginRepository.saveAndFlush(projectSettleGrossProfit);

        ProjectSettleProfitMargin projectSettleContributionProfit = new ProjectSettleProfitMargin();
        projectSettleContributionProfit.setProjectId(project.getId());
        projectSettleContributionProfit.setType(ProjectSettleProfitMargin.TYPE_CONTRIBUTION_PROFIT);
        projectSettleContributionProfit.setAmount(settleBean.getContributionProfit());
        projectSettleContributionProfit.setBudget(budgetBean.getContributionProfitBudgetTotal());
        projectSettleContributionProfit.setEstimate(estimateBean.getContributionProfitEstimateTotal());
        projectSettleContributionProfit.setTime(time);
        projectSettleProfitMarginRepository.saveAndFlush(projectSettleContributionProfit);

        ProjectSettleProfitMargin projectSettleNetProfit = new ProjectSettleProfitMargin();
        projectSettleNetProfit.setProjectId(project.getId());
        projectSettleNetProfit.setType(ProjectSettleProfitMargin.TYPE_NET_PROFIT);
        projectSettleNetProfit.setAmount(settleBean.getNetProfit());
        projectSettleNetProfit.setBudget(BigDecimal.ZERO);
        projectSettleNetProfit.setEstimate(BigDecimal.ZERO);
        projectSettleNetProfit.setTime(time);
        projectSettleProfitMarginRepository.saveAndFlush(projectSettleNetProfit);
    }

    private void cashFlow(Project project, SettleBean settleBean, BudgetSettleBean cashFlowBean, String time) {
        ProjectSettleCashFlow projectSettleSaleIncomeCash = new ProjectSettleCashFlow();
        projectSettleSaleIncomeCash.setProjectId(project.getId());
        projectSettleSaleIncomeCash.setType(ProjectSettleCashFlow.SALE_INCOME_CASH);
        projectSettleSaleIncomeCash.setAmount(settleBean.getSaleIncomeCash());
        projectSettleSaleIncomeCash.setBudget(cashFlowBean.getSaleIncomeCashBudget());
        projectSettleSaleIncomeCash.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleSaleIncomeCash);

        ProjectSettleCashFlow projectSettleTaxReturn = new ProjectSettleCashFlow();
        projectSettleTaxReturn.setProjectId(project.getId());
        projectSettleTaxReturn.setType(ProjectSettleCashFlow.TAX_RETURN);
        projectSettleTaxReturn.setAmount(settleBean.getTaxReturn());
        projectSettleTaxReturn.setBudget(cashFlowBean.getTaxReturnBudget());
        projectSettleTaxReturn.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleTaxReturn);

        ProjectSettleCashFlow projectSettleEarnestMoneyIncome = new ProjectSettleCashFlow();
        projectSettleEarnestMoneyIncome.setProjectId(project.getId());
        projectSettleEarnestMoneyIncome.setType(ProjectSettleCashFlow.EARNEST_MONEY_INCOME);
        projectSettleEarnestMoneyIncome.setAmount(settleBean.getEarnestMoneyIncome());
        projectSettleEarnestMoneyIncome.setBudget(cashFlowBean.getEarnestMoneyIncomeBudget());
        projectSettleEarnestMoneyIncome.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleEarnestMoneyIncome);

        ProjectSettleCashFlow projectSettlePurchaseCost = new ProjectSettleCashFlow();
        projectSettlePurchaseCost.setProjectId(project.getId());
        projectSettlePurchaseCost.setType(ProjectSettleCashFlow.PURCHASE_COST);
        projectSettlePurchaseCost.setAmount(settleBean.getPurchaseCost());
        projectSettlePurchaseCost.setBudget(cashFlowBean.getPurchaseCostBudget());
        projectSettlePurchaseCost.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettlePurchaseCost);

        ProjectSettleCashFlow projectSettleTaxCost = new ProjectSettleCashFlow();
        projectSettleTaxCost.setProjectId(project.getId());
        projectSettleTaxCost.setType(ProjectSettleCashFlow.TAX_COST);
        projectSettleTaxCost.setAmount(settleBean.getTaxCost());
        projectSettleTaxCost.setBudget(cashFlowBean.getTaxCostBudget());
        projectSettleTaxCost.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleTaxCost);

        ProjectSettleCashFlow projectSettleEarnestMoneyCost = new ProjectSettleCashFlow();
        projectSettleEarnestMoneyCost.setProjectId(project.getId());
        projectSettleEarnestMoneyCost.setType(ProjectSettleCashFlow.EARNEST_MONEY_COST);
        projectSettleEarnestMoneyCost.setAmount(settleBean.getEarnestMoneyCost());
        projectSettleEarnestMoneyCost.setBudget(cashFlowBean.getEarnestMoneyCostBudget());
        projectSettleEarnestMoneyCost.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleEarnestMoneyCost);

        ProjectSettleCashFlow projectSettleNetCashFlow = new ProjectSettleCashFlow();
        projectSettleNetCashFlow.setProjectId(project.getId());
        projectSettleNetCashFlow.setType(ProjectSettleCashFlow.NET_CASH_FLOW);
        projectSettleNetCashFlow.setAmount(settleBean.getNetCashFlow());
        projectSettleNetCashFlow.setBudget(cashFlowBean.getNetCashFlowBudget());
        projectSettleNetCashFlow.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleNetCashFlow);

        ProjectSettleCashFlow projectSettleCashInflowFromInvestingActivities = new ProjectSettleCashFlow();
        projectSettleCashInflowFromInvestingActivities.setProjectId(project.getId());
        projectSettleCashInflowFromInvestingActivities.setType(ProjectSettleCashFlow.CASH_INFLOW_FROM_INVESTING_ACTIVITIES);
        projectSettleCashInflowFromInvestingActivities.setAmount(settleBean.getCashInflowFromInvestingActivities());
        projectSettleCashInflowFromInvestingActivities.setBudget(cashFlowBean.getCashInflowFromInvestingActivitiesBudget());
        projectSettleCashInflowFromInvestingActivities.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleCashInflowFromInvestingActivities);

        ProjectSettleCashFlow projectSettleCashOutflowFromInvestingActivities = new ProjectSettleCashFlow();
        projectSettleCashOutflowFromInvestingActivities.setProjectId(project.getId());
        projectSettleCashOutflowFromInvestingActivities.setType(ProjectSettleCashFlow.CASH_OUTFLOW_FROM_INVESTING_ACTIVITIES);
        projectSettleCashOutflowFromInvestingActivities.setAmount(settleBean.getCashOutflowFromInvestingActivities());
        projectSettleCashOutflowFromInvestingActivities.setBudget(cashFlowBean.getCashOutflowFromInvestingActivitiesBudget());
        projectSettleCashOutflowFromInvestingActivities.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleCashOutflowFromInvestingActivities);

        ProjectSettleCashFlow projectSettleNetCashFromInvestingActivities = new ProjectSettleCashFlow();
        projectSettleNetCashFromInvestingActivities.setProjectId(project.getId());
        projectSettleNetCashFromInvestingActivities.setType(ProjectSettleCashFlow.NET_CASH_FROM_INVESTING_ACTIVITIES);
        projectSettleNetCashFromInvestingActivities.setAmount(settleBean.getNetCashFromInvestingActivities());
        projectSettleNetCashFromInvestingActivities.setBudget(cashFlowBean.getNetCashFromInvestingActivitiesBudget());
        projectSettleNetCashFromInvestingActivities.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleNetCashFromInvestingActivities);

        ProjectSettleCashFlow projectSettleFinancingCapitalInflow = new ProjectSettleCashFlow();
        projectSettleFinancingCapitalInflow.setProjectId(project.getId());
        projectSettleFinancingCapitalInflow.setType(ProjectSettleCashFlow.FINANCING_CAPITAL_INFLOW);
        projectSettleFinancingCapitalInflow.setAmount(settleBean.getFinancingCapitalInflow());
        projectSettleFinancingCapitalInflow.setBudget(cashFlowBean.getFinancingCapitalInflowBudget());
        projectSettleFinancingCapitalInflow.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleFinancingCapitalInflow);

        ProjectSettleCashFlow projectSettleFinancingCapitalOutflow = new ProjectSettleCashFlow();
        projectSettleFinancingCapitalOutflow.setProjectId(project.getId());
        projectSettleFinancingCapitalOutflow.setType(ProjectSettleCashFlow.FINANCING_CAPITAL_OUTFLOW);
        projectSettleFinancingCapitalOutflow.setAmount(settleBean.getFinancingCapitalOutflow());
        projectSettleFinancingCapitalOutflow.setBudget(cashFlowBean.getFinancingCapitalOutflowBudget());
        projectSettleFinancingCapitalOutflow.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleFinancingCapitalOutflow);

        ProjectSettleCashFlow projectSettleFinancingCapitalCashflow = new ProjectSettleCashFlow();
        projectSettleFinancingCapitalCashflow.setProjectId(project.getId());
        projectSettleFinancingCapitalCashflow.setType(ProjectSettleCashFlow.FINANCING_CAPITAL_CASHFLOW);
        projectSettleFinancingCapitalCashflow.setAmount(settleBean.getFinancingCapitalCashflow());
        projectSettleFinancingCapitalCashflow.setBudget(cashFlowBean.getFinancingCapitalCashflowBudget());
        projectSettleFinancingCapitalCashflow.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleFinancingCapitalCashflow);

        ProjectSettleCashFlow projectSettleNetIncreaseMonetaryFunds = new ProjectSettleCashFlow();
        projectSettleNetIncreaseMonetaryFunds.setProjectId(project.getId());
        projectSettleNetIncreaseMonetaryFunds.setType(ProjectSettleCashFlow.NET_INCREASE_MONETARY_FUNDS);
        projectSettleNetIncreaseMonetaryFunds.setAmount(settleBean.getNetIncreaseMonetaryFunds());
        projectSettleNetIncreaseMonetaryFunds.setBudget(cashFlowBean.getNetIncreaseMonetaryFundsBudget());
        projectSettleNetIncreaseMonetaryFunds.setTime(time);
        projectSettleCashFlowRepository.saveAndFlush(projectSettleNetIncreaseMonetaryFunds);
    }

    private void getIncomeFormerSettle(FormerBean settleBean, List<ProjectSettleIncome> incomes) {
        if(CollectionUtil.isNotEmpty(incomes)){
            BigDecimal incomeDevice = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_DEVICE).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeDeviceTaxExclude(incomeDevice);

            BigDecimal incomeEngineer  = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_ENGINEER).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeEngineerTaxExclude(incomeEngineer );

            BigDecimal incomeService = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_SERVICE).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeServiceTaxExclude(incomeService);
        }
    }

    private void getCostFormerSettle(FormerBean settleBean, List<ProjectSettleCost> costs) {
        if(CollectionUtil.isNotEmpty(costs)){
            BigDecimal costDevice = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_DEVICE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseDeviceTaxExclude(costDevice);

            BigDecimal costBuild  = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_BUILDING).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseBuildTaxExclude(costBuild);

            BigDecimal costService = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_SERVICE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseServiceTaxExclude(costService);

            BigDecimal costOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseOtherTaxExclude(costOther);

            BigDecimal costProjectManage  = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_PROJECT_MANAGE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostProjectManageTaxExclude(costProjectManage );

            BigDecimal costOtherOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER_OTHER).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostOtherOtherTaxExclude(costOtherOther);
        }
    }

    private void getCostManageFormerSettle(FormerBean settleBean, List<ProjectSettleCostManage> manages) {
        if(CollectionUtil.isNotEmpty(manages)){
            BigDecimal costManageExpropriation = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_EXPROPRIATION).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostExpropriationTaxExclude(costManageExpropriation);

            BigDecimal costManageCompany  = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_COMPANY_MANAGE).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostCompanyManageTaxExclude(costManageCompany);

            BigDecimal costIncomeTax = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_INCOME_TAX).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostIncomeTax(costIncomeTax);
        }
    }

    private void getProfitFormerSettle(FormerBean settleBean, List<ProjectSettleProfitMargin> profits) {
        if(CollectionUtil.isNotEmpty(profits)) {
            BigDecimal grossProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_GROSS_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setGrossProfit(grossProfit);

            BigDecimal contributionProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_CONTRIBUTION_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setContributionProfit(contributionProfit);

            BigDecimal netProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_NET_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetProfit(netProfit);
        }
    }

    private void getCashFlowFormerSettle(FormerBean settleBean, List<ProjectSettleCashFlow> cashFlows) {
        if(CollectionUtil.isNotEmpty(cashFlows)) {
            BigDecimal saleIncomeCash = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.SALE_INCOME_CASH).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setSaleIncomeCash(saleIncomeCash);

            BigDecimal taxReturn = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_RETURN).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setTaxReturn(taxReturn);

            BigDecimal earnestMoneyIncome = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_INCOME).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setEarnestMoneyIncome(earnestMoneyIncome);

            BigDecimal purchaseCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.PURCHASE_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setPurchaseCost(purchaseCost);

            BigDecimal taxCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setTaxCost(taxCost);

            BigDecimal earnestMoneyCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setEarnestMoneyCost(earnestMoneyCost);

            BigDecimal netCashFlow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetCashFlow(netCashFlow);

            BigDecimal cashInflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_INFLOW_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCashInflowFromInvestingActivities(cashInflowFromInvestingActivities);

            BigDecimal cashOutflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_OUTFLOW_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCashOutflowFromInvestingActivities(cashOutflowFromInvestingActivities);

            BigDecimal netCashFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetCashFromInvestingActivities(netCashFromInvestingActivities);

            BigDecimal financingCapitalInflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_INFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalInflow(financingCapitalInflow);

            BigDecimal financingCapitalOutflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_OUTFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalOutflow(financingCapitalOutflow);

            BigDecimal financingCapitalCashflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_CASHFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalCashflow(financingCapitalCashflow);

            BigDecimal netIncreaseMonetaryFunds = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_INCREASE_MONETARY_FUNDS).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetIncreaseMonetaryFunds(netIncreaseMonetaryFunds);
        }
    }

    public FormerBean getFormerSettle(Project project, String time) {
        FormerBean settleBean = new FormerBean();
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectIdBefore(project.getId(), time);

        getIncomeFormerSettle(settleBean, incomes);

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectIdBefore(project.getId(), time);

        getCostFormerSettle(settleBean, costs);

        List<ProjectSettleCostManage> manages = projectSettleCostManageRepository.findAllByProjectIdBefore(project.getId(), time);

        getCostManageFormerSettle(settleBean, manages);

        List<ProjectSettleProfitMargin> profits = projectSettleProfitMarginRepository.findAllByProjectIdBefore(project.getId(), time);

        getProfitFormerSettle(settleBean, profits);

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectIdBefore(project.getId(), time);

        getCashFlowFormerSettle(settleBean, cashFlows);

        return settleBean;
    }

    public SettleBean getMonthSettle(Project project, String time) {
        SettleBean settleBean = new SettleBean();
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(incomes)){
            ProjectSettleIncome projectSettleIncomeDevice = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_DEVICE).collect(Collectors.toList()).get(0);
            settleBean.setIncomeDevice(projectSettleIncomeDevice.getIncomeTaxExclude());

            ProjectSettleIncome projectSettleIncomeEngineer = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_ENGINEER).collect(Collectors.toList()).get(0);
            settleBean.setIncomeEngineer(projectSettleIncomeEngineer.getIncomeTaxExclude());

            ProjectSettleIncome projectSettleIncomeService = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_SERVICE).collect(Collectors.toList()).get(0);
            settleBean.setIncomeService(projectSettleIncomeService.getIncomeTaxExclude());
        }

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costs)){
            ProjectSettleCost projectSettleCostDevice = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_DEVICE).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseDevice(projectSettleCostDevice.getCostTaxExclude());

            ProjectSettleCost projectSettleCostBuild = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_BUILDING).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseBuild(projectSettleCostBuild.getCostTaxExclude());

            ProjectSettleCost projectSettleCostService = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_SERVICE).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseService(projectSettleCostService.getCostTaxExclude());

            ProjectSettleCost projectSettleCostOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseOther(projectSettleCostOther.getCostTaxExclude());

            ProjectSettleCost projectSettleCostProjectManage = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_PROJECT_MANAGE).collect(Collectors.toList()).get(0);
            settleBean.setCostProjectManage(projectSettleCostProjectManage.getCostTaxExclude());

            ProjectSettleCost projectSettleCostOtherOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER_OTHER).collect(Collectors.toList()).get(0);
            settleBean.setCostOther(projectSettleCostOtherOther.getCostTaxExclude());
        }

        List<ProjectSettleCostManage> costManages = projectSettleCostManageRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costManages)){
            ProjectSettleCostManage costManageExpropriation = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_EXPROPRIATION).collect(Collectors.toList()).get(0);
            settleBean.setCostExpropriation(costManageExpropriation.getCostTaxExclude());

            ProjectSettleCostManage costManageCompany = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_COMPANY_MANAGE).collect(Collectors.toList()).get(0);
            settleBean.setCostCompanyManage(costManageCompany.getCostTaxExclude());

            ProjectSettleCostManage costIncomeTax = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_INCOME_TAX).collect(Collectors.toList()).get(0);
            settleBean.setCostIncomeTax(costIncomeTax.getCostTaxExclude());
        }

        List<ProjectSettleProfitMargin> profitMargins = projectSettleProfitMarginRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(profitMargins)){
            ProjectSettleProfitMargin grossProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_GROSS_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setGrossProfit(grossProfit.getAmount());

            ProjectSettleProfitMargin contributionProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_CONTRIBUTION_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setContributionProfit(contributionProfit.getAmount());

            ProjectSettleProfitMargin netProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_NET_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setNetProfit(netProfit.getAmount());
        }

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(cashFlows)){
            ProjectSettleCashFlow saleIncomeCash = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.SALE_INCOME_CASH).collect(Collectors.toList()).get(0);
            settleBean.setSaleIncomeCash(saleIncomeCash.getAmount());

            ProjectSettleCashFlow taxReturn = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_RETURN).collect(Collectors.toList()).get(0);
            settleBean.setTaxReturn(taxReturn.getAmount());

            ProjectSettleCashFlow earnestMoneyIncome = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_INCOME).collect(Collectors.toList()).get(0);
            settleBean.setEarnestMoneyIncome(earnestMoneyIncome.getAmount());

            ProjectSettleCashFlow purchaseCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.PURCHASE_COST).collect(Collectors.toList()).get(0);
            settleBean.setPurchaseCost(purchaseCost.getAmount());

            ProjectSettleCashFlow taxCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_COST).collect(Collectors.toList()).get(0);
            settleBean.setTaxCost(taxCost.getAmount());

            ProjectSettleCashFlow earnestMoneyCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_COST).collect(Collectors.toList()).get(0);
            settleBean.setEarnestMoneyCost(earnestMoneyCost.getAmount());

            ProjectSettleCashFlow netCashFlow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FLOW).collect(Collectors.toList()).get(0);
            settleBean.setNetCashFlow(netCashFlow.getAmount());

            ProjectSettleCashFlow cashInflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_INFLOW_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setCashInflowFromInvestingActivities(cashInflowFromInvestingActivities.getAmount());

            ProjectSettleCashFlow cashOutflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_OUTFLOW_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setCashOutflowFromInvestingActivities(cashOutflowFromInvestingActivities.getAmount());

            ProjectSettleCashFlow netCashFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setNetCashFromInvestingActivities(netCashFromInvestingActivities.getAmount());

            ProjectSettleCashFlow financingCapitalInflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_INFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalInflow(financingCapitalInflow.getAmount());

            ProjectSettleCashFlow financingCapitalOutflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_OUTFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalOutflow(financingCapitalOutflow.getAmount());

            ProjectSettleCashFlow financingCapitalCashflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_CASHFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalCashflow(financingCapitalCashflow.getAmount());

            ProjectSettleCashFlow netIncreaseMonetaryFunds = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_INCREASE_MONETARY_FUNDS).collect(Collectors.toList()).get(0);
            settleBean.setNetIncreaseMonetaryFunds(netIncreaseMonetaryFunds.getAmount());
        }

        return settleBean;
    }

    public SettleMonthBean getMonthSettleByTime(Project project, String time) {
        SettleMonthBean settleBean = new SettleMonthBean();
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(incomes)){
            ProjectSettleIncome projectSettleIncomeDevice = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_DEVICE).collect(Collectors.toList()).get(0);
            settleBean.setIncomeDevice(projectSettleIncomeDevice.getIncomeTaxExclude());
            settleBean.setBudgetIncomeDevice(projectSettleIncomeDevice.getBudget());
            settleBean.setEstimateIncomeDevice(projectSettleIncomeDevice.getEstimate());

            ProjectSettleIncome projectSettleIncomeEngineer = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_ENGINEER).collect(Collectors.toList()).get(0);
            settleBean.setIncomeEngineer(projectSettleIncomeEngineer.getIncomeTaxExclude());
            settleBean.setBudgetIncomeEngineer(projectSettleIncomeEngineer.getBudget());
            settleBean.setEstimateIncomeEngineer(projectSettleIncomeEngineer.getEstimate());

            ProjectSettleIncome projectSettleIncomeService = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_SERVICE).collect(Collectors.toList()).get(0);
            settleBean.setIncomeService(projectSettleIncomeService.getIncomeTaxExclude());
            settleBean.setBudgetIncomeService(projectSettleIncomeService.getBudget());
            settleBean.setEstimateIncomeService(projectSettleIncomeService.getEstimate());
        }

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costs)){
            ProjectSettleCost projectSettleCostDevice = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_DEVICE).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseDevice(projectSettleCostDevice.getCostTaxExclude());
            settleBean.setBudgetCostPurchaseDevice(projectSettleCostDevice.getBudget());
            settleBean.setEstimateCostPurchaseDevice(projectSettleCostDevice.getEstimate());

            ProjectSettleCost projectSettleCostBuild = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_BUILDING).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseBuild(projectSettleCostBuild.getCostTaxExclude());
            settleBean.setBudgetCostPurchaseBuild(projectSettleCostBuild.getBudget());
            settleBean.setEstimateCostPurchaseBuild(projectSettleCostBuild.getEstimate());

            ProjectSettleCost projectSettleCostService = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_SERVICE).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseService(projectSettleCostService.getCostTaxExclude());
            settleBean.setBudgetCostPurchaseService(projectSettleCostService.getBudget());
            settleBean.setEstimateCostPurchaseService(projectSettleCostService.getEstimate());

            ProjectSettleCost projectSettleCostOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER).collect(Collectors.toList()).get(0);
            settleBean.setCostPurchaseOther(projectSettleCostOther.getCostTaxExclude());
            settleBean.setBudgetCostPurchaseOther(projectSettleCostOther.getBudget());
            settleBean.setEstimateCostPurchaseOther(projectSettleCostOther.getEstimate());

            ProjectSettleCost projectSettleCostProjectManage = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_PROJECT_MANAGE).collect(Collectors.toList()).get(0);
            settleBean.setCostProjectManage(projectSettleCostProjectManage.getCostTaxExclude());
            settleBean.setBudgetCostProjectManage(projectSettleCostProjectManage.getBudget());
            settleBean.setEstimateCostProjectManage(projectSettleCostProjectManage.getEstimate());

            ProjectSettleCost projectSettleCostOtherOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER_OTHER).collect(Collectors.toList()).get(0);
            settleBean.setCostOther(projectSettleCostOtherOther.getCostTaxExclude());
            settleBean.setBudgetCostOther(projectSettleCostOtherOther.getBudget());
            settleBean.setEstimateCostOther(projectSettleCostOtherOther.getEstimate());
        }

        List<ProjectSettleCostManage> costManages = projectSettleCostManageRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(costManages)){
            ProjectSettleCostManage costManageExpropriation = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_EXPROPRIATION).collect(Collectors.toList()).get(0);
            settleBean.setCostExpropriation(costManageExpropriation.getCostTaxExclude());
            settleBean.setEstimateCostExpropriation(costManageExpropriation.getEstimate());
            settleBean.setBudgetCostExpropriation(costManageExpropriation.getBudget());

            ProjectSettleCostManage costManageCompany = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_COMPANY_MANAGE).collect(Collectors.toList()).get(0);
            settleBean.setCostCompanyManage(costManageCompany.getCostTaxExclude());
            settleBean.setEstimateCostCompanyManage(costManageCompany.getEstimate());
            settleBean.setBudgetCostCompanyManage(costManageCompany.getBudget());

            ProjectSettleCostManage costIncomeTax = costManages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_INCOME_TAX).collect(Collectors.toList()).get(0);
            settleBean.setCostIncomeTax(costIncomeTax.getCostTaxExclude());
        }

        List<ProjectSettleProfitMargin> profitMargins = projectSettleProfitMarginRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(profitMargins)){
            ProjectSettleProfitMargin grossProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_GROSS_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setGrossProfit(grossProfit.getAmount());
            settleBean.setEstimateGrossProfit(grossProfit.getEstimate());
            settleBean.setBudgetGrossProfit(grossProfit.getBudget());

            ProjectSettleProfitMargin contributionProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_CONTRIBUTION_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setContributionProfit(contributionProfit.getAmount());
            settleBean.setEstimateContributionProfit(contributionProfit.getEstimate());
            settleBean.setBudgetContributionProfit(contributionProfit.getBudget());

            ProjectSettleProfitMargin netProfit = profitMargins.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_NET_PROFIT).collect(Collectors.toList()).get(0);
            settleBean.setNetProfit(netProfit.getAmount());
        }

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectIdAndTime(project.getId(), time);
        if(CollectionUtil.isNotEmpty(cashFlows)){
            ProjectSettleCashFlow saleIncomeCash = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.SALE_INCOME_CASH).collect(Collectors.toList()).get(0);
            settleBean.setSaleIncomeCash(saleIncomeCash.getAmount());
            settleBean.setBudgetSaleIncomeCash(saleIncomeCash.getBudget());

            ProjectSettleCashFlow taxReturn = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_RETURN).collect(Collectors.toList()).get(0);
            settleBean.setTaxReturn(taxReturn.getAmount());

            ProjectSettleCashFlow earnestMoneyIncome = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_INCOME).collect(Collectors.toList()).get(0);
            settleBean.setEarnestMoneyIncome(earnestMoneyIncome.getAmount());
            settleBean.setBudgetEarnestMoneyIncome(earnestMoneyIncome.getBudget());

            ProjectSettleCashFlow purchaseCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.PURCHASE_COST).collect(Collectors.toList()).get(0);
            settleBean.setPurchaseCost(purchaseCost.getAmount());
            settleBean.setBudgetPurchaseCost(purchaseCost.getBudget());

            ProjectSettleCashFlow taxCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_COST).collect(Collectors.toList()).get(0);
            settleBean.setTaxCost(taxCost.getAmount());

            ProjectSettleCashFlow earnestMoneyCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_COST).collect(Collectors.toList()).get(0);
            settleBean.setEarnestMoneyCost(earnestMoneyCost.getAmount());
            settleBean.setBudgetEarnestMoneyCost(earnestMoneyCost.getBudget());

            ProjectSettleCashFlow netCashFlow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FLOW).collect(Collectors.toList()).get(0);
            settleBean.setNetCashFlow(netCashFlow.getAmount());
            settleBean.setBudgetNetCashFlow(netCashFlow.getBudget());

            ProjectSettleCashFlow cashInflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_INFLOW_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setCashInflowFromInvestingActivities(cashInflowFromInvestingActivities.getAmount());

            ProjectSettleCashFlow cashOutflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_OUTFLOW_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setCashOutflowFromInvestingActivities(cashOutflowFromInvestingActivities.getAmount());

            ProjectSettleCashFlow netCashFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FROM_INVESTING_ACTIVITIES).collect(Collectors.toList()).get(0);
            settleBean.setNetCashFromInvestingActivities(netCashFromInvestingActivities.getAmount());

            ProjectSettleCashFlow financingCapitalInflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_INFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalInflow(financingCapitalInflow.getAmount());
            settleBean.setBudgetFinancingCapitalInflow(financingCapitalInflow.getBudget());

            ProjectSettleCashFlow financingCapitalOutflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_OUTFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalOutflow(financingCapitalOutflow.getAmount());
            settleBean.setBudgetFinancingCapitalOutflow(financingCapitalOutflow.getBudget());

            ProjectSettleCashFlow financingCapitalCashflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_CASHFLOW).collect(Collectors.toList()).get(0);
            settleBean.setFinancingCapitalCashflow(financingCapitalCashflow.getAmount());
            settleBean.setBudgetFinancingCapitalCashflow(financingCapitalCashflow.getBudget());

            ProjectSettleCashFlow netIncreaseMonetaryFunds = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_INCREASE_MONETARY_FUNDS).collect(Collectors.toList()).get(0);
            settleBean.setNetIncreaseMonetaryFunds(netIncreaseMonetaryFunds.getAmount());
            settleBean.setBudgetNetIncreaseMonetaryFunds(netIncreaseMonetaryFunds.getBudget());
        }

        return settleBean;
    }

    public FormerBean getCurrentSettle(Project project, String time) {
        FormerBean settleBean = new FormerBean();
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectId(project.getId());

        getIncomeFormerSettle(settleBean, incomes);

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectId(project.getId());

        getCostFormerSettle(settleBean, costs);

        List<ProjectSettleCostManage> manages = projectSettleCostManageRepository.findAllByProjectId(project.getId());

        getCostManageFormerSettle(settleBean, manages);

        List<ProjectSettleProfitMargin> profits = projectSettleProfitMarginRepository.findAllByProjectId(project.getId());

        getProfitFormerSettle(settleBean, profits);

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectId(project.getId());

        getCashFlowFormerSettle(settleBean, cashFlows);

        return settleBean;
    }

    public SettleBean getMonthTotalSettle(List<Integer> projectInt, String time) {
        SettleBean settleBean = new SettleBean();

        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectsAndTime(projectInt, time);
        if(CollectionUtil.isNotEmpty(incomes)){
            BigDecimal incomeDevice = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_DEVICE).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeDevice(incomeDevice);

            BigDecimal incomeEngineer  = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_ENGINEER).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeEngineer(incomeEngineer );

            BigDecimal incomeService = incomes.stream().filter(d -> d.getType() == ProjectSettleIncome.TYPE_SERVICE).map(ProjectSettleIncome::getIncomeTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setIncomeService(incomeService);
        }

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectsAndTime(projectInt, time);
        if(CollectionUtil.isNotEmpty(costs)){
            BigDecimal costDevice = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_DEVICE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseDevice(costDevice);

            BigDecimal costBuild  = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_BUILDING).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseBuild(costBuild);

            BigDecimal costService = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_SERVICE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseService(costService);

            BigDecimal costOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostPurchaseOther(costOther);

            BigDecimal costProjectManage  = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_PROJECT_MANAGE).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostProjectManage(costProjectManage );

            BigDecimal costOtherOther = costs.stream().filter(d -> d.getType() == ProjectSettleCost.TYPE_OTHER_OTHER).map(ProjectSettleCost::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostOther(costOtherOther);
        }

        List<ProjectSettleCostManage> manages = projectSettleCostManageRepository.findAllByProjectsAndTime(projectInt, time);
        if(CollectionUtil.isNotEmpty(manages)){
            BigDecimal costManageExpropriation = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_EXPROPRIATION).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostExpropriation(costManageExpropriation);

            BigDecimal costManageCompany  = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_COMPANY_MANAGE).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostCompanyManage(costManageCompany);

            BigDecimal costIncomeTax = manages.stream().filter(d -> d.getType() == ProjectSettleCostManage.TYPE_INCOME_TAX).map(ProjectSettleCostManage::getCostTaxExclude).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCostIncomeTax(costIncomeTax);
        }

        List<ProjectSettleProfitMargin> profits = projectSettleProfitMarginRepository.findAllByProjectsAndTime(projectInt, time);
        if(CollectionUtil.isNotEmpty(profits)) {
            BigDecimal grossProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_GROSS_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setGrossProfit(grossProfit);

            BigDecimal contributionProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_CONTRIBUTION_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setContributionProfit(contributionProfit);

            BigDecimal netProfit = profits.stream().filter(d -> d.getType() == ProjectSettleProfitMargin.TYPE_NET_PROFIT).map(ProjectSettleProfitMargin::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetProfit(netProfit);
        }

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectsAndTime(projectInt, time);
        if(CollectionUtil.isNotEmpty(cashFlows)) {
            BigDecimal saleIncomeCash = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.SALE_INCOME_CASH).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setSaleIncomeCash(saleIncomeCash);

            BigDecimal taxReturn = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_RETURN).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setTaxReturn(taxReturn);

            BigDecimal earnestMoneyIncome = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_INCOME).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setEarnestMoneyIncome(earnestMoneyIncome);

            BigDecimal purchaseCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.PURCHASE_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setPurchaseCost(purchaseCost);

            BigDecimal taxCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.TAX_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setTaxCost(taxCost);

            BigDecimal earnestMoneyCost = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.EARNEST_MONEY_COST).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setEarnestMoneyCost(earnestMoneyCost);

            BigDecimal netCashFlow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetCashFlow(netCashFlow);

            BigDecimal cashInflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_INFLOW_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCashInflowFromInvestingActivities(cashInflowFromInvestingActivities);

            BigDecimal cashOutflowFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.CASH_OUTFLOW_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setCashOutflowFromInvestingActivities(cashOutflowFromInvestingActivities);

            BigDecimal netCashFromInvestingActivities = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_CASH_FROM_INVESTING_ACTIVITIES).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetCashFromInvestingActivities(netCashFromInvestingActivities);

            BigDecimal financingCapitalInflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_INFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalInflow(financingCapitalInflow);

            BigDecimal financingCapitalOutflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_OUTFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalOutflow(financingCapitalOutflow);

            BigDecimal financingCapitalCashflow = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.FINANCING_CAPITAL_CASHFLOW).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setFinancingCapitalCashflow(financingCapitalCashflow);

            BigDecimal netIncreaseMonetaryFunds = cashFlows.stream().filter(d -> d.getType() == ProjectSettleCashFlow.NET_INCREASE_MONETARY_FUNDS).map(ProjectSettleCashFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            settleBean.setNetIncreaseMonetaryFunds(netIncreaseMonetaryFunds);
        }
        return settleBean;
    }

    public FormerBean getCurrentSettleBytime(Project project, String time) {
        FormerBean settleBean = new FormerBean();
        List<ProjectSettleIncome> incomes = projectSettleIncomeRepository.findAllByProjectIdAndTimeBeforeAndEquals(project.getId(),time);

        getIncomeFormerSettle(settleBean, incomes);

        List<ProjectSettleCost> costs = projectSettleCostRepository.findAllByProjectIdAndTimeBeforeAndEquals(project.getId(),time);

        getCostFormerSettle(settleBean, costs);

        List<ProjectSettleCostManage> manages = projectSettleCostManageRepository.findAllByProjectIdAndTimeBeforeAndEquals(project.getId(),time);

        getCostManageFormerSettle(settleBean, manages);

        List<ProjectSettleProfitMargin> profits = projectSettleProfitMarginRepository.findAllByProjectIdAndTimeBeforeAndEquals(project.getId(),time);

        getProfitFormerSettle(settleBean, profits);

        List<ProjectSettleCashFlow> cashFlows = projectSettleCashFlowRepository.findAllByProjectIdAndTimeBeforeAndEquals(project.getId(),time);

        getCashFlowFormerSettle(settleBean, cashFlows);

        return settleBean;
    }
}
