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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.modules.basedata.entity.FdMatrixType;
import org.jeecg.modules.basedata.mapper.FdMatrixTypeMapper;
import org.jeecg.modules.financeManage.entity.FdSampleStorageRevenueRecognition;
import org.jeecg.modules.financeManage.mapper.FdSampleStorageRevenueRecognitionMapper;
import org.jeecg.modules.financeManage.service.IFdSampleStorageRevenueRecognitionService;
import org.jeecg.modules.projectManagement.entity.FdContract;
import org.jeecg.modules.projectManagement.entity.FdProjectFile;
import org.jeecg.modules.projectManagement.entity.FdProjectQuotationTemplateItem;
import org.jeecg.modules.projectManagement.mapper.FdProjectQuotationTemplateItemMapper;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

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

/**
 * @Description: 样本储存收入确认
 * @author： jeecg-boot
 * @date：   2020-08-10
 * @version： V1.0
 */
@Transactional
@Service
public class FdSampleStorageRevenueRecognitionServiceImpl extends ServiceImpl<FdSampleStorageRevenueRecognitionMapper, FdSampleStorageRevenueRecognition> implements IFdSampleStorageRevenueRecognitionService {

    @Resource
    IFdSampleStorageRevenueRecognitionService iFdSampleStorageRevenueRecognitionService;
    @Resource
    FdSampleStorageRevenueRecognitionMapper fdSampleStorageRevenueRecognitionMapper;
    @Resource
    ISysDictService iSysDictService;
    @Resource
    IFdProjectFileService iFdProjectFileService;
    @Resource
    IFdContractService iFdContractService;
    @Resource
    FdProjectQuotationTemplateItemMapper fdProjectQuotationTemplateItemMapper;
    @Resource
    FdMatrixTypeMapper fdMatrixTypeMapper;

    @Override
    public void addCustom(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition) {
        //获取时间以及相关金额
        getAmortizationTimeAndMoney(fdSampleStorageRevenueRecognition);
        fdSampleStorageRevenueRecognitionMapper.insert(fdSampleStorageRevenueRecognition);
    }




    @Override
    public void sampleStorageTriggerAdd(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition) {
        //项目档案数据
//        FdProjectFile fdProjectFile=iFdProjectFileService.getById(fdSampleStorageRevenueRecognition.getProjectFileId());
//        fdSampleStorageRevenueRecognition.setLabAddressId(fdProjectFile.getLabAddress());//实验地址id
//        fdSampleStorageRevenueRecognition.setPfStatusId(fdProjectFile.getStatus());//状态
        //项目档案数据
        FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognitionResult=fdSampleStorageRevenueRecognitionMapper.getByProjectId(fdSampleStorageRevenueRecognition.getProjectFileId());
        fdSampleStorageRevenueRecognition.setLabAddressId(fdSampleStorageRevenueRecognitionResult.getLabAddressId());//实验地址id
        fdSampleStorageRevenueRecognition.setPfStatusId(fdSampleStorageRevenueRecognitionResult.getPfStatusId());//状态
        fdSampleStorageRevenueRecognition.setTaxRate(fdSampleStorageRevenueRecognitionResult.getTaxRate());//税率
        fdSampleStorageRevenueRecognition.setQuotationId(fdSampleStorageRevenueRecognitionResult.getQuotationId());//报价id

        //获取项目的相关数据
        getProjectData(fdSampleStorageRevenueRecognition);
        //保存
        addCustom(fdSampleStorageRevenueRecognition);
    }

    @Override
    public void sampleStorageTriggerUpdate(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition) {
        //项目档案数据
        FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognitionResult=fdSampleStorageRevenueRecognitionMapper.getByProjectId(fdSampleStorageRevenueRecognition.getProjectFileId());
        fdSampleStorageRevenueRecognition.setLabAddressId(fdSampleStorageRevenueRecognitionResult.getLabAddressId());//实验地址id
        fdSampleStorageRevenueRecognition.setPfStatusId(fdSampleStorageRevenueRecognitionResult.getPfStatusId());//状态
        fdSampleStorageRevenueRecognition.setTaxRate(fdSampleStorageRevenueRecognitionResult.getTaxRate());//税率
        fdSampleStorageRevenueRecognition.setQuotationId(fdSampleStorageRevenueRecognitionResult.getQuotationId());//报价id

        //获取项目的相关数据
        getProjectData(fdSampleStorageRevenueRecognition);

        updateCustom(fdSampleStorageRevenueRecognition);
    }


