package com.jeeplus.modules.sg.financial.erpcredit.util;

import com.jeeplus.modules.sg.audit.information.entity.Information;
import com.jeeplus.modules.sg.financial.erpcredit.entity.ErpAccount;
import com.jeeplus.modules.sg.financial.erpcredit.entity.ErpCredit;
import com.jeeplus.modules.sg.financial.expense.entity.Expense;
import com.jeeplus.modules.sg.financial.settlement.entity.MaintainData;
import io.swagger.models.auth.In;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 费用入账工具类
 */
public class CostAccountUnits {
    public static List<Expense> getQCExpense(List<ErpCredit> erpCredits,List<Expense> expenses){
        List<Expense> expenseList = new ArrayList<Expense>();
        boolean flag = false;
        for (Expense expense:expenses){
            flag = false;
            for (ErpCredit erpCredit1:erpCredits){
                if (expense.getProjectId().equals(erpCredit1.getItemId())){
                    flag = true;
                    break;
                }
            }
            if (flag){
                expenseList.add(expense);
            }
        }
        return getOneErpListJudge(expenseList);
    }

    //得到 2020年项目
    public static List<Expense> getOneErpListJudge(List<Expense> expenses){
        String projectBatch = "";
//        List<Expense> expensesList = new ArrayList<Expense>();
        boolean yearJudgment = false;
        for (Expense expense:expenses){
            projectBatch = expense.getProjectBatch();
            if (null!=projectBatch&&!"".equals(projectBatch)){
               yearJudgment = getYearJudgment(projectBatch);
               if (yearJudgment){
                  expense.setStatus("0");
               }else {
                   expense.setStatus("1");
               }
            }
        }
        return expenses;
    }

    //判断项目时间
    public static boolean getYearJudgment(String projectBatch){
        Integer yearNumber = 2020;
        if (projectBatch.length()>=4){
            projectBatch = projectBatch.substring(0,4);
            yearNumber = new Integer(projectBatch);
            if (yearNumber>=2020){
                return true;
            }
        }
        return false;
    }
    //2020之前的项目费用入账判断(无问题)设计费 实际付款金额
    public static Map<String,List<ErpCredit>> getJudgeDesign(List<ErpCredit> erpCredits, List<Expense> expenses){
        Map<String,List<ErpCredit>> designMap = new HashMap<String, List<ErpCredit>>();
        //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题 集合
        List<ErpCredit> erpCredits1 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）>实付金额（不含税价）,需要进入人工判断，若人工判断通过，则费用入账核实无问题，若人工判断不通过则费用入账核实存在问题；
        List<ErpCredit> erpCredits2 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题
        List<ErpCredit> erpCredits3 = new ArrayList<ErpCredit>();
        Double otherDesignFee = 0.0;//=ERP明细账生成数据中设计费入账金额(不含税价)
        for (ErpCredit erpCredit:erpCredits){
            otherDesignFee = erpCredit.getOtherDesignFee();
            for (Expense expense:expenses){
                if (erpCredit.getItemId().equals(expense.getProjectId())){
                    erpCredit.setDesignFeePayable(expense.getDesignFeePayable());//设计费应付金额
                    //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题
                    if (expense.getDesignFeePayable()>= otherDesignFee-0.01 && expense.getDesignFeePayable()<= otherDesignFee+0.01){
                        erpCredits1.add(erpCredit);//无问题
                    }else if (expense.getDesignFeePayable()>otherDesignFee){
                        erpCredit.setDesignStatus("2");
                        erpCredit.setDesignFeePayable(expense.getDesignFeePayable());
                        erpCredits2.add(erpCredit);//存在问题
                    }else {
                        erpCredit.setDesignStatus("1");
                        erpCredit.setDesignFeePayable(expense.getDesignFeePayable());
                        erpCredits3.add(erpCredit);//<存在问题
                    }
                    break;
                }
            }
        }
        designMap.put("designNoProblem",erpCredits1);//无问题
        designMap.put("designThanProblem",erpCredits2);//人工判断
        designMap.put("designYesProblem",erpCredits3);//存在问题导出
        return designMap;
    }

