// by ljh 处理历史数据 正式 console 执行代码
global class RentalNextShippmentDateBatch implements Database.Batchable<sObject> {
    public String query;
    public String type;

    global RentalNextShippmentDateBatch() {
        this.query = query;
        this.type = type;
    }
    global RentalNextShippmentDateBatch(String type) {
        this.query = query;
        this.type = type;
    }
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String query = '';
        // 1.回收后检测 ok
        // 2. 已出库--回收后检测 ok(检测NG和欠品的：不显示时间)
        query = 'select id,name,Check_lost_Item_F__c,RAES_Final_reply_day__c,Inspection_result_after_F_New__c,NextShippmentDate__c,After_Inspection_time_F_New__c  from Rental_Apply_Equipment_Set_Detail__c where Is_Body__c = true and DeliverySlip__c != null and Arrival_in_wh__c = false ';
        query += ' and RA_RecordTypeId__c != \''+System.label.RARrecordtype+'\'';
        if(this.type == '1'){
            query += ' and Inspection_result_after_F_New__c = \'OK\'';
            query += ' and NextShippmentDate__c = null order by After_Inspection_time_F_New__c';
        }
        if(this.type == '2'){
            query += ' and Check_lost_Item_F__c != \'欠品\' and Check_lost_Item_F__c != \'消耗\'  and (Inspection_result_after_F_New__c = \'\' or Inspection_result_after_F_New__c = NULL) ';
            query += ' and NextShippmentDate__c = null order by RAES_Final_reply_day__c';
        }
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Rental_Apply_Equipment_Set_Detail__c> scope) {
        if(this.type == '1'){
            Date minDate = Date.newInstance(4000, 12, 31);
            Date maxDate = Date.newInstance(1700, 1, 1);
            Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>> dLMap = new Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>>();
            List<Rental_Apply_Equipment_Set_Detail__c> upRdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            for (Rental_Apply_Equipment_Set_Detail__c nObj : scope) {
                    // 检测OK时间+3个工作日(奥林巴斯日历)
                    Date date1 = nObj.After_Inspection_time_F_New__c.date();
                    if (minDate > date1) {
                        minDate = date1;
                    }
                    if (maxDate < date1) {
                        maxDate = date1;
                    }
                    if(!dLMap.containsKey(date1)){
                        dLMap.put(date1,new List<Rental_Apply_Equipment_Set_Detail__c>());
                    }
                    dLMap.get(date1).add(nObj); 
            }
            List<OlympusCalendar__c> ocList = [SELECT Id
                        , Date__c
                     FROM OlympusCalendar__c
                    WHERE Date__c >= :minDate
                      AND Date__c <= :maxDate.addDays(30)
                      AND IsWorkDay__c = 1
                    ORDER BY Date__c ASC];
            Map<Date, Date> dateadd3Map = new Map<Date, Date>();
            Integer ocListSize = ocList.size();
            if (ocListSize > 3) {
                for (Integer i = 0; i < ocListSize - 3; i ++) {
                    dateadd3Map.put(ocList[i].Date__c, ocList[i + 3].Date__c);
                }
                for(Date d:dLMap.keySet()){
                    // 因为 检测是工作日 一般不会出现 else 情况
                    if (dateadd3Map.containsKey(d)) {
                        for(Rental_Apply_Equipment_Set_Detail__c rd:dLMap.get(d)){
                            Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                            raesd.Id = rd.id;
                            raesd.NextShippmentDate__c = dateadd3Map.get(d);
                            upRdList.add(raesd);
                        }
                    }
                    // 很少发生
                    else{
                        for (Integer i = 0; i < ocListSize - 3; i ++) {
                            if(d < ocList[i].Date__c){
                                for(Rental_Apply_Equipment_Set_Detail__c rd:dLMap.get(d)){
                                    Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                                    raesd.Id = rd.id;
                                    raesd.NextShippmentDate__c = ocList[i + 2].Date__c;
                                    upRdList.add(raesd);
                                }
                                break;
                            }
                        }
                    }
                }
                update upRdList;
            }
        }
        if(this.type == '2'){
            Date minDate = Date.newInstance(4000, 12, 31);
            Date maxDate = Date.newInstance(1700, 1, 1);
            Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>> dLMap = new Map<Date, List<Rental_Apply_Equipment_Set_Detail__c>>();
            List<Rental_Apply_Equipment_Set_Detail__c> upRdList = new List<Rental_Apply_Equipment_Set_Detail__c>();
            for (Rental_Apply_Equipment_Set_Detail__c nObj : scope) {
                    // 最新预定归还日+8个工作日(奥林巴斯日历)
                    Date date1 = nObj.RAES_Final_reply_day__c;
                    if (minDate > date1) {
                        minDate = date1;
                    }
                    if (maxDate < date1) {
                        maxDate = date1;
                    }
                    if(!dLMap.containsKey(date1)){
                        dLMap.put(date1,new List<Rental_Apply_Equipment_Set_Detail__c>());
                    }
                    dLMap.get(date1).add(nObj); 
            }
            List<OlympusCalendar__c> ocList = [SELECT Id
                        , Date__c
                     FROM OlympusCalendar__c
                    WHERE Date__c >= :minDate
                      AND Date__c <= :maxDate.addDays(30)
                      AND IsWorkDay__c = 1
                    ORDER BY Date__c ASC];
            Map<Date, Date> dateadd3Map = new Map<Date, Date>();
            Integer ocListSize = ocList.size();
            if (ocListSize > 8) {
                for (Integer i = 0; i < ocListSize - 8; i ++) {
                    dateadd3Map.put(ocList[i].Date__c, ocList[i + 8].Date__c);
                }
                for(Date d:dLMap.keySet()){
                    if (dateadd3Map.containsKey(d)) {
                        for(Rental_Apply_Equipment_Set_Detail__c rd:dLMap.get(d)){
                            Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                            raesd.Id = rd.id;
                            raesd.NextShippmentDate__c = dateadd3Map.get(d);
                            upRdList.add(raesd);
                        }
                    }
                    else{
                        for (Integer i = 0; i < ocListSize - 8; i ++) {
                            if(d < ocList[i].Date__c){
                                for(Rental_Apply_Equipment_Set_Detail__c rd:dLMap.get(d)){
                                    Rental_Apply_Equipment_Set_Detail__c raesd = new Rental_Apply_Equipment_Set_Detail__c();
                                    raesd.Id = rd.id;
                                    raesd.NextShippmentDate__c = ocList[i + 7].Date__c;
                                    upRdList.add(raesd);
                                }
                                break;
                            }
                        }
                    }
                }
                update upRdList;
            }
        }
    }
    global void finish(Database.BatchableContext BC) {

    }
}