    //获取项目的相关数据
    public void getProjectData(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition){
        //合同数据
//        FdContract fdContract=iFdContractService.getById(fdSampleStorageRevenueRecognition.getContractId());
//        fdSampleStorageRevenueRecognition.setTaxRate(fdContract.getTaxRate());//税率

        //获取实验室地点名称与状态名称
        getLabAddressName(fdSampleStorageRevenueRecognition);
        //获取样本存储费
        getSampleStorageFee(fdSampleStorageRevenueRecognition);
        //结算状态
        fdSampleStorageRevenueRecognition.setSettlementStatusId("1");
        fdSampleStorageRevenueRecognition.setSettlementStatusName("未结算");
    }

    //获取实验室地点
    public void getLabAddressName(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition){
        if(StringUtils.isNotBlank(fdSampleStorageRevenueRecognition.getLabAddressId())){
            //获取实验地点的数据字典数据
            List<Map<String, Object>> dictList= iSysDictService.queryDictItemsByCode("biological_analysis_laboratory_location");
            //判断是否为空
            if(dictList!=null){
                for(Map<String, Object> map:dictList){
                    //根据id找到对应的名称
                    if(fdSampleStorageRevenueRecognition.getLabAddressId().equals(map.get("value"))){
                        fdSampleStorageRevenueRecognition.setLabAddressName(map.get("text")+"");
                    }
                }
            }
        }

        if(StringUtils.isNotBlank(fdSampleStorageRevenueRecognition.getPfStatusId())){
            //获取项目档案的数据字典数据
            List<Map<String, Object>> dictList= iSysDictService.queryDictItemsByCode("file_starts");
            //判断是否为空
            if(dictList!=null){
                for(Map<String, Object> map:dictList){
                    //根据id找到对应的名称
                    if(fdSampleStorageRevenueRecognition.getPfStatusId().equals(map.get("value"))){
                        fdSampleStorageRevenueRecognition.setPfStatusName(map.get("text")+"");
                    }
                }
            }
        }

    }

    //获取样本存储费
    public void getSampleStorageFee(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition){

        //化合物名称
        String[] compounds=fdSampleStorageRevenueRecognition.getCompoundName().split(",");
        //基质名称
        String[] maxtris=fdSampleStorageRevenueRecognition.getMatrixTypeName().split("、");
        //模板类型
        List<String> types=new ArrayList<>();
        types.add("5");
        types.add("6");
        //模板数据
        List<FdProjectQuotationTemplateItem> fdProjectQuotationTemplateItemList=fdProjectQuotationTemplateItemMapper.getItemAndTempByQuotation(fdSampleStorageRevenueRecognition.getQuotationId(),types);
        Double sampleStorageFeeNotTax=0.00;//样本存储含税
        //获取岩本存储费
        if(fdProjectQuotationTemplateItemList!=null&&fdProjectQuotationTemplateItemList.size()>0&&compounds!=null&&maxtris!=null){
            for(FdProjectQuotationTemplateItem item:fdProjectQuotationTemplateItemList){//循环模板数据
                //只是样本存储费的才获取费用
                if(item.getName().indexOf("样本存储费")!=-1||item.getName().indexOf("Sample storage fee")!=-1){
                    String templateName = item.getQuotationTemplateName();//报价模板名称
                    String[] templateNames = templateName.split("-");
                    if(templateNames!=null&&templateNames.length>2){
                        for(String compoundName:compounds){//循环化合物
                            for(String maxtri:maxtris){//循环基质
                                //找到对应化合物对应基质的样本存储费
                                if(compoundName.equals(templateNames[1])&&maxtri.equals(templateNames[2])){
                                    if(isNumber(item.getFeeCategory1Contract())){//判断是否为数字
                                        //累加样本存储费
                                        sampleStorageFeeNotTax=(getDecimal(sampleStorageFeeNotTax).add(getDecimal(Double.parseDouble(item.getFeeCategory1Contract())))).doubleValue();
                                    }
                                    if(isNumber(item.getFeeCategory2Contract())){//判断是否为数字
                                        //累加样本存储费
                                        sampleStorageFeeNotTax=(getDecimal(sampleStorageFeeNotTax).add(getDecimal(Double.parseDouble(item.getFeeCategory2Contract())))).doubleValue();
                                    }
                                    //样本存储描述
                                    fdSampleStorageRevenueRecognition.setSampleStorageDescription(item.getName());
                                }
                            }
                        }
                    }
                }
            }
        }
        //不含税样本存储费
        fdSampleStorageRevenueRecognition.setSampleStorageFeeNotTax(sampleStorageFeeNotTax);
        //含税样本存储费
        Double sampleStorageFeeTax=0.00;
        if(isNumber(fdSampleStorageRevenueRecognition.getTaxRate())){
            Double taxRate=1+(Double.parseDouble(fdSampleStorageRevenueRecognition.getTaxRate())/100);
            sampleStorageFeeTax=(getDecimal(sampleStorageFeeNotTax).multiply(getDecimal(taxRate))).doubleValue();
        }
        fdSampleStorageRevenueRecognition.setSampleStorageFeeTax(sampleStorageFeeTax);
    }

