package org.jeecg.modules.financeManage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.modules.clinical.budget.entity.FdClinicalBudget;
import org.jeecg.modules.clinical.budget.entity.FdClinicalBudgetHandoverfeeItems;
import org.jeecg.modules.clinical.budget.entity.FdClinicalBudgetTemplateTypeCost;
import org.jeecg.modules.clinical.budget.service.IFdClinicalBudgetHandoverfeeItemsService;
import org.jeecg.modules.clinical.budget.service.IFdClinicalBudgetService;
import org.jeecg.modules.clinical.budget.service.IFdClinicalBudgetTemplateTypeCostService;
import org.jeecg.modules.finance.entity.FdBalancePaymentSettlement;
import org.jeecg.modules.finance.service.IFdBalancePaymentSettlementService;
import org.jeecg.modules.finance.service.IFdSupplementaryContractReceivablesService;
import org.jeecg.modules.financeManage.entity.FdClinicalIncome;
import org.jeecg.modules.financeManage.entity.FdClinicalIncomeBudgetCost;
import org.jeecg.modules.financeManage.entity.FdClinicalIncomeOverchargeIncome;
import org.jeecg.modules.financeManage.entity.FdClinicalIncomeServiceFeeIncome;
import org.jeecg.modules.financeManage.mapper.FdClinicalIncomeBudgetCostMapper;
import org.jeecg.modules.financeManage.mapper.FdClinicalIncomeMapper;
import org.jeecg.modules.financeManage.service.IFdClinicalIncomeBudgetCostService;
import org.jeecg.modules.financeManage.service.IFdClinicalIncomeOverchargeIncomeService;
import org.jeecg.modules.financeManage.service.IFdClinicalIncomeService;
import org.jeecg.modules.financeManage.service.IFdClinicalIncomeServiceFeeIncomeService;
import org.jeecg.modules.projectManagement.entity.FdClinicalProjectMilestones;
import org.jeecg.modules.projectManagement.entity.FdContract;
import org.jeecg.modules.projectManagement.entity.FdContractProportion;
import org.jeecg.modules.projectManagement.entity.FdProjectFile;
import org.jeecg.modules.projectManagement.mapper.FdWorkingHoursItemsMapper;
import org.jeecg.modules.projectManagement.service.IFdClinicalProjectMilestonesService;
import org.jeecg.modules.projectManagement.service.IFdContractProportionService;
import org.jeecg.modules.projectManagement.service.IFdContractService;
import org.jeecg.modules.projectManagement.service.IFdProjectFileService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static org.jeecg.common.util.oConvertUtils.isEmpty;

/**
 * @Description: 临床收入确认
 * @author： jeecg-boot
 * @date：   2020-06-23
 * @version： V1.0
 */
@Transactional
@Service
public class FdClinicalIncomeServiceImpl extends ServiceImpl<FdClinicalIncomeMapper, FdClinicalIncome> implements IFdClinicalIncomeService {

    @Resource
    FdClinicalIncomeMapper fdClinicalIncomeMapper;
    @Resource
    FdClinicalIncomeBudgetCostMapper fdClinicalIncomeBudgetCostMapper;
    @Resource
    IFdClinicalIncomeBudgetCostService iFdClinicalIncomeBudgetCostService;
    @Resource
    IFdClinicalIncomeServiceFeeIncomeService iFdClinicalIncomeServiceFeeIncomeService;
    @Resource
    IFdClinicalIncomeOverchargeIncomeService iFdClinicalIncomeOverchargeIncomeService;

    @Resource
    IFdProjectFileService iFdProjectFileService;

    @Resource
    IFdContractService iFdContractService;

    @Resource
    IFdClinicalBudgetHandoverfeeItemsService iFdClinicalBudgetHandoverfeeItemsService;

    @Resource
    IFdClinicalProjectMilestonesService iFdClinicalProjectMilestonesService;

    @Resource
    IFdClinicalBudgetTemplateTypeCostService iFdClinicalBudgetTemplateTypeCostService;

    @Resource
    IFdClinicalBudgetService iFdClinicalBudgetService;

    @Resource
    FdWorkingHoursItemsMapper fdWorkingHoursItemsMapper;

    @Resource
    ISysDictService iSysDictService;

    @Resource
    IFdBalancePaymentSettlementService iFdBalancePaymentSettlementService;

    @Resource
    IFdClinicalIncomeService iFdClinicalIncomeService;

    @Resource
    IFdContractProportionService iFdContractProportionService;

    @Override
    public void saveAll(FdClinicalIncome fdClinicalIncome) {
        //新增主表
        fdClinicalIncomeMapper.insert(fdClinicalIncome);
        //新增子表
        addChild(fdClinicalIncome);
//        //新增服务费收入
//        if(fdClinicalIncome.getFdClinicalIncomeServiceFeeIncomeList()!=null&&fdClinicalIncome.getFdClinicalIncomeServiceFeeIncomeList().size()>0){
//            Integer sort=1;
//            for(FdClinicalIncomeServiceFeeIncome fdClinicalIncomeServiceFeeIncome:fdClinicalIncome.getFdClinicalIncomeServiceFeeIncomeList()){
//                fdClinicalIncomeServiceFeeIncome.setId(null);
//                fdClinicalIncomeServiceFeeIncome.setCreateBy(null);
//                fdClinicalIncomeServiceFeeIncome.setCreateTime(null);
//                fdClinicalIncomeServiceFeeIncome.setClinicalIncomeId(fdClinicalIncome.getId());
//                fdClinicalIncomeServiceFeeIncome.setSort(sort);
//                sort++;
//            }
//            iFdClinicalIncomeServiceFeeIncomeService.saveBatch(fdClinicalIncome.getFdClinicalIncomeServiceFeeIncomeList());
//        }
//        //新增过手费收入
//        if(fdClinicalIncome.getFdClinicalIncomeOverchargeIncomeList()!=null&&fdClinicalIncome.getFdClinicalIncomeOverchargeIncomeList().size()>0){
//            Integer sort=1;
//            for(FdClinicalIncomeOverchargeIncome fdClinicalIncomeOverchargeIncome:fdClinicalIncome.getFdClinicalIncomeOverchargeIncomeList()){
//                fdClinicalIncomeOverchargeIncome.setId(null);
//                fdClinicalIncomeOverchargeIncome.setCreateBy(null);
//                fdClinicalIncomeOverchargeIncome.setCreateTime(null);
//                fdClinicalIncomeOverchargeIncome.setClinicalIncomeId(fdClinicalIncome.getId());
//                fdClinicalIncomeOverchargeIncome.setSort(sort);
//                sort++;
//            }
//            iFdClinicalIncomeOverchargeIncomeService.saveBatch(fdClinicalIncome.getFdClinicalIncomeOverchargeIncomeList());
//        }
    }

