/**************************************************************************************************
@Author: Denny陈帮才
@Name: SummaryThreeYearsContractBatch
@CreateDate: 24/08/2022
@Description: 汇总3年内合同历史 //每一年都要算（合同时间那一年维修金额 ）//过去第三年、过去第二年、过去一年合同金额
@Version 1.0
*****************************************************************************************************/
global class SummaryThreeYearsContractBatch implements Database.Batchable<sObject>,Database.Stateful {
    public String query;
    public List < String > accountIdList;
    private BatchIF_Log__c iflog;
    public Date nowDt =Date.today();
    public String OCSM_Period_half;
    public String OCSM_Period = 'FY'+(nowDt.year()+1);
    public Date sTime;
    public Date eTime;
    public Date firYEnd;
    public Date secYEnd;

    global SummaryThreeYearsContractBatch() {
        this.query = query;
    }
    global SummaryThreeYearsContractBatch(List < String > accountIdList) {
        this.accountIdList = accountIdList;
    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        system.debug('执行start');
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushNotification';
        iflog.Log__c  = 'SummaryThreeYearsContractBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;

        if(nowDt.month() >= 4){
            sTime = Date.newInstance(nowDt.year()-3,4,1);
            firYEnd = Date.newInstance(nowDt.year()-2,3,31);
            secYEnd = Date.newInstance(nowDt.year()-1,3,31);
            eTime = Date.newInstance(nowDt.year(),3,31);
            
        }else{
            sTime = Date.newInstance(nowDt.year()-4,4,1);
            firYEnd = Date.newInstance(nowDt.year()-3,3,31);
            secYEnd = Date.newInstance(nowDt.year()-2,3,31);
            eTime = Date.newInstance(nowDt.year()-1,3,31);
        }
        //查询三个财年内是否有维修合同的医院
        query ='select Id, Hospital__c from Maintenance_Contract__c where ((Contract_End_Date__c>=:sTime and Contract_End_Date__c<=:eTime) or (Contract_Start_Date__c >=:sTime and Contract_Start_Date__c <=:eTime) or(Contract_Start_Date__c <:sTime and Contract_End_Date__c>:eTime)) and RecordType.Name!=\'多年保修合同\' ';
        if (accountIdList != null && accountIdList.size() > 0) {
            query += ' AND Hospital__c IN :accountIdList ';
        }
        System.debug(LoggingLevel.INFO, '*** query: ' + query); 
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Maintenance_Contract__c> scope) {
        System.debug(LoggingLevel.INFO, '*** excute start: ' );
        if (nowDt.month() >= 4 && nowDt.month() <= 9) {
            OCSM_Period_half = '1H';
        }else{
            OCSM_Period_half = '2H';
        }
        System.debug(LoggingLevel.INFO, '*** the OCSM_Period_half__c: ' + OCSM_Period_half);
        //获取维修合同Id、Hospital
        List<Id> hosId = new List<Id>();
        List<Id> mainId = new List<Id>();
        for (Maintenance_Contract__c mcc : scope) {
            hosId.add(mcc.Hospital__c);
            mainId.add(mcc.Id);
        }

        //服务客户目标对象里 医院在scope里以及年份等于查询年份的
        List<Account_Service_Of_Target__c> asotList = [select Id,Account_HP__c 
                                                    from Account_Service_Of_Target__c 
                                                    where Account_HP__c in: hosId 
                                                    and OCSM_Period_half__c = :OCSM_Period_half
                                                    and OCSM_Period__c = :OCSM_Period];
        Map<Id,Account_Service_Of_Target__c> oldMap = new Map<Id,Account_Service_Of_Target__c>();
        for (Account_Service_Of_Target__c ast : asotList) {
            oldMap.put(ast.Account_HP__c,ast);
        }
        
        // //汇总医院维修合同数量
        AggregateResult[] aggResult = [SELECT Hospital__c,COUNT(Id)countalias
                                       FROM Maintenance_Contract__c WHERE Id IN: mainId 
                                       group by Hospital__c];   
        Map<Id,Decimal> countMap = new Map<Id,Decimal>();

        for (AggregateResult ass : aggResult ) {
            Id  assId= (Id)ass.get('Hospital__c');
            Decimal Defir = (Decimal)ass.get('countalias');
            countMap.put(assId, Defir);  
        }

        //过去1、2、3年维修金额
         Map<Id,Decimal> LastYearMap = new Map<Id,Decimal>();
         Map<Id,Decimal> Last2YearMap = new Map<Id,Decimal>();
         Map<Id,Decimal> Last3YearMap = new Map<Id,Decimal>();

         //过去1、2、3年签约合同数量
         Map<Id,Decimal> Last1YearCountMap = new Map<Id,Decimal>();
         Map<Id,Decimal> Last2YearCountMap = new Map<Id,Decimal>();
         Map<Id,Decimal> Last3YearCountMap = new Map<Id,Decimal>();

        //过去一年维修合同金额、签约合同数量（去年）
        AggregateResult[] LastYear = [SELECT Hospital__c,SUM(Contract_Amount__c)sumprices,COUNT(Id)countalias
                                       FROM Maintenance_Contract__c WHERE Id IN: mainId 
                                       AND Contract_Conclusion_Date__c>:secYEnd  //3.31
                                       AND Contract_Conclusion_Date__c<=:eTime   //3.31
                                       group by Hospital__c]; 
        for (AggregateResult ass : LastYear ) {
            Id  assId= (Id)ass.get('Hospital__c');
            Decimal Defir = (Decimal)ass.get('sumprices');
            Decimal MCount = (Decimal)ass.get('countalias');
            LastYearMap.put(assId, Defir); 
            Last1YearCountMap.put(assId,MCount); 
        }

        //过去两年维修合同金额、签约合同数量（前年）
        AggregateResult[] BeforeLastYear = [SELECT Hospital__c,SUM(Contract_Amount__c)sumprices,COUNT(Id)countalias
                                       FROM Maintenance_Contract__c WHERE Id IN: mainId 
                                       AND Contract_Conclusion_Date__c>:firYEnd   //3.31
                                       AND Contract_Conclusion_Date__c<=:secYEnd  //3.31
                                       group by Hospital__c]; 
        for (AggregateResult ass : BeforeLastYear ) {
            Id  assId= (Id)ass.get('Hospital__c');
            Decimal Defir = (Decimal)ass.get('sumprices');
            Decimal MCount = (Decimal)ass.get('countalias');
            Last2YearMap.put(assId, Defir);  
            Last2YearCountMap.put(assId,MCount); 

        }

        //过去三年年维修合同金额、签约合同数量（大前年）
        AggregateResult[] ThreeYearago = [SELECT Hospital__c,SUM(Contract_Amount__c)sumprices,COUNT(Id)countalias
                                       FROM Maintenance_Contract__c WHERE Id IN: mainId 
                                       AND Contract_Conclusion_Date__c>=:sTime  //4.1
                                       AND Contract_Conclusion_Date__c<=:firYEnd  //3.31
                                       group by Hospital__c];
        for (AggregateResult ass : ThreeYearago ) {
            Id  assId= (Id)ass.get('Hospital__c');
            Decimal Defir = (Decimal)ass.get('sumprices');
            Decimal MCount = (Decimal)ass.get('countalias');
            Last3YearMap.put(assId, Defir);  
            Last3YearCountMap.put(assId,MCount); 

        } 

        List<Account_Service_Of_Target__c> asList = new List<Account_Service_Of_Target__c>();
        for (Id mapId : countMap.keySet()) {

            Account_Service_Of_Target__c asItem = new Account_Service_Of_Target__c();
            asItem.Account_HP__c = mapId;

            //过去1、2、3年维修合同数量(按合同日计算)
            // asItem.Last_Years_Contract_Count__c = Last1YearCountMap.get(mapId);
            // asItem.Last_Two_Years_Contract_Count__c = Last2YearCountMap.get(mapId);
            // asItem.Last_Three_Year_Contract_Count__c = Last3YearCountMap.get(mapId);

            //过去第一年合同日是否有合同
            if(Last1YearCountMap.get(mapId)!=0 && Last1YearCountMap.get(mapId)!=null){
                asItem.IF_Last_Years_Contract__c = '1';
            }else{
                asItem.IF_Last_Years_Contract__c = '0';
            }
            //过去第二年合同日是否有合同
            if(Last2YearCountMap.get(mapId)!=0 && Last2YearCountMap.get(mapId)!=null){
                asItem.IF_Last_Two_Years_Contract__c = '1';
            }else{
                asItem.IF_Last_Two_Years_Contract__c = '0';
            }
            //过去第三年合同日是否有合同
            if(Last3YearCountMap.get(mapId)!=0 && Last3YearCountMap.get(mapId)!=null){
                asItem.IF_Last_Three_Years_Contract__c = '1';
            }else{
                asItem.IF_Last_Three_Years_Contract__c = '0';
            }

            asItem.OCSM_Period_half__c = OCSM_Period_half;
            asItem.OCSM_Period__c = OCSM_Period;

            //过去三年是否有签约合同
            asItem.Last_Three_Years_IF_Have_Contract__c = true;
            //过去三年维修合同数量(3个完整财年)
            asItem.Last_Three_Years_Contract_Count_del__c = countMap.get(mapId);

            //过去1、2、3年维修合同金额
            asItem.Last_Years_Contract_Amount__c = LastYearMap.get(mapId);
            asItem.Last_Two_Years_Contract_Amount__c = Last2YearMap.get(mapId);
            asItem.Last_Three_Years_Contract_Amount__c = Last3YearMap.get(mapId);

            if(oldMap.containsKey(asItem.Account_HP__c)){
                asItem.Id = oldMap.get(asItem.Account_HP__c).Id;
            }
            if(!asList.contains(asItem)){
                asList.add(asItem);
            }

        }
        System.debug(LoggingLevel.INFO, '*** asList: ' + asList);
        upsert asList;


        
    }

    global void finish(Database.BatchableContext BC) {
        iflog.Log__c += '\n SummaryThreeYearsContractBatch end';
        String tmp = iflog.ErrorLog__c;
        if (tmp.length() > 65000) {
            tmp = tmp.substring(0, 65000);
            tmp += ' ...have more lines...';
            iflog.ErrorLog__c = tmp;
        }
        update iflog;
    }
}