global without sharing class SetOlympusCalendarWorkDayBatch implements Database.Batchable, Database.Stateful { private final Integer DAYCOUNT = 30; public List emailMessages = new List(); private Integer totalCount = 0; // 总件数 private Integer failedCount = 0; private Integer totalCountDone = 0; Boolean IsNeedExecute = false; // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 是否符合执行条件 // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 start global SetOlympusCalendarWorkDayBatch() { } global SetOlympusCalendarWorkDayBatch(Boolean NeedExecute) { this.IsNeedExecute = NeedExecute; } // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 end global Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator([ SELECT Id , Date__c , IsWorkDay__c , After_1_WorkDay__c , After_2_WorkDay__c , After_3_WorkDay__c , After_4_WorkDay__c , After_5_WorkDay__c , After_6_WorkDay__c , After_7_WorkDay__c , After_8_WorkDay__c , After_9_WorkDay__c , After_10_WorkDay__c , After_11_WorkDay__c , After_12_WorkDay__c , After_13_WorkDay__c , After_14_WorkDay__c , After_15_WorkDay__c , After_16_WorkDay__c , After_17_WorkDay__c , After_18_WorkDay__c , After_19_WorkDay__c , After_20_WorkDay__c , After_21_WorkDay__c , After_22_WorkDay__c , After_23_WorkDay__c , After_24_WorkDay__c , After_25_WorkDay__c , After_26_WorkDay__c , After_27_WorkDay__c , After_28_WorkDay__c , After_29_WorkDay__c , After_30_WorkDay__c , Before_1_WorkDay__c , Before_2_WorkDay__c , Before_3_WorkDay__c , Before_4_WorkDay__c , Before_5_WorkDay__c , Before_6_WorkDay__c , Before_7_WorkDay__c , Before_8_WorkDay__c , Before_9_WorkDay__c , Before_10_WorkDay__c , Before_11_WorkDay__c , Before_12_WorkDay__c , Before_13_WorkDay__c , Before_14_WorkDay__c , Before_15_WorkDay__c , Before_16_WorkDay__c , Before_17_WorkDay__c , Before_18_WorkDay__c , Before_19_WorkDay__c , Before_20_WorkDay__c , Before_21_WorkDay__c , Before_22_WorkDay__c , Before_23_WorkDay__c , Before_24_WorkDay__c , Before_25_WorkDay__c , Before_26_WorkDay__c , Before_27_WorkDay__c , Before_28_WorkDay__c , Before_29_WorkDay__c , Before_30_WorkDay__c FROM OlympusCalendar__c WHERE Before_30_WorkDay__c = null OR After_30_WorkDay__c = null ]); } global void execute(Database.BatchableContext B, List ocList) { Savepoint sp = Database.setSavepoint(); try { totalCount += ocList.size(); Date minDate = Date.newInstance(4000, 12, 31); Date maxDate = Date.newInstance(1700, 1, 1); for (OlympusCalendar__c oc : ocList) { if (oc.Date__c > maxDate) { maxDate = oc.Date__c; } if (oc.Date__c < minDate) { minDate = oc.Date__c; } } List olcList = [SELECT Id , Date__c , IsWorkDay__c FROM OlympusCalendar__c WHERE Date__c >= :minDate.addDays(-60) AND Date__c <= :maxDate.addDays(60) AND IsWorkDay__c = 1 ORDER BY Date__c]; for (Integer i = 0; i < ocList.size(); i ++) { OlympusCalendar__c oc = ocList[i]; for (Integer j = 0; j < olcList.size(); j ++) { OlympusCalendar__c olc = olcList[j]; if (olc.Date__c > oc.Date__c) { // 因为字段是从1开始的所以直接g从1开始 for (Integer g = 1; g <= olcList.size() - j; g ++) { // 因为字段是从1开始所得所以直接用g oc.put('After_' + g + '_WorkDay__c', olcList[j + g - 1].Date__c); // 因为从1开始所以不需要减1 if (g == DAYCOUNT) { break; } } Integer k = 1; // 因为当前日历可能是周末,所以从1开始 for (Integer g = 1; g <= j; g ++) { // 因为上面上大于的判断。所以前一天可能和日历日期是同一天。所以需要加if文 if (olcList[j - g].Date__c < oc.Date__c) { oc.put('Before_' + k + '_WorkDay__c', olcList[j - g].Date__c); if (k == DAYCOUNT) { break; } k ++; } } break; } } } Database.update(ocList); totalCountDone += ocList.size(); } catch (Exception e) { Database.rollback(sp); emailMessages.add(e.getMessage() + e.getStackTraceString()); failedCount += ocList.size(); } } global void finish(Database.BatchableContext BC) { BatchEmailUtil be = new BatchEmailUtil(); String[] toList = new String[]{UserInfo.getUserEmail()}; String title = 'OlympusCalendar工作日更新Batch'; String[] ccList = new String[] {}; if(this.emailMessages.size() == 0 && totalCountDone == totalCount){ // 不发送成功邮件 } else{ String emailLabel = 'BatchNotify'; for (OrgWideEmailAddress tmpEmailObj : [SELECT Id, Address, DisplayName FROM OrgWideEmailAddress WHERE DisplayName like :emailLabel]) { ccList.add(tmpEmailObj.Address); } be.failedMail(toList, ccList, title, String.join(this.emailMessages, '\n'), totalCount, totalCountDone, failedCount); be.send(); } Id execBTId = Database.executeBatch(new InventoryAutoGiveupBatch(), 200); } }