    /**
    * @Author chenchuang
    * @Description //TODO 新增子集菜单
    * @Date 2020/7/6 17:24
    * @Param [fdClinicalIncome]
    * @return void
    */
    public void addChild(FdClinicalIncome fdClinicalIncome){
        //新增成本预算
        if(fdClinicalIncome.getFdClinicalIncomeBudgetCostList()!=null&&fdClinicalIncome.getFdClinicalIncomeBudgetCostList().size()>0){
            Integer sort=1;
            for (FdClinicalIncomeBudgetCost fdClinicalIncomeBudgetCost:fdClinicalIncome.getFdClinicalIncomeBudgetCostList()){
                fdClinicalIncomeBudgetCost.setId(null);
                fdClinicalIncomeBudgetCost.setCreateBy(null);
                fdClinicalIncomeBudgetCost.setCreateTime(null);
                fdClinicalIncomeBudgetCost.setClinicalIncomeId(fdClinicalIncome.getId());
                fdClinicalIncomeBudgetCost.setSort(sort);
                sort++;
            }
            //批量新增
            iFdClinicalIncomeBudgetCostService.saveBatch(fdClinicalIncome.getFdClinicalIncomeBudgetCostList());
        }
    }

    @Override
    public void updateAll(FdClinicalIncome fdClinicalIncome) {
        //修改主表
        fdClinicalIncomeMapper.updateById(fdClinicalIncome);
        //删除子表
        deleteChild(fdClinicalIncome);
        //新增子表
        addChild(fdClinicalIncome);
    }