    //项目费用入账判断设计费 设计费应付金额
    public static List<Expense> getJudgeDesignActual(List<Expense> expenses, List<MaintainData> maintainDatas){
        double investment = 0.0;    //发文总投资
        double estimateTotal = 0.0;//概算总金额
        double designFee = 0.0;//概预算中设计费设计费
        double designCost = 0.0;//设计费合同则扣
        double designTypeicalCost =0.0;//设计费典型设计折扣
        double documentDesignCost = 0.0;//发文中设计费金额（不含税）
        double designFeePayable = 0.0;//设计费应付金额 不含税价
        List<Expense> expenseList = new ArrayList<Expense>();
        for (Expense expense:expenses){
            designCost = expense.getDesignCost();
            designTypeicalCost = expense.getDesignTypeicalCost();
            documentDesignCost = expense.getDocumentDesignCost();//发文中设计费金额（不含税）
            for (MaintainData maintainData:maintainDatas){
                //项目定义号相同
               if (expense.getProjectId().equals(maintainData.getProjectId())){
                   investment = Double.valueOf(maintainData.getInvestment());//发文总投资
                   estimateTotal = maintainData.getDesignFee()+maintainData.getBuildingFee()+maintainData.getEquipmentFee()+maintainData.getMaterialFee()+maintainData
                           .getInstallFee()+maintainData.getSupervisionFee()+maintainData.getPreliminaryWorkFee()+maintainData.getDamages()+maintainData.getManagementFee();
                   estimateTotal = estimateTotal/10000;//发文总金额（----------------------------------------）
                    if (expense.getStatus().equals("1")){//2020年之前项目
                        if (investment<=estimateTotal+0.01 && investment>=estimateTotal-0.01){
                            designFee = maintainData.getDesignFee();//该预算中设计费
                            designFeePayable = designFee*designCost*designTypeicalCost/1.06;//不含税价
                        }else {
                            designFeePayable =  documentDesignCost*designCost*designTypeicalCost/1.06;//不换税价
                        }
                    }else {//2020年之后项目
                        if (investment<=estimateTotal+0.01 && investment>=estimateTotal-0.01){
                            designFee = maintainData.getDesignFee();//该预算中设计费
                            designFeePayable = designFee*designCost*designTypeicalCost*1.06;
                        }else {
                            designFeePayable =  documentDesignCost*designCost*designTypeicalCost*1.06;
                        }
                    }
                   expense.setDesignFeePayable(designFeePayable);//设计费应付金额
                   expenseList.add(expense);
                   break;
               }
            }
        }
        return expenses;
    }
    //2020之前的项目费用入账判断(无问题)监理费 实际付款金额
    public static Map<String,List<ErpCredit>> getJudgeSupervisorFee(List<ErpCredit> erpCredits, List<Expense> expenses){
        Map<String,List<ErpCredit>> supervisorFeeMap = new HashMap<String, List<ErpCredit>>();
        //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题 集合
        List<ErpCredit> erpCredits1 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）>实付金额（不含税价）,需要进入人工判断，若人工判断通过，则费用入账核实无问题，若人工判断不通过则费用入账核实存在问题；
        List<ErpCredit> erpCredits2 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题
        List<ErpCredit> erpCredits3 = new ArrayList<ErpCredit>();
        Double otherSupervisorFee = 0.0;//=ERP明细账生成数据中监理费入账金额(不含税价)
        for (ErpCredit erpCredit:erpCredits){
            otherSupervisorFee = erpCredit.getOtherSupervisorFee();
            for (Expense expense:expenses){
                if (erpCredit.getItemId().equals(expense.getProjectId())){
                    erpCredit.setSupervisorFeePayable(expense.getSupervisorFeePayable());//监理费
                    //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题
                    if (expense.getSupervisorFeePayable()>= otherSupervisorFee-0.01 && expense.getSupervisorFeePayable()<= otherSupervisorFee+0.01){
                        erpCredits1.add(erpCredit);//无问题
                    }else if (expense.getSupervisorFeePayable()>otherSupervisorFee){
                        erpCredit.setSupervisorStatus("2");
                        erpCredit.setSupervisorFeePayable(expense.getSupervisorFeePayable());
                        erpCredits2.add(erpCredit);//存在问题
                    }else {
                        erpCredit.setSupervisorStatus("1");
                        erpCredit.setSupervisorFeePayable(expense.getSupervisorFeePayable());
                        erpCredits3.add(erpCredit);//<存在问题
                    }
                    break;
                }
            }
        }
        supervisorFeeMap.put("supervisorNoProblem",erpCredits1);//无问题
        supervisorFeeMap.put("supervisorThanProblem",erpCredits2);//人工判断
        supervisorFeeMap.put("supervisorYesProblem",erpCredits3);//存在问题导出
        return supervisorFeeMap;
    }

