//当前日期大于OPD计划实施日期 and 状态不等于取消或完毕 and （opd计划下没有任何得备品借出申请 or 或者对应备品借出状态是草案中,申请中,取消时）
//需要创建OPD计划取消延期,更新opd计划
//1.OPD计划取消延期.取消理由是取消成功,2.需要考虑opd计划所有人是否已离职，若离职，取消/延期理由为担当离职，否则为没完成备品申请
// OPD计划延期一次后，在第二个月仍没有分配备品的，OPD计划自动取消，原因为备品不足，同时备品申请自动取消。 ljh 20220929 
global class OPDPlanCancelPostponePlanLogicBatch implements Database.Batchable<sObject>, Database.Stateful {
    //加日志 为了更新历史数据 做一下日志查看 20201124 you start
    private final Id TEST_ID = null;
    private BatchIF_Log__c iflog;
    //加日志 为了更新历史数据 做一下日志查看 20201124 you end
    public String soql = '';
    public String opdId;
    Public Integer opdplannum=0;

    global OPDPlanCancelPostponePlanLogicBatch() {
        this.soql = soql;
        //加日志 为了更新历史数据 做一下日志查看 20201124 you start
        System.debug('TEST_ID=' + TEST_ID);
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushOPDPlanNotification';
        iflog.Log__c  = 'OPDPlanCancelPostponePlanLogicBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
        //加日志 为了更新历史数据 做一下日志查看 20201124 you end
    }

    global OPDPlanCancelPostponePlanLogicBatch(String opdId) {
        this.soql = soql;
        this.opdId = opdId;
        //加日志 为了更新历史数据 做一下日志查看 20201124 you start
        TEST_ID = opdId;
        System.debug('TEST_ID=' + TEST_ID);
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushOPDPlanNotification';
        iflog.Log__c  = 'OPDPlanCancelPostponePlanLogicBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
        //加日志 为了更新历史数据 做一下日志查看 20201124 you end
    }
    //获取状态不是取消 或者 完毕 且OPD计划实施日期小于当前时间的opd计划
    global Database.QueryLocator start(Database.BatchableContext BC) {
        Date dateToday = Date.today();
        system.debug('opdId' + opdId+'=iflog=='+iflog);

        soql  = 'select id,Status__c,name,OPDPlan_ImplementDate__c,Rental_Apply2__c, StayOrNot__c,SystemDelayMark__c ';
        soql += ' from OPDPlan__c';
        soql += ' where Status__c != \'取消\' and Status__c != \'完毕\'';
        soql += ' and (OPDPlan_ImplementDate__c < :dateToday';
        //update by rentx 2021-01-04 SWAG-BWSBW3  增加一条判断，当OPD计划来源是会议时，担当离职不取消。
        // soql += ' or StayOrNot__c = \'已离职\')';
        soql += ' or StayOrNot__c = \'已离职\')';
        //update by rentx 2021-01-04 SWAG-BWSBW3
        
        //update by yc 20210121 start
        soql += ' and OPDType__c != \'学会\'';
        //update by yc 20210121 end
        
        if (String.isNotBlank(this.opdId)) {
            soql += ' and id = \'' + this.opdId + '\'';
        }
        system.debug('soql:' + soql);
        return Database.getQueryLocator(soql);
    }

    global void execute(Database.BatchableContext BC, List<OPDPlan__c> OPDPlanList) {
        //最终更新用OPD计划取消延期List
        List<CancelPostponePlan__c> cppList =  new List<CancelPostponePlan__c>();
        List<OPDPlan__c> OpdRtlList = new List<OPDPlan__c>();
        List<OPDPlan__c>OpdUpList = new List<OPDPlan__c>();
        system.debug('OPDPlanList' + OPDPlanList.size());
        Set<Id> raIdSet = new Set<Id>();// 有保有设备 的一申请书  20221107 ljh update SWAG-CHM5E4
        for (OPDPlan__c op : OPDPlanList) {
            if (op.Rental_Apply2__c != null) {
                // 所有有备品的OPD计划
                OpdRtlList.add(op);
            } else {
                // 可以取消的OPD计划
                OpdUpList.add(op);
            }
        }
        //opdID与OPD计划取消延期Map
        Map<id, Rental_Apply__c> rtlMap  = new Map<id, Rental_Apply__c>();
        Set<Id> rtl3Set  = new Set<Id>();//20221108  ljh update SWAG-CHM5E4
        if (OpdRtlList.size() > 0) {
            //获取OPD计划下的取消延期数据
            //20220920  ljh update SWAG-CHM5E4  start
            List<Rental_Apply_Equipment_Set_Detail__c> raesList =
                [select Rental_Apply__c from Rental_Apply_Equipment_Set_Detail__c where Asset__c != null and Rental_Apply__r.OPDPlan__c in :OpdRtlList];
            for(Rental_Apply_Equipment_Set_Detail__c raes:raesList){
                raIdSet.add(raes.Rental_Apply__c);
            }    
            //20220920  ljh update SWAG-CHM5E4 end
            List<Rental_Apply__c> rtlList =
                [select id, RA_Status__c, OPDPlan__c from Rental_Apply__c where OPDPlan__c in :OpdRtlList];
            //取出备品借出状态不是草案中,申请中,取消的取消延期数据放入map
            for (Rental_Apply__c rtl : rtlList) {
                //20221007  ljh update SWAG-CHM5E4 start
                // if (rtl.RA_Status__c != '草案中' && rtl.RA_Status__c != '申请中' && rtl.RA_Status__c != '取消') {
                //     // OPD计划-所有备品Map
                //     rtlMap.put(rtl.OPDPlan__c, rtl);
                // }
                if (rtl.RA_Status__c == '草案中' || rtl.RA_Status__c == '申请中' || rtl.RA_Status__c == '取消') {
                    // OPD计划-所有备品Map
                    rtl3Set.add(rtl.OPDPlan__c);
                }
                if(raIdSet.contains(rtl.Id)){
                    rtlMap.put(rtl.OPDPlan__c, rtl);
                } 
                //20221007  ljh update SWAG-CHM5E4 end
            }
        }
        Date dateToday1 = Date.today();//20221108  ljh update SWAG-CHM5E4
        //取出可以变更的备品借出申请
        for (OPDPlan__c OpdRt : OpdRtlList) {
            //20221108  ljh update SWAG-CHM5E4 start
            // if (!rtlMap.containskey(OpdRt.Id)) {
            //     OpdUpList.add(OpdRt);
            // }
            if (!rtlMap.containskey(OpdRt.Id) && rtl3Set.contains(OpdRt.Id)) {
                OpdUpList.add(OpdRt);
            }else if(!rtlMap.containskey(OpdRt.Id) && !rtl3Set.contains(OpdRt.Id) && OpdRt.OPDPlan_ImplementDate__c < dateToday1 && OpdRt.SystemDelayMark__c){
                OpdUpList.add(OpdRt);
            }
            //20221108  ljh update SWAG-CHM5E4 end
        }
        // Date dateToday1 = Date.today();
        System.debug('OpdUpList个数:'+OpdUpList.size());
        //赋值需要考虑担当者是否在职
        for (OPDPlan__c op : OpdUpList) {
            CancelPostponePlan__c cpp = new CancelPostponePlan__c();
            cpp.CancelOPDPlan__c = op.id;
            cpp.RecordTypeId = '01210000000gQyL';
            cpp.Status__c = '取消成功';
            system.debug('计划实施日==' + op.OPDPlan_ImplementDate__c+'==是否延期=='+op.SystemDelayMark__c+'==opd计划=='+op.id);
            if (op.StayOrNot__c == '已离职') {
                cpp.cancelReasonCombobox__c = '担当离职';
                //update by yc 20210207 start SWAG-BXVDPJ
            } else if(op.OPDPlan_ImplementDate__c < dateToday1 && op.SystemDelayMark__c){
                cpp.cancelReasonCombobox__c = '备品不足';
                //update by yc 20210207 end SWAG-BXVDPJ
            }else {
                cpp.cancelReasonCombobox__c = '没完成备品申请';
            }

            system.debug('cpp' + cpp);
            cppList.add(cpp);
        }

        system.debug('条数' + cppList.size());
        //加日志 为了更新历史数据 做一下日志查看 20201124 you start
        opdplannum +=cppList.size();
         try {
              insert cppList;
         } catch (Exception e) {
              iflog.ErrorLog__c = 'ERROR [' + OpdUpList + '] => [' + rtlMap + ']' + e.getMessage() + '\n';
             }
        //加日志 为了更新历史数据 做一下日志查看 20201124 you end
        
        
    }
    global void finish(Database.BatchableContext BC) {
        //加日志 为了更新历史数据 做一下日志查看 20201124 you start
        iflog.Log__c += '更新件数： ' +  opdplannum;
        iflog.Log__c += '\nOPDPlanCancelPostponePlanLogicBatch 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;
        //加日志 为了更新历史数据 做一下日志查看 20201124 you end

        // 20210119 youchang start   SWAG-BX7F9W   
        Date dateToday = Date.today();
        String todaystr =  String.valueOf(dateToday);
        Database.executeBatch(new BathUpdateSobject('OPDPlan__c',' Status__c=\'计划中\' and OPDType__c= \'学会\' and OPDPlan_ImplementDate__c < '+todaystr), 20);
       // 20210119 youchang end   SWAG-BX7F9W  
    }
}