    /**
    * @Author chenchuang
    * @Description //TODO 删除子表
    * @Date 2020/7/8 12:29
    * @Param [fdClinicalIncome]
    * @return void
    */
    public void deleteChild(FdClinicalIncome fdClinicalIncome){
        LambdaQueryWrapper<FdClinicalIncomeBudgetCost> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FdClinicalIncomeBudgetCost::getClinicalIncomeId,fdClinicalIncome.getId());
        lambdaQueryWrapper.eq(FdClinicalIncomeBudgetCost::getDelFlag,"0");
        FdClinicalIncomeBudgetCost fdClinicalIncomeBudgetCost=new FdClinicalIncomeBudgetCost();
        fdClinicalIncomeBudgetCost.setDelFlag("1");
        iFdClinicalIncomeBudgetCostService.update(fdClinicalIncomeBudgetCost,lambdaQueryWrapper);
    }

    @Override
    public FdClinicalIncome getByProjectFileId(String projectFildId) {
        //根据项目id查询相关信息
        FdClinicalIncome fdClinicalIncome=fdClinicalIncomeMapper.getByProjectId(projectFildId);
        fdClinicalIncome.setLastMonthHospitalCost(0.0);
        fdClinicalIncome.setLastMonthAccumulatedRevenueToBeRecognized(0.0);

        ///////签署方
        List<Map<String,Object>> dictItem=iSysDictService.queryDictItemsByCode("contract_square");
        for(Map<String,Object> item:dictItem){
            if(item.get("value").equals(fdClinicalIncome.getContractPartyId())){
                fdClinicalIncome.setContractPartyName(item.get("text").toString());
            }
        }
        //获取项目变化数据
        getProjectChangeData(fdClinicalIncome);
        return fdClinicalIncome;
    }

    //获取项目变化数据
    public void getProjectChangeData(FdClinicalIncome fdClinicalIncome){
        //获取当前月份
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        fdClinicalIncome.setIncomeDateMonth(month+"");
        ///////查询临床的项目总进度
        LambdaQueryWrapper<FdClinicalProjectMilestones> fdClinicalProjectMilestonesLambdaQueryWrapper=new LambdaQueryWrapper<>();
        fdClinicalProjectMilestonesLambdaQueryWrapper.eq(FdClinicalProjectMilestones::getDelFlag,"0");
//        fdClinicalProjectMilestonesLambdaQueryWrapper.eq(FdClinicalProjectMilestones::getMilestonesType,"5");//内部
        fdClinicalProjectMilestonesLambdaQueryWrapper.eq(FdClinicalProjectMilestones::getPkContract,fdClinicalIncome.getContractId());
        List<FdClinicalProjectMilestones> fdClinicalProjectMilestonesList=iFdClinicalProjectMilestonesService.list(fdClinicalProjectMilestonesLambdaQueryWrapper);
        //判断是否有值
        Double hospitalProgress=0.0;//医院进度
        if(fdClinicalProjectMilestonesList!=null&&fdClinicalProjectMilestonesList.size()>0){
            Double posse=0.0;
            //获取临床总进度
            for(FdClinicalProjectMilestones fdClinicalProjectMilestones:fdClinicalProjectMilestonesList){
                //总进度是否位数字
                if(isNumber(fdClinicalProjectMilestones.getOverallProgress())){
                    posse+=Double.parseDouble(fdClinicalProjectMilestones.getOverallProgress());
                }
                //医院进度
                if(isNumber(fdClinicalProjectMilestones.getHospitalProgress())){
                    hospitalProgress+=Double.parseDouble(fdClinicalProjectMilestones.getHospitalProgress());
                }

            }
            fdClinicalIncome.setOverallProjectProgress((posse/fdClinicalProjectMilestonesList.size())+"");
            hospitalProgress=(hospitalProgress/fdClinicalProjectMilestonesList.size());
        }
        ///////查询临床预算中的过手费明细
        LambdaQueryWrapper<FdClinicalBudgetHandoverfeeItems> fdClinicalBudgetHandoverfeeItemsLambdaQueryWrapper=new LambdaQueryWrapper<>();
        fdClinicalBudgetHandoverfeeItemsLambdaQueryWrapper.eq(FdClinicalBudgetHandoverfeeItems::getClinicalBudgetId,fdClinicalIncome.getClinicalBudgetId());
        fdClinicalBudgetHandoverfeeItemsLambdaQueryWrapper.eq(FdClinicalBudgetHandoverfeeItems::getDelFlag,"0");
        List<FdClinicalBudgetHandoverfeeItems> fdClinicalBudgetHandoverfeeItemsList=iFdClinicalBudgetHandoverfeeItemsService.list(fdClinicalBudgetHandoverfeeItemsLambdaQueryWrapper);
        //医院成本
        Double hospitalCost=0.0;
        //判断是否有值
        if(fdClinicalBudgetHandoverfeeItemsList!=null&&fdClinicalBudgetHandoverfeeItemsList.size()>0){
            //获取临床操作费的临床中心
            for(FdClinicalBudgetHandoverfeeItems fdClinicalBudgetHandoverfeeItems:fdClinicalBudgetHandoverfeeItemsList){
                if(fdClinicalBudgetHandoverfeeItems.getCostOverchargeId().equals("1")){
                    fdClinicalIncome.setResearchCenterName(fdClinicalBudgetHandoverfeeItems.getClinicalCenter());
                }
                //判断是否为临床中心操作费或者失败筛选
                if(fdClinicalBudgetHandoverfeeItems.getCostOverchargeId().equals("1")||fdClinicalBudgetHandoverfeeItems.getCostOverchargeId().equals("7")){
                    //获取医院成本
                    if(isNumber(fdClinicalBudgetHandoverfeeItems.getCostNotTax())){
                        hospitalCost+=Double.parseDouble(fdClinicalBudgetHandoverfeeItems.getCostNotTax());
                    }
                }
            }
        }
        ///////查询临床预算中的合同收入明细
        LambdaQueryWrapper<FdClinicalBudgetTemplateTypeCost> fdClinicalBudgetTemplateTypeCostLambdaQueryWrapper=new LambdaQueryWrapper<>();
        fdClinicalBudgetTemplateTypeCostLambdaQueryWrapper.eq(FdClinicalBudgetTemplateTypeCost::getDelFlag,"0");
        fdClinicalBudgetTemplateTypeCostLambdaQueryWrapper.eq(FdClinicalBudgetTemplateTypeCost::getClinicalBudgetId,fdClinicalIncome.getClinicalBudgetId());
        List<FdClinicalBudgetTemplateTypeCost> fdClinicalBudgetTemplateTypeCostList=iFdClinicalBudgetTemplateTypeCostService.list(fdClinicalBudgetTemplateTypeCostLambdaQueryWrapper);
        //判断是否有值
        if(fdClinicalBudgetTemplateTypeCostList!=null&&fdClinicalBudgetTemplateTypeCostList.size()>0){
            Double cro=0.0;//cro
            Double croCorrelation=0.0;//cro相关
            Double clinical=0.0;//临床
            for(FdClinicalBudgetTemplateTypeCost fdClinicalBudgetTemplateTypeCost:fdClinicalBudgetTemplateTypeCostList){
                //CRO
                if(fdClinicalBudgetTemplateTypeCost.getTemplateTypeId().equals("1")){
                    fdClinicalIncome.setCroTypeId("1");
                    fdClinicalIncome.setCroTypeName(fdClinicalBudgetTemplateTypeCost.getTemplateTypeName());
                    //判断是否为数字
                    if(isNumber(fdClinicalBudgetTemplateTypeCost.getTotal())){
                        cro=Double.parseDouble(fdClinicalBudgetTemplateTypeCost.getTotal());
                    }
                    fdClinicalIncome.setCroTotal(cro);
                }
                //CRO相关
                if(fdClinicalBudgetTemplateTypeCost.getTemplateTypeId().equals("3")){
                    fdClinicalIncome.setCroCorrelationTypeId("3");
                    fdClinicalIncome.setCroCorrelationTypeName(fdClinicalBudgetTemplateTypeCost.getTemplateTypeName());
                    //判断是否为数字
                    if(isNumber(fdClinicalBudgetTemplateTypeCost.getTotal())){
                        croCorrelation=Double.parseDouble(fdClinicalBudgetTemplateTypeCost.getTotal());
                    }
                    fdClinicalIncome.setCroCorrelationTotal(croCorrelation);
                }
                //临床操作
                if(fdClinicalBudgetTemplateTypeCost.getTemplateTypeId().equals("4")){
                    fdClinicalIncome.setClinicalOperationTypeId("4");
                    fdClinicalIncome.setClinicalOperationTypeName(fdClinicalBudgetTemplateTypeCost.getTemplateTypeName());
                    //判断是否为数字
                    if(isNumber(fdClinicalBudgetTemplateTypeCost.getTotal())){
                        clinical=Double.parseDouble(fdClinicalBudgetTemplateTypeCost.getTotal());
                    }
                    fdClinicalIncome.setClinicalOperationTotal(clinical);
                }
            }
            //含税合同金额
            BigDecimal b1 = new BigDecimal(cro);
            BigDecimal b2 = new BigDecimal(croCorrelation);
            BigDecimal b3 = new BigDecimal(clinical);
            fdClinicalIncome.setContractAmountIncludingTax((b1.add(b2).add(b3)).doubleValue());
        }
        ///////项目预算金额
        FdClinicalBudget fdClinicalBudget= iFdClinicalBudgetService.getById(fdClinicalIncome.getClinicalBudgetId());
        if(isNumber(fdClinicalBudget.getClinicalOverpaymentTotalNotTax())){
            fdClinicalIncome.setProjectBudgetAmount(Double.parseDouble(fdClinicalBudget.getClinicalOverpaymentTotalNotTax()));
        }
        ///////医院进度
        fdClinicalIncome.setHospitalProgress(hospitalProgress+"");
        ///////医院成本
        fdClinicalIncome.setHospitalCost(hospitalCost);
        ///////按本月进度确认医院成本
//        BigDecimal hospitalProgressDecimal = new BigDecimal(hospitalProgress/100);
//        BigDecimal hospitalCostDecimal = new BigDecimal(hospitalCost);
        Double thisMonthHospitalCost=(hospitalProgress/100)*hospitalCost;
        fdClinicalIncome.setThisMonthHospitalCost(Double.parseDouble(formatDouble5(thisMonthHospitalCost)));
        ///////累计工时，实际工时
        Double cumulativeWork=0.0;
        String projectTotal=fdWorkingHoursItemsMapper.getProjectTotalByProjectId(fdClinicalIncome.getContractId());
        if(projectTotal!=null&& StringUtils.isNotBlank(projectTotal)){
            fdClinicalIncome.setCumulativeWork(projectTotal);
            fdClinicalIncome.setActualWorkingHours(projectTotal);
            cumulativeWork=Double.parseDouble(projectTotal);
        }
        //如果存在导入工时
        if(isNumber(fdClinicalIncome.getCumulativeWorkExport())){
            cumulativeWork=(getDecimal(cumulativeWork).add(getDecimal(Double.parseDouble(fdClinicalIncome.getCumulativeWorkExport())))).doubleValue();
            fdClinicalIncome.setCumulativeWork(cumulativeWork+"");
        }
        ///////按标准工时确认的工时成本
        Double unitCost=0.0;
        if(isNumber(fdClinicalBudget.getUnitCost())){
            unitCost=Double.parseDouble(fdClinicalBudget.getUnitCost());
        }
        BigDecimal cumulativeWorkDecimal= new BigDecimal(cumulativeWork);
        BigDecimal unitCostDecimal = new BigDecimal(unitCost);
        fdClinicalIncome.setWorkCost((cumulativeWorkDecimal.multiply(unitCostDecimal)).doubleValue());
        ///////累计成本
        getCumulativeCost(fdClinicalIncome);
        ///////完工百分比
        Double percentageOfCompletion=(getDecimal(fdClinicalIncome.getCumulativeCost()).divide(getDecimal(fdClinicalIncome.getProjectBudgetAmount()),2, BigDecimal.ROUND_HALF_UP)).doubleValue();
        fdClinicalIncome.setPercentageOfCompletion(formatDouble5((percentageOfCompletion*100)));
        ///////累计应确认的收入
        getThisMonthAccumulatedRevenueToBeRecognized(fdClinicalIncome);
        ///////本月应确认收入
        Double thisMonthRevenueToBeRecognized=(getDecimal(fdClinicalIncome.getThisMonthAccumulatedRevenueToBeRecognized()).subtract(getDecimal(fdClinicalIncome.getLastMonthAccumulatedRevenueToBeRecognized()))).doubleValue();
        fdClinicalIncome.setThisMonthRevenueToBeRecognized(thisMonthRevenueToBeRecognized);
        ///////本月应确认的医院成本
        Double lastMonthRevenueToBeRecognized=(getDecimal(fdClinicalIncome.getThisMonthHospitalCost()).subtract(getDecimal(fdClinicalIncome.getLastMonthHospitalCost()))).doubleValue();
        fdClinicalIncome.setLastMonthRevenueToBeRecognized(lastMonthRevenueToBeRecognized);
        ///////实际工时占预算工时百分比
        Double clinicalHoursTotal=0.0;
        if(isNumber(fdClinicalBudget.getClinicalHoursTotal())){
            fdClinicalIncome.setBudgetWork(fdClinicalBudget.getClinicalHoursTotal());
            clinicalHoursTotal=Double.parseDouble(fdClinicalBudget.getClinicalHoursTotal());
        }
        fdClinicalIncome.setActualBudgetWorkPercentage(Double.parseDouble(formatDouble5(cumulativeWork/clinicalHoursTotal)));

        //项目实际服务费收入
        getServiceFeeIncome(fdClinicalIncome);
        //项目实际过手费收入
//        getOverchargeIncome(fdClinicalIncome);

    }

    //获取累计成本
    public void getCumulativeCost(FdClinicalIncome fdClinicalIncome){
        //按本月进度医院成本
        Double thisMonthHospitalCost=0.0;
        if(fdClinicalIncome.getThisMonthHospitalCost()!=null){
            thisMonthHospitalCost=fdClinicalIncome.getThisMonthHospitalCost();
        }
        //伦理费
        Double ethicalFee=0.0;
        if(fdClinicalIncome.getEthicalFee()!=null){
            ethicalFee=fdClinicalIncome.getEthicalFee();
        }
        //CRC
        Double crcFee=0.0;
        if(fdClinicalIncome.getCrcFee()!=null){
            crcFee=fdClinicalIncome.getCrcFee();
        }
        //招募
        Double recruitFee=0.0;
        if(fdClinicalIncome.getRecruitFee()!=null){
            recruitFee=fdClinicalIncome.getRecruitFee();
        }
        //报销等其他费用
        Double reimbursementAndOther=0.0;
        if(fdClinicalIncome.getReimbursementAndOther()!=null){
            reimbursementAndOther=fdClinicalIncome.getReimbursementAndOther();
        }
        //按标准工时确认的工时成本
        Double workCost=fdClinicalIncome.getWorkCost();
        //累计成本
        Double cumulativeCost=0.0;
        cumulativeCost= (getDecimal(thisMonthHospitalCost).add(getDecimal(ethicalFee)).add(getDecimal(crcFee)).add(getDecimal(recruitFee)).add(getDecimal(reimbursementAndOther)).add(getDecimal(workCost))).doubleValue();
        fdClinicalIncome.setCumulativeCost(cumulativeCost);
    }
    //累计应确认的收入
    public void getThisMonthAccumulatedRevenueToBeRecognized(FdClinicalIncome fdClinicalIncome){
        //不含税转包费/合同金额
        Double contractAmountIncludingNotTax=0.0;
        if(fdClinicalIncome.getContractAmountIncludingNotTax()!=null){
            contractAmountIncludingNotTax=fdClinicalIncome.getContractAmountIncludingNotTax();
        }
        //完工百分比
        Double percentageOfCompletion=0.0;
        if(isNumber(fdClinicalIncome.getPercentageOfCompletion())){
            percentageOfCompletion=Double.parseDouble(fdClinicalIncome.getPercentageOfCompletion());
        }
        Double thisMonthAccumulatedRevenueToBeRecognized=0.0;
        //如果完工百分比小于100
        if(percentageOfCompletion<100.0){
            thisMonthAccumulatedRevenueToBeRecognized=(getDecimal(percentageOfCompletion/100).multiply(getDecimal(contractAmountIncludingNotTax))).doubleValue();
        }else{//如果大于
            thisMonthAccumulatedRevenueToBeRecognized=contractAmountIncludingNotTax;
        }
        //累计应确认的收入
        fdClinicalIncome.setThisMonthAccumulatedRevenueToBeRecognized(thisMonthAccumulatedRevenueToBeRecognized);
    }

    //项目实际服务费
    public void getServiceFeeIncome(FdClinicalIncome fdClinicalIncome){
        //根据合同号查询尾矿结算数据
        //项目实际服务费含税收入
        LambdaQueryWrapper<FdBalancePaymentSettlement> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FdBalancePaymentSettlement::getDelFlag,"0");
        lambdaQueryWrapper.eq(FdBalancePaymentSettlement::getContractId,fdClinicalIncome.getContractId());
        List<FdBalancePaymentSettlement> fdBalancePaymentSettlementList=iFdBalancePaymentSettlementService.list(lambdaQueryWrapper);
        //循环查出来的数据
        if(fdBalancePaymentSettlementList!=null&&fdBalancePaymentSettlementList.size()>0){
            for(FdBalancePaymentSettlement fdBalancePaymentSettlement:fdBalancePaymentSettlementList){
                //获取尾矿结算金额
                if(StringUtils.isNotBlank(fdBalancePaymentSettlement.getSettlementMoney())&&isNumber(fdBalancePaymentSettlement.getSettlementMoney())){
                    fdClinicalIncome.setServiceFeeIncome(Double.parseDouble(fdBalancePaymentSettlement.getSettlementMoney()));
                }
            }
        }
        //项目实际服务费不含税收入
        //税率
        Double tax=0.0;
        if(isNumber(fdClinicalIncome.getTaxRate())){
            tax=Double.parseDouble(fdClinicalIncome.getTaxRate())/100;
        }
        Double serviceFeeIncomeNotTax=0.0;
        if(fdClinicalIncome.getServiceFeeIncome()!=null){
            serviceFeeIncomeNotTax=Double.parseDouble(formatDouble5(fdClinicalIncome.getServiceFeeIncome()/(1+tax)));
        }
        fdClinicalIncome.setServiceFeeIncomeNotTax(serviceFeeIncomeNotTax);
        //实际工时成本
        fdClinicalIncome.setActualWorkCost(fdClinicalIncome.getWorkCost());
        //服务费毛利
        fdClinicalIncome.setGrossProfitOfServiceFee((getDecimal(serviceFeeIncomeNotTax).subtract(getDecimal(fdClinicalIncome.getActualWorkCost())).doubleValue()));

        //实际服务费毛利率
        Double grossProfitRateOfServiceFee=0.0;
        if(serviceFeeIncomeNotTax!=0.0){
            grossProfitRateOfServiceFee=(getDecimal(fdClinicalIncome.getGrossProfitOfServiceFee()).divide(getDecimal(serviceFeeIncomeNotTax),2, BigDecimal.ROUND_HALF_UP)).doubleValue();
        }
        fdClinicalIncome.setGrossProfitRateOfServiceFee(grossProfitRateOfServiceFee);
        //项目实际过手费
        getOverchargeIncome(fdClinicalIncome,fdBalancePaymentSettlementList);
    }

    //项目实际过手费
    public void getOverchargeIncome(FdClinicalIncome fdClinicalIncome,List<FdBalancePaymentSettlement> fdBalancePaymentSettlementList){
        //获取合同比例金额中的
        LambdaQueryWrapper<FdContractProportion> fdContractProportionLambdaQueryWrapper=new LambdaQueryWrapper<>();
        fdContractProportionLambdaQueryWrapper.eq(FdContractProportion::getContractId,fdClinicalIncome.getContractId());
        List<FdContractProportion> fdContractProportionList=iFdContractProportionService.list(fdContractProportionLambdaQueryWrapper);
        //是否为空
        if(fdContractProportionList!=null&&fdContractProportionList.size()>0){
            Double overchargeIncome=0.0;
            Double totalMoney=0.0;//临床合同金额
            //循环比例
            for(FdContractProportion fdContractProportion:fdContractProportionList){
                //查找临床项目的金额
                if(fdContractProportion.getProportionItem().equals("临床项目")&&StringUtils.isNotBlank(fdContractProportion.getTotalMoney())){
                    totalMoney=Double.parseDouble(fdContractProportion.getTotalMoney());
                }
            }
            //循环尾款结算的数据
            Double clinicalServiceFee=0.0;//临床服务费差价
            Double clinicalPassFee=0.0;//临床过手费差价
            if(fdBalancePaymentSettlementList!=null&&fdBalancePaymentSettlementList.size()>0){
                for(FdBalancePaymentSettlement fdBalancePaymentSettlement:fdBalancePaymentSettlementList){
                    //获取临床服务费差价
                    if(StringUtils.isNotBlank(fdBalancePaymentSettlement.getClinicalServiceFee())&&isNumber(fdBalancePaymentSettlement.getClinicalServiceFee())){
                        clinicalServiceFee=Double.parseDouble(fdBalancePaymentSettlement.getSettlementMoney());
                    }
                    //临床过手费差价
                    if(StringUtils.isNotBlank(fdBalancePaymentSettlement.getClinicalPassFee())&&isNumber(fdBalancePaymentSettlement.getClinicalPassFee())){
                        clinicalPassFee=Double.parseDouble(fdBalancePaymentSettlement.getClinicalPassFee());
                    }
                }
            }
            overchargeIncome=(getDecimal(totalMoney).add(getDecimal(clinicalServiceFee)).add(getDecimal(clinicalPassFee))).doubleValue();
            //项目实际过手费收入
            fdClinicalIncome.setOverchargeIncome(overchargeIncome);
            //项目实际过手费不含税收入
            Double overchargeIncomeNotTax=0.0;
            if(overchargeIncome!=0.0){
                Double preTax=0.0;//税率
                if(isNumber(fdClinicalIncome.getTaxRate())){
                    preTax=Double.parseDouble(fdClinicalIncome.getTaxRate())/100;
                }
                overchargeIncomeNotTax=(getDecimal(overchargeIncome).divide(getDecimal((1+preTax)),2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                fdClinicalIncome.setOverchargeIncomeNotTax(overchargeIncomeNotTax);
            }
            //实际过手费成本
            Double actualPassingFeeCost=0.0;
            actualPassingFeeCost=fdClinicalIncome.getCumulativeCost();
            fdClinicalIncome.setActualPassingFeeCost(actualPassingFeeCost);
            //过手费毛利
            Double GrossProfitOfPassingFee=0.0;
            GrossProfitOfPassingFee=(getDecimal(overchargeIncomeNotTax).subtract(getDecimal(actualPassingFeeCost))).doubleValue();
            fdClinicalIncome.setGrossProfitOfPassingFee(GrossProfitOfPassingFee);
            //实际过手费毛利率
            Double grossProfitRateOfPassingFee=0.0;
            if(overchargeIncomeNotTax!=0.0&&GrossProfitOfPassingFee!=0.0){
                grossProfitRateOfPassingFee=(getDecimal(GrossProfitOfPassingFee).divide(getDecimal(overchargeIncomeNotTax),2, BigDecimal.ROUND_HALF_UP)).doubleValue();
            }
            fdClinicalIncome.setGrossProfitRateOfPassingFee(grossProfitRateOfPassingFee);

        }
    }

    public BigDecimal getDecimal(Double d){
        BigDecimal decimal= new BigDecimal(d);
        return decimal;
    }


    public static String formatDouble5(double d) {
        return String.format("%.2f", d);
    }

    private boolean isNumber(String str){
                if(isEmpty(str)){
                        return false;
                    }
                 String reg = "\\d+(\\.\\d+)?";
                 return str.matches(reg);

     }

    @Override
    public List<FdContract> getContractList() {
        return fdClinicalIncomeMapper.getContractList();
    }


    @Override
    public void export(FdClinicalIncome fdClinicalIncome) {
        List<String> codeList=new ArrayList<>();//储存合同号
        //获取合同号
        if(fdClinicalIncome.getFdClinicalIncomeList()!=null&&fdClinicalIncome.getFdClinicalIncomeList().size()>0){
            for (FdClinicalIncome fdClinicalIncome1:fdClinicalIncome.getFdClinicalIncomeList()){
                codeList.add(fdClinicalIncome1.getCode());
            }

            //获取对应合同号的临床收入确认项目
            LambdaQueryWrapper<FdClinicalIncome> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FdClinicalIncome::getDelFlag,"0");
            lambdaQueryWrapper.in(FdClinicalIncome::getCode,codeList);
            List<FdClinicalIncome> fdClinicalIncomeList=fdClinicalIncomeMapper.selectList(lambdaQueryWrapper);
            //如果不为空
            if(fdClinicalIncomeList!=null&&fdClinicalIncomeList.size()>0){
                for(FdClinicalIncome queryIncome:fdClinicalIncomeList){
                    for(FdClinicalIncome exportIncome:fdClinicalIncome.getFdClinicalIncomeList()){
                        if(queryIncome.getCode().equals(exportIncome.getCode())){
                            if(exportIncome.getEthicalFee()!=null){
                                queryIncome.setEthicalFee(exportIncome.getEthicalFee());
                            }
                            if(exportIncome.getCrcFee()!=null){
                                queryIncome.setCrcFee(exportIncome.getCrcFee());
                            }
                            if(exportIncome.getRecruitFee()!=null){
                                queryIncome.setRecruitFee(exportIncome.getRecruitFee());
                            }
                            if(exportIncome.getReimbursementAndOther()!=null){
                                queryIncome.setReimbursementAndOther(exportIncome.getReimbursementAndOther());
                            }
                            if(StringUtils.isNotBlank(exportIncome.getCumulativeWorkExport())){
//                                Double cumulativeWork=0.0;
//                                //系统的工时和导入的工时是否为数字
//                                if(isNumber(queryIncome.getCumulativeWork())&&isNumber(exportIncome.getCumulativeWork())){
//                                    //系统的工时加导入的工时
//                                    cumulativeWork=(getDecimal(Double.parseDouble(queryIncome.getCumulativeWork())).add(getDecimal(Double.parseDouble(exportIncome.getCumulativeWork())))).doubleValue();
//                                }
                                queryIncome.setCumulativeWorkExport(exportIncome.getCumulativeWorkExport());
                            }
                        }
                    }
                }
                //批量修改
                fdClinicalIncomeMapper.updateFdClincalIncomeBatchByCode(fdClinicalIncomeList);
                //更新项目确认
                refreshProgress();
            }
        }
    }

    @Override
    public void deleteAll(FdClinicalIncome fdClinicalIncome) {
        //删除子表
        deleteChild(fdClinicalIncome);
        //删除主表
        fdClinicalIncome.setDelFlag("1");
        fdClinicalIncomeMapper.updateById(fdClinicalIncome);
    }

    @Override
    public void refreshProgress() {
        //查询所有进行中的收入确认项目
        LambdaQueryWrapper<FdClinicalIncome> fdClinicalIncomeLambdaQueryWrapper=new LambdaQueryWrapper<>();
        fdClinicalIncomeLambdaQueryWrapper.eq(FdClinicalIncome::getDelFlag,"0");
        fdClinicalIncomeLambdaQueryWrapper.eq(FdClinicalIncome::getProjectFileStatus,"1");
        fdClinicalIncomeLambdaQueryWrapper.orderByDesc(FdClinicalIncome::getCreateTime);
        List<FdClinicalIncome> fdClinicalIncomeList=fdClinicalIncomeMapper.selectList(fdClinicalIncomeLambdaQueryWrapper);
        //是否为空
        if(fdClinicalIncomeList!=null&&fdClinicalIncomeList.size()>0){
            List<String> projectFiedIdList=new ArrayList<>();//存储项目档案id
            List<String> clinicalIncomeIdList=new ArrayList<>();//储存临床收入id
            List<String> clinicalBudgetIdList=new ArrayList<>();//储存临床预算id
            //循环收入确认的项目获取项目档案id
            for(FdClinicalIncome fdClinicalIncome:fdClinicalIncomeList){
                projectFiedIdList.add(fdClinicalIncome.getProjectFileId());
                clinicalIncomeIdList.add(fdClinicalIncome.getId());
                clinicalBudgetIdList.add(fdClinicalIncome.getClinicalBudgetId());
            }
            //获取需要跟新临床收入的对应子表预算成本明细
            getClincalIncomeItems(fdClinicalIncomeList,clinicalIncomeIdList);
            //获取对应项目档案信息
            //            List<FdClinicalIncome> fdClinicalIncomeListByFiedId=fdClinicalIncomeMapper.getByProjectIdBatch(projectFiedIdList);
            LambdaQueryWrapper<FdProjectFile> fileLambdaQueryWrapper=new LambdaQueryWrapper<>();
            fileLambdaQueryWrapper.eq(FdProjectFile::getDelFlag,"0");
            fileLambdaQueryWrapper.in(FdProjectFile::getId,projectFiedIdList);
            List<FdProjectFile> fdProjectFileList= iFdProjectFileService.list(fileLambdaQueryWrapper);
            //是否为空
            if(fdProjectFileList!=null&&fdProjectFileList.size()>0){
                //删除更新之前的数据
                deleteFdClincalIncomeBatch(fdClinicalIncomeLambdaQueryWrapper);
                //循环收入确认项目
                for(FdClinicalIncome fdClinicalIncome:fdClinicalIncomeList){
                    //循环对应项目档案
                    for(FdProjectFile fdProjectFile:fdProjectFileList){
                        //获取项目档案最新状态
                        if(fdClinicalIncome.getProjectFileId().equals(fdProjectFile.getId())){
                            fdClinicalIncome.setProjectFileStatus(fdProjectFile.getStatus());
                        }
                    }
                    //只在二十号更新上月进度
                    Calendar now = Calendar.getInstance();
                    int day=now.get(Calendar.DAY_OF_MONTH);
                    if(day==20){
                        //获取按上月进度确认医院成本
                        fdClinicalIncome.setLastMonthHospitalCost(fdClinicalIncome.getThisMonthHospitalCost());
                        //获取截止上月已确认的收入
                        fdClinicalIncome.setLastMonthAccumulatedRevenueToBeRecognized(fdClinicalIncome.getThisMonthAccumulatedRevenueToBeRecognized());
                    }else{
                        //获取按上月进度确认医院成本
                        fdClinicalIncome.setLastMonthHospitalCost(fdClinicalIncome.getLastMonthHospitalCost());
                        //获取截止上月已确认的收入
                        fdClinicalIncome.setLastMonthAccumulatedRevenueToBeRecognized(fdClinicalIncome.getLastMonthAccumulatedRevenueToBeRecognized());
                    }
                    //id清空
                    fdClinicalIncome.setId(null);
                    //修改人设置
                    SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
                    fdClinicalIncome.setUpdateBy(user.getUsername());
                    //修改时间设置
                    fdClinicalIncome.setUpdateTime(new Date());
                    //获取项目变化数据
                    getProjectChangeData(fdClinicalIncome);
                }
                //保存更新之后数据
                iFdClinicalIncomeService.saveBatch(fdClinicalIncomeList);
                //更新明细成本子表并保存
                getClinicalBudgetHandoverfeeItems(fdClinicalIncomeList,clinicalBudgetIdList);
            }
        }
    }



    //获取需要跟新临床收入的对应子表预算成本明细
    public void getClincalIncomeItems(List<FdClinicalIncome> fdClinicalIncomeList,List<String> clinicalIncomeIdList){
        //临床收入id是否为空
        if(clinicalIncomeIdList!=null&&clinicalIncomeIdList.size()>0){
            //查询需要跟新的预算成本数据
            LambdaQueryWrapper<FdClinicalIncomeBudgetCost> fdClinicalIncomeBudgetCostLambdaQueryWrapper=new LambdaQueryWrapper<>();
            fdClinicalIncomeBudgetCostLambdaQueryWrapper.eq(FdClinicalIncomeBudgetCost::getDelFlag,"0");
            fdClinicalIncomeBudgetCostLambdaQueryWrapper.in(FdClinicalIncomeBudgetCost::getClinicalIncomeId,clinicalIncomeIdList);
            List<FdClinicalIncomeBudgetCost> fdClinicalIncomeBudgetCostList=fdClinicalIncomeBudgetCostMapper.selectList(fdClinicalIncomeBudgetCostLambdaQueryWrapper);
            //判断预算成本数据是否为空
            if(fdClinicalIncomeBudgetCostList!=null&&fdClinicalIncomeBudgetCostList.size()>0){
                //临床收入项目是否为空
                if(fdClinicalIncomeList!=null&&fdClinicalIncomeList.size()>0){
                    //循环临床收入主表集合
                    for(FdClinicalIncome fdClinicalIncome:fdClinicalIncomeList){
                        List<FdClinicalIncomeBudgetCost> fdClinicalIncomeBudgetCostListAdd=new ArrayList<>();//用于储存对应临床收入下的预算成本明细
                        //循环临床收入确认
                        for(FdClinicalIncomeBudgetCost budgetCost:fdClinicalIncomeBudgetCostList){
                            //根据外键id找到对应的明细
                            if(fdClinicalIncome.getId().equals(budgetCost.getClinicalIncomeId())){
                                fdClinicalIncomeBudgetCostListAdd.add(budgetCost);
                            }
                        }
                        //保存到对应临床收入对象中
                        fdClinicalIncome.setFdClinicalIncomeBudgetCostList(fdClinicalIncomeBudgetCostListAdd);
                    }
                }
            }



        }
    }

    //更新明细成本子表并保存
    public void getClinicalBudgetHandoverfeeItems(List<FdClinicalIncome> fdClinicalIncomeList,List<String> clinicalBudgetIdList){
        //临床预算id是否为空
        if(clinicalBudgetIdList!=null&&clinicalBudgetIdList.size()>0){
            //查询需要更新临床收入中临床预算中的过手费明细
           LambdaQueryWrapper<FdClinicalBudgetHandoverfeeItems> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FdClinicalBudgetHandoverfeeItems::getDelFlag,"0");
            lambdaQueryWrapper.in(FdClinicalBudgetHandoverfeeItems::getClinicalBudgetId,clinicalBudgetIdList);
            List<FdClinicalBudgetHandoverfeeItems> fdClinicalBudgetHandoverfeeItemsList=iFdClinicalBudgetHandoverfeeItemsService.list(lambdaQueryWrapper);
            //临床预算中的过手费明细是否为空
            if(fdClinicalBudgetHandoverfeeItemsList!=null&&fdClinicalBudgetHandoverfeeItemsList.size()>0){
                //临床收入数据集合是否为空
                if(fdClinicalIncomeList!=null&&fdClinicalIncomeList.size()>0){
                    //循环预算成本明细
                    List<FdClinicalIncomeBudgetCost> fdClinicalIncomeBudgetCostListAdd=new ArrayList<>();
                    //循环临床收入
                    for(FdClinicalIncome fdClinicalIncome:fdClinicalIncomeList){
                        //找到预算成本明细
                        if(fdClinicalIncome.getFdClinicalIncomeBudgetCostList()!=null&&fdClinicalIncome.getFdClinicalIncomeBudgetCostList().size()>0){

                            for(FdClinicalIncomeBudgetCost budgetCost:fdClinicalIncome.getFdClinicalIncomeBudgetCostList()){

                                //预算成本
                                getUpdateFdClinicalIncomeBudgetCost(fdClinicalIncome,budgetCost,fdClinicalBudgetHandoverfeeItemsList);

                                //获取实际成本
                                //伦理费
                                if(budgetCost.getCostOverchargeId().equals("0")){
                                    budgetCost.setActualCost(fdClinicalIncome.getEthicalFee());
                                }
                                //临床中心操作费
                                if(budgetCost.getCostOverchargeId().equals("1")){
                                    budgetCost.setActualCost(fdClinicalIncome.getHospitalCost());
                                }
                                //crc
                                if(budgetCost.getCostOverchargeId().equals("2")){
                                    budgetCost.setActualCost(fdClinicalIncome.getCrcFee());
                                }
                                //受试者招募费
                                if(budgetCost.getCostOverchargeId().equals("3")){
                                    budgetCost.setActualCost(fdClinicalIncome.getRecruitFee());
                                }
                                //报销等其他费用
                                if(budgetCost.getCostOverchargeId().equals("6")){
                                    budgetCost.setActualCost(fdClinicalIncome.getReimbursementAndOther());
                                }
                                //实际成本/预算成本
                                Double getBudgetCost=budgetCost.getBudgetCost();
                                Double getActualCost=budgetCost.getActualCost();
                                String actualBudgetCostPercentage=formatDouble5(getActualCost/getBudgetCost);
                                if(isNumber(actualBudgetCostPercentage)){
                                    budgetCost.setActualBudgetCostPercentage(Double.parseDouble(actualBudgetCostPercentage));
                                }else{
                                    budgetCost.setActualBudgetCostPercentage(0.0);
                                }

                                //修改更新后的明细外键等数据,储存
                                getFdClinicalIncomeBudgetCostListAdd(fdClinicalIncome,budgetCost,fdClinicalIncomeBudgetCostListAdd);
                            }
                        }
                    }
                    //批量保存明细
                    iFdClinicalIncomeBudgetCostService.saveBatch(fdClinicalIncomeBudgetCostListAdd);
                }
            }
        }
    }

    //更新明细成本
    public void getUpdateFdClinicalIncomeBudgetCost(FdClinicalIncome fdClinicalIncome,FdClinicalIncomeBudgetCost budgetCost,List<FdClinicalBudgetHandoverfeeItems> fdClinicalBudgetHandoverfeeItemsList){
        BigDecimal other=new BigDecimal(0.0);//其他的成本合计
        //循环临床预算中的过手费明细
        for(FdClinicalBudgetHandoverfeeItems feeItem:fdClinicalBudgetHandoverfeeItemsList){
            //找到对应的明细
            if(fdClinicalIncome.getClinicalBudgetId().equals(feeItem.getClinicalBudgetId())&&budgetCost.getCostOverchargeId().equals(feeItem.getCostOverchargeId())){
                //是否为数字
                if(isNumber(feeItem.getCostNotTax())){
                    //获取最新的预算成本
                    budgetCost.setBudgetCost(Double.parseDouble(feeItem.getCostNotTax()));
                }
            }
            //如果为其他
            if(fdClinicalIncome.getClinicalBudgetId().equals(feeItem.getClinicalBudgetId())&&budgetCost.getCostOverchargeId().equals("6")){
                if(feeItem.getCostOverchargeId().equals("4")
                        ||feeItem.getCostOverchargeId().equals("5")
                        ||feeItem.getCostOverchargeId().equals("6")){
                    //是否为数字
                    if(isNumber(feeItem.getCostNotTax())){
                        other=other.add(getDecimal(Double.parseDouble(feeItem.getCostNotTax())));
                    }
                }
            }
        }
        //其他
        if(budgetCost.getCostOverchargeId().equals("6")){
            //获取最新的预算成本
            budgetCost.setBudgetCost(other.doubleValue());
        }
    }

    //保存明细成本
    public void getFdClinicalIncomeBudgetCostListAdd(FdClinicalIncome fdClinicalIncome,FdClinicalIncomeBudgetCost budgetCost,List<FdClinicalIncomeBudgetCost> fdClinicalIncomeBudgetCostListAdd){

        budgetCost.setId(null);
        budgetCost.setClinicalIncomeId(fdClinicalIncome.getId());
        budgetCost.setUpdateTime(new Date());
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        budgetCost.setUpdateBy(user.getUsername());
        fdClinicalIncomeBudgetCostListAdd.add(budgetCost);
    }

    //删除更新之前的收入确认项目
    public void deleteFdClincalIncomeBatch(LambdaQueryWrapper<FdClinicalIncome> fdClinicalIncomeLambdaQueryWrapper){
        FdClinicalIncome fdClinicalIncome=new FdClinicalIncome();
        fdClinicalIncome.setDelFlag("1");
        fdClinicalIncomeMapper.update(fdClinicalIncome,fdClinicalIncomeLambdaQueryWrapper);
    }


    @Override
    public List<FdClinicalIncome> exportMain() {
        return fdClinicalIncomeMapper.exportMain();
    }
}