    //获取摊销时间累计金额等数据
    public void getAmortizationTimeAndMoney(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition){
        //如果开始日期和截止日期都不为空
        if(fdSampleStorageRevenueRecognition.getStartConfirmationDate()!=null&&fdSampleStorageRevenueRecognition.getEndConfirmationDate()!=null){
            //获取两个时间之间相隔多少月
            int amortizationTime =countMonths(fdSampleStorageRevenueRecognition.getStartConfirmationDate(),fdSampleStorageRevenueRecognition.getEndConfirmationDate());
            fdSampleStorageRevenueRecognition.setAmortizationTime(amortizationTime+"");
            //按月摊销的收入
            Double incomeMonth=0.00;
            if(fdSampleStorageRevenueRecognition.getSampleStorageFeeNotTax()!=null){
                incomeMonth=(getDecimal(fdSampleStorageRevenueRecognition.getSampleStorageFeeNotTax()).divide(getDecimal(Double.valueOf(amortizationTime)),2, BigDecimal.ROUND_HALF_UP)).doubleValue();
            }
            fdSampleStorageRevenueRecognition.setIncomeMonth(incomeMonth);
            //获取开始时间与现在时间之间的所有日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            List<String> dateList=getBetweenTime(sdf.format(fdSampleStorageRevenueRecognition.getStartConfirmationDate()),sdf.format(new Date()));
            int cumulativeConfirmationMonth=0;//累计确认月份
            //循环时间段有多少个20号
            if(dateList!=null&&dateList.size()>0){
//                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                for(String date:dateList){
                    try {
                        Date toDate=sdf.parse(date);
                        Integer day=Integer.parseInt(String .format("%td", toDate));//日
                        if(day==20){
                            cumulativeConfirmationMonth++;
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                }
            }
            fdSampleStorageRevenueRecognition.setCumulativeConfirmationMonth(cumulativeConfirmationMonth+"");
            //累计确认金额
            Double accumulatedConfirmedAmount=0.00;
            accumulatedConfirmedAmount=(getDecimal(Double.valueOf(cumulativeConfirmationMonth)).multiply(getDecimal(incomeMonth))).doubleValue();
            fdSampleStorageRevenueRecognition.setAccumulatedConfirmedAmount(accumulatedConfirmedAmount);
            //收入确认月份
            Integer mon=Integer.parseInt(String .format("%tm", new Date()));//月
            fdSampleStorageRevenueRecognition.setIncomeDateMonth(mon+"");
        }
    }


    @Override
    public FdSampleStorageRevenueRecognition getFdSampleStorageRevenueRecognitionByProjectId(String projectId) {
        //项目档案数据
        FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognitionResult=fdSampleStorageRevenueRecognitionMapper.getByProjectId(projectId);
        //获取合同方
        if(StringUtils.isNotBlank(fdSampleStorageRevenueRecognitionResult.getContractPartyId())){
            //获取合同方的数据字典数据
            List<Map<String, Object>> dictList= iSysDictService.queryDictItemsByCode("contract_square");
            //判断是否为空
            if(dictList!=null){
                for(Map<String, Object> map:dictList){
                    //根据id找到对应的名称
                    if(fdSampleStorageRevenueRecognitionResult.getContractPartyId().equals(map.get("value"))){
                        fdSampleStorageRevenueRecognitionResult.setContractPartyName(map.get("text")+"");
                    }
                }
            }
        }
        //获取基质类型
        //获取id
        List<String> list4 = Arrays.asList(fdSampleStorageRevenueRecognitionResult.getMatrixTypeId().split(","));
        //根据id获取对象
        List<FdMatrixType> typeList = fdMatrixTypeMapper.selectBatchIds(list4);
        String maxtrixName="";//储存基质名称
        if(typeList!=null&&typeList.size()>0){
            for(FdMatrixType fdMatrixType:typeList){
                if(maxtrixName.equals("")){
                    maxtrixName=fdMatrixType.getName();
                }else{
                    maxtrixName=maxtrixName+"、"+fdMatrixType.getName();
                }
            }
        }
        fdSampleStorageRevenueRecognitionResult.setMatrixTypeName(maxtrixName);
        //相关结算状态
        getProjectData(fdSampleStorageRevenueRecognitionResult);
        return fdSampleStorageRevenueRecognitionResult;
    }

    @Override
    public void updateCustom(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition) {
        //获取时间以及相关金额
        getAmortizationTimeAndMoney(fdSampleStorageRevenueRecognition);
        fdSampleStorageRevenueRecognitionMapper.updateById(fdSampleStorageRevenueRecognition);
    }

    @Override
    public void monthlyUpdate() {

        //获取上月未结算的数据
        LambdaQueryWrapper<FdSampleStorageRevenueRecognition> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FdSampleStorageRevenueRecognition::getDelFlag,"0");
        lambdaQueryWrapper.eq(FdSampleStorageRevenueRecognition::getSettlementStatusId,"1");
        lambdaQueryWrapper.orderByDesc(FdSampleStorageRevenueRecognition::getCreateTime);
        List<FdSampleStorageRevenueRecognition> fdSampleStorageRevenueRecognitionList=fdSampleStorageRevenueRecognitionMapper.selectList(lambdaQueryWrapper);
        //判断是否为空
        if(fdSampleStorageRevenueRecognitionList!=null&&fdSampleStorageRevenueRecognitionList.size()>0){
            //删除上月未结算数据
            FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognitionDelete=new FdSampleStorageRevenueRecognition();
            fdSampleStorageRevenueRecognitionDelete.setDelFlag("1");
            fdSampleStorageRevenueRecognitionMapper.update(fdSampleStorageRevenueRecognitionDelete,lambdaQueryWrapper);
            for(FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognition:fdSampleStorageRevenueRecognitionList){
                //获取最新状态
                FdSampleStorageRevenueRecognition fdSampleStorageRevenueRecognitionResult=fdSampleStorageRevenueRecognitionMapper.getByProjectId(fdSampleStorageRevenueRecognition.getProjectFileId());
                fdSampleStorageRevenueRecognition.setPfStatusId(fdSampleStorageRevenueRecognitionResult.getPfStatusId());//状态
                //获取上月的确认金额
                Calendar now = Calendar.getInstance();
                int day=now.get(Calendar.DAY_OF_MONTH);
                if(day==20){//二十号才执行覆盖上月金额
                    fdSampleStorageRevenueRecognition.setAccumulatedConfirmedAmountLast(fdSampleStorageRevenueRecognition.getAccumulatedConfirmedAmount());
                }
                //获取当前操作人
                SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
                fdSampleStorageRevenueRecognition.setId(null);
                fdSampleStorageRevenueRecognition.setUpdateBy(user.getUsername());
                fdSampleStorageRevenueRecognition.setUpdateTime(new Date());
                //修改
                addCustom(fdSampleStorageRevenueRecognition);
            }
        }
    }