    //项目费用入账判断监理费 监理费应付金额
    public static List<Expense> getJudgeSupervisorFeeActual(List<Expense> expenses, List<MaintainData> maintainDatas){
        double investment = 0.0;    //发文总投资
        double estimateTotal = 0.0;//概算总金额
        double supervisionFee = 0.0;//概预算中监理费
        double supervisionCost = 0.0;//监理费合同则扣
        double supervisionTypeicalCost =0.0;//监理费典型设计折扣
        double documentSupervisionCost = 0.0;//发文中监理费金额（不含税）
        double supervisorFeePayable = 0.0;//监理费应付金额
        List<Expense> expenseList = new ArrayList<Expense>();
        for (Expense expense:expenses){
            supervisionCost = expense.getSupervisionCost();//监理费合同则扣
            supervisionTypeicalCost = expense.getSupervisionTypeicalCost();//监理费典型设计折扣
            documentSupervisionCost = expense.getDocumentSupervisionCost();//监理费应付金额 不含税价
            for (MaintainData maintainData:maintainDatas){
                //项目定义号相同
                if (expense.getProjectId().equals(maintainData.getProjectId())){
                    investment = Double.valueOf(maintainData.getInvestment());//发文总投资
                    estimateTotal = maintainData.getDesignFee()+maintainData.getBuildingFee()+maintainData.getEquipmentFee()+maintainData.getMaterialFee()+maintainData
                            .getInstallFee()+maintainData.getSupervisionFee()+maintainData.getPreliminaryWorkFee()+maintainData.getDamages()+maintainData.getManagementFee();
                    estimateTotal = estimateTotal/10000;//发文总金额（----------------------------------------）
                    if (expense.getStatus().equals("1")){//2020年之前项目
                        if (investment<=estimateTotal+0.01 && investment>=estimateTotal-0.01){
                            supervisionFee = maintainData.getSupervisionFee();//概预算中监理费金额
                            supervisorFeePayable = supervisionFee*supervisionCost*supervisionTypeicalCost/1.06;//不含税价
                        }else {
                            supervisorFeePayable =  documentSupervisionCost*supervisionCost*supervisionTypeicalCost/1.06;//不换税价
                        }
                    }else {//2020年之后项目
                        if (investment<=estimateTotal+0.01 && investment>=estimateTotal-0.01){
                            supervisionFee = maintainData.getSupervisionFee();//概预算中监理费金额
                            supervisorFeePayable = supervisionFee*supervisionCost*supervisionTypeicalCost*1.06;
                        }else {
                            supervisorFeePayable =  documentSupervisionCost*supervisionCost*supervisionTypeicalCost*1.06;
                        }
                    }
                    expense.setSupervisorFeePayable(supervisorFeePayable);//设计费应付金额
                    expenseList.add(expense);
                    break;
                }
            }
        }
        return expenses;
    }