    //获取两个时间相隔得月数
    public static int countMonths(Date date1, Date date2){
//        SimpleDateFormat sdf=new SimpleDateFormat(pattern);
        Calendar c1=Calendar.getInstance();
        Calendar c2=Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        int year =c2.get(Calendar.YEAR)-c1.get(Calendar.YEAR);
        //开始日期若小月结束日期
        if(year<0){
            year=-year;
            return year*12+c1.get(Calendar.MONTH)-c2.get(Calendar.MONTH);
        }
        return year*12+c2.get(Calendar.MONTH)-c1.get(Calendar.MONTH);
    }

    //获取两个时间的时间段
    public static List<String> getBetweenTime(String starttime,String endtime)
    {
        List<String> betweenTime = new ArrayList<String>();
        try
        {
            Date sdate= new SimpleDateFormat("yyyy-MM-dd").parse(starttime);
            Date edate= new SimpleDateFormat("yyyy-MM-dd").parse(endtime);

            SimpleDateFormat outformat = new SimpleDateFormat("yyyy-MM-dd");

            Calendar sCalendar = Calendar.getInstance();
            sCalendar.setTime(sdate);
            int year = sCalendar.get(Calendar.YEAR);
            int month = sCalendar.get(Calendar.MONTH);
            int day = sCalendar.get(Calendar.DATE);
            sCalendar.set(year, month, day, 0, 0, 0);

            Calendar eCalendar = Calendar.getInstance();
            eCalendar.setTime(edate);
            year = eCalendar.get(Calendar.YEAR);
            month = eCalendar.get(Calendar.MONTH);
            day = eCalendar.get(Calendar.DATE);
            eCalendar.set(year, month, day, 0, 0, 0);

            while (sCalendar.before(eCalendar))
            {
                betweenTime.add(outformat.format(sCalendar.getTime()));
                sCalendar.add(Calendar.DAY_OF_YEAR, 1);
            }
            betweenTime.add(outformat.format(eCalendar.getTime()));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return betweenTime;
    }

    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);

    }
}