    //2020之前的项目费用入账判断(无问题)施工费 实际付款金额
    public static Map<String,List<ErpCredit>> getJudgeConsFee(List<ErpCredit> erpCredits, List<Expense> expenses){
        Map<String,List<ErpCredit>> consFeeMap = new HashMap<String, List<ErpCredit>>();
        //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题 集合
        List<ErpCredit> erpCredits1 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）>实付金额（不含税价）,需要进入人工判断，若人工判断通过，则费用入账核实无问题，若人工判断不通过则费用入账核实存在问题；
        List<ErpCredit> erpCredits2 = new ArrayList<ErpCredit>();
        //若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题
        List<ErpCredit> erpCredits3 = new ArrayList<ErpCredit>();
        Double consTotalFee = 0.0;//=ERP明细账生成数据中监理费入账金额(不含税价)
        for (ErpCredit erpCredit:erpCredits){
            consTotalFee = erpCredit.getConsTotalFee();
            for (Expense expense:expenses){
                if (erpCredit.getItemId().equals(expense.getProjectId())){
                    //施工费
                    erpCredit.setConstructionFeePayable(expense.getConstructionFeePayable());
                    //若应付金额（不含税价）=实付金额（不含税价）,差异若在0.01则忽略不计，则费用入账核实无问题
                    if (expense.getConstructionFeePayable()>= consTotalFee-0.01 && expense.getSupervisorFeePayable()<= consTotalFee+0.01){
                        erpCredits1.add(erpCredit);//无问题
                    }else if (expense.getConstructionFeePayable()>consTotalFee){
                        erpCredit.setConstructionStatus("2");
                        erpCredit.setConstructionFeePayable(expense.getConstructionFeePayable());
                        erpCredits2.add(erpCredit);//存在问题
                    }else {
                        erpCredit.setConstructionStatus("1");
                        erpCredit.setConstructionFeePayable(expense.getConstructionFeePayable());
                        erpCredits3.add(erpCredit);//<存在问题
                    }
                    break;
                }
            }
        }
        consFeeMap.put("consNoProblem",erpCredits1);//无问题
        consFeeMap.put("consThanProblem",erpCredits2);//人工判断
        consFeeMap.put("consYesProblem",erpCredits3);//存在问题导出
        return consFeeMap;
    }

    //项目费用入账判断施工费 施工费应付金额
    public static List<Expense> getJudgeConsFeeActual(List<Information> informationList,List<Expense> expenses){
        Double constructionFeePayable=0.0;//施工费应付金额
        Double constructionCost = 0.0; //施工费合同折扣
        Double settlementPrice = 1.0;//结算审定施工费金额（含税价）
        for (Expense expense:expenses){
            settlementPrice = 1.0;
            constructionFeePayable=0.0;
            constructionCost = expense.getConstructionCost();//施工合同折扣
            for (Information information:informationList){
                if (expense.getProjectId().equals(information.getProjectId())){
                    //结算审定施工费金额（含税价）如果不为空则赋值
                    if (null!=information.getSettlementPrice()){
                        settlementPrice = information.getSettlementPrice();
                    }
                    //2020年前的项目
                    if (expense.getStatus().equals("1")){
                        constructionFeePayable = constructionCost*settlementPrice/1.09;
                    }else {//2020后的项目
                        constructionFeePayable = constructionCost*settlementPrice/1.09;
                    }
                    expense.setConstructionFeePayable(constructionFeePayable);
                    break;
                }
            }
        }
        return expenses;
    }

    //方法整合
    public static Map<String,List<ErpCredit>> getJudgeEnterAccount(List<ErpCredit> erpCredits, List<Expense> expenses,List<Information> informationList,List<MaintainData> maintainDatas){
        Map<String,List<ErpCredit>> listMap = new HashMap<String, List<ErpCredit>>();
        //设计费
        //项目费用入账判断设计费 设计费应付金额
        List<Expense> judgeDesignActual = getJudgeDesignActual(expenses, maintainDatas);
        //项目费用入账判断(无问题)设计费 实际付款金额
        Map<String, List<ErpCredit>> judgeDesign = getJudgeDesign(erpCredits, judgeDesignActual);
        //监理费
        List<Expense> judgeSupervisorFeeActual = getJudgeSupervisorFeeActual(expenses, maintainDatas);
        Map<String, List<ErpCredit>> judgeSupervisorFee = getJudgeSupervisorFee(erpCredits, judgeSupervisorFeeActual);
        //施工费
        List<Expense> judgeConsFeeActual = getJudgeConsFeeActual(informationList, expenses);
        Map<String, List<ErpCredit>> judgeConsFee = getJudgeConsFee(erpCredits, judgeConsFeeActual);

        //获取存在集合的且有问题（应付金额（不含税价）>实付金额（不含税价））
        List<ErpCredit> designThanProblem = judgeDesign.get("designThanProblem");//获取设计费
        List<ErpCredit> supervisorThanProblem = judgeSupervisorFee.get("supervisorThanProblem");//获取监理费
        List<ErpCredit> consThanProblem = judgeConsFee.get("consThanProblem");//获取施工费
        List<ErpCredit> judgeEnterAccountTwo = getJudgeEnterAccount(designThanProblem, supervisorThanProblem, consThanProblem,"2");

        //若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题。
        List<ErpCredit> designYesProblem = judgeDesign.get("designYesProblem");//获取设计费
        List<ErpCredit> supervisorYesProblem = judgeSupervisorFee.get("supervisorYesProblem");//获取监理费
        List<ErpCredit> consYesProblem = judgeConsFee.get("consYesProblem");//获取施工费
        List<ErpCredit> judgeEnterAccountThree = getJudgeEnterAccount(designYesProblem, supervisorYesProblem, consYesProblem,"1");
        listMap.put("judgeEnterAccountTwo",judgeEnterAccountTwo);
        listMap.put("judgeEnterAccountThree",judgeEnterAccountThree);
        return listMap;
    }


    //统一list
    public static List<ErpCredit> getJudgeEnterAccount(List<ErpCredit> erpCredits1,List<ErpCredit> erpCredits2,List<ErpCredit> erpCredits3,String status){
        List<ErpCredit> list = new ArrayList<ErpCredit>();
        List<ErpCredit> sureList = new ArrayList<ErpCredit>();
        for (ErpCredit erpCredit1:erpCredits1){
            list.add(erpCredit1);
        }
        for (ErpCredit erpCredit2:erpCredits2){
            list.add(erpCredit2);
        }
        for (ErpCredit erpCredit3:erpCredits3){
            list.add(erpCredit3);
        }
        boolean flag = true;
        for (ErpCredit erpCredit:list){
            flag = true;
            for (ErpCredit sureErp:sureList){
                if (erpCredit.getItemId().equals(sureErp.getItemId())){
                    if (null!=erpCredit.getDesignStatus()){//设计费存在问题
                      if (erpCredit.getDesignStatus().equals(status)){
                          sureErp.setDesignStatus(status);
                          sureErp.setDesignFeePayable(erpCredit.getDesignFeePayable());
                      }
                    }
                    if (null!=erpCredit.getConstructionStatus()){
                       if (erpCredit.getConstructionStatus().equals(status)){
                           sureErp.setConstructionStatus(status);
                           sureErp.setConstructionFeePayable(erpCredit.getConstructionFeePayable());
                       }
                    }
                    if (null!=erpCredit.getSupervisorStatus()){
                        if (erpCredit.getSupervisorStatus().equals(status)){
                            sureErp.setSupervisorStatus(status);
                            sureErp.setSupervisorFeePayable(erpCredit.getSupervisorFeePayable());
                        }
                    }
                    flag = false;
                }
            }
            if (flag){
                sureList.add(erpCredit);
            }
        }
        return sureList;
    }
}
