global class SetCurrentDailyReportSumBatch implements Database.Batchable < sObject > , Database.Stateful { String query; String yearField; //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 start String yearWorkDay; String lastYearWorkDay; //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 end Date toDate; Id userId; //用于传入的财年 Integer flag; //该财年的开始日 Date fromDate1 = null; //该财年的结束日 Date endDate = null; //上财年的开始日 Date fromDate2 = null; //上财年的结束日 Date endDate1 = null; Boolean IsNeedExecute = false; // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 是否符合执行条件 global SetCurrentDailyReportSumBatch() { toDate = Date.today(); } global SetCurrentDailyReportSumBatch(Date d, Id id) { toDate = d; userId = id; } //根据财年更新所有用户 global SetCurrentDailyReportSumBatch(Integer year) { flag = year; toDate = Date.today(); } //根据财年和userid 更新单个的用户 global SetCurrentDailyReportSumBatch(Integer year, Id id) { flag = year; userId = id; toDate = Date.today(); } //更新本财年所有用户 global SetCurrentDailyReportSumBatch(Id id) { userId = id; toDate = Date.today(); } // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 start global SetCurrentDailyReportSumBatch(Boolean NeedExecute) { this.IsNeedExecute = NeedExecute; this.toDate = Date.today(); } // 2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 end global Database.QueryLocator start(Database.BatchableContext BC) { if (toDate.month() == 4 && toDate.day() == 1) { yearField = 'Daily_Report_Num_'; yearField += String.valueOf(toDate.year() - 1 - 1867) + 'P__c'; } //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 start if (flag != null) { //根据传入的财年 去判断该财年的开始日期 fromDate1 = Date.newInstance(flag + 1867, 4, 1); endDate = Date.newInstance(flag + 1 + 1867, 4, 1); //根据传入的财年 去判断上财年的开始日期 fromDate2 =Date.newInstance(flag + 1867 - 1, 4, 1); endDate1 =Date.newInstance(flag + 1867, 4, 1); //该财年要更新的字段 yearWorkDay = 'WorkDate'; yearWorkDay += String.valueOf(flag) + 'P__c'; //上次啊年要更新的字段 lastYearWorkDay = 'WorkDate'; lastYearWorkDay += String.valueOf(flag -1) + 'P__c'; } else { //根据当前时间判断本财年 if (toDate.month() >= 4) { fromDate1 = Date.newInstance(toDate.year(), 4, 1); endDate = Date.newInstance(toDate.year() + 1, 4, 1); fromDate2 = Date.newInstance(toDate.year() - 1, 4, 1); endDate1 = Date.newInstance(toDate.year(), 4, 1); } else { fromDate1 = Date.newInstance(toDate.year() - 1, 4, 1); endDate = Date.newInstance(toDate.year(), 4, 1); fromDate2 = Date.newInstance(toDate.year() - 2, 4, 1); endDate1 = Date.newInstance(toDate.year()- 1, 4, 1); } if (fromDate1 == toDate) { fromDate1 = Date.newInstance(toDate.year() - 1, 4, 1); endDate = Date.newInstance(toDate.year(), 4, 1); fromDate2 = Date.newInstance(toDate.year() - 2, 4, 1); endDate1 = Date.newInstance(toDate.year()- 1, 4, 1); } //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 start if (toDate.month() >= 4) { yearWorkDay = 'WorkDate'; yearWorkDay += String.valueOf(toDate.year() - 1867) + 'P__c'; lastYearWorkDay = 'WorkDate'; lastYearWorkDay += String.valueOf(toDate.year() - 1867 -1) + 'P__c'; } else { yearWorkDay = 'WorkDate'; yearWorkDay += String.valueOf(toDate.year() - 1 - 1867) + 'P__c'; lastYearWorkDay = 'WorkDate'; lastYearWorkDay += String.valueOf(toDate.year() - 2 - 1867) + 'P__c'; } //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 end } //注释源代码 // if (String.isBlank(yearField)) { if (String.isBlank(yearField)) { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c,' + yearWorkDay + ' from User'; } else { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c, ' + yearField + ', ' + yearWorkDay + ' from User'; } if (flag != null) { if (String.isBlank(yearField)) { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c,'; query += 'Last_financial_year_Jan__c,Last_financial_year_Feb__c,Last_financial_year_Mar__c,Last_financial_year_Apr__c,'; query += 'Last_financial_year_May__c,Last_financial_year_June__c ,Last_financial_year_July__c,Last_financial_year_Aug__c,'; query += 'Last_financial_year_Sep__c,Last_financial_year_Oct__c ,Last_financial_year_Nov__c,Last_financial_year_Dec__c'; query += ',' + yearWorkDay + ',' + lastYearWorkDay+ ' from User'; } else { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c,'; query += 'Last_financial_year_Jan__c,Last_financial_year_Feb__c,Last_financial_year_Mar__c,Last_financial_year_Apr__c,'; query += 'Last_financial_year_May__c,Last_financial_year_June__c ,Last_financial_year_July__c,Last_financial_year_Aug__c,'; query += 'Last_financial_year_Sep__c,Last_financial_year_Oct__c ,Last_financial_year_Nov__c,Last_financial_year_Dec__c'; query += ',' + yearWorkDay + ',' + yearField + ',' + lastYearWorkDay+ ' from User'; } } else { if (String.isBlank(yearField)) { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c,'; query += 'The_financial_year_Jan__c,The_financial_year_Feb__c,The_financial_year_Mar__c,The_financial_year_Apr__c,'; query += 'The_financial_year_May__c,The_financial_year_June__c ,The_financial_year_July__c,The_financial_year_Aug__c,'; query += 'The_financial_year_Sep__c,The_financial_year_Oct__c ,The_financial_year_Nov__c,The_financial_year_Dec__c'; query += ',' + yearWorkDay + ',' + lastYearWorkDay+ ' from User'; } else { query = 'select Id, Current_Daily_Report_Sum__c,Current_Daily_Report_Sum_work__c,Use_Start_Date__c,'; query += 'The_financial_year_Jan__c,The_financial_year_Feb__c,The_financial_year_Mar__c,The_financial_year_Apr__c,'; query += 'The_financial_year_May__c,The_financial_year_June__c ,The_financial_year_July__c,The_financial_year_Aug__c,'; query += 'The_financial_year_Sep__c,The_financial_year_Oct__c ,The_financial_year_Nov__c,The_financial_year_Dec__c'; query += ',' + yearWorkDay + ',' + yearField+ ',' + lastYearWorkDay + ' from User'; } } //【委托】用户信息中增加工作日逻辑 逻辑1 更新本财年工作日数 精琢技术 wql 2020/05/29 end if (String.isBlank(userId) == false) { query += ' where Id=\'' + userId + '\''; } system.debug('sql:' + query); return Database.getQueryLocator(query); } //2018/8/8 SWAG-B3D5PU 目前用户页面中已经有了一个“本期日报数”,累计的是所有的日报数,现在新建一个“本期日报数(工作日)”只累计工作日的日报数 global void execute(Database.BatchableContext BC, List < sObject > scope) { List < User > userList = new List < User > (); userList = scope; List < AggregateResult > resultList = new List < AggregateResult > (); List < AggregateResult > resultList_work = new List < AggregateResult > (); List < Date > workDay = new List < Date > (); Date fromDate = null; Boolean nextYearFlag = false; if (toDate.month() >= 4) { fromDate = Date.newInstance(toDate.year(), 4, 1); } else { fromDate = Date.newInstance(toDate.year() - 1, 4, 1); } if (fromDate == toDate) { fromDate = Date.newInstance(toDate.year() - 1, 4, 1); nextYearFlag = true; } //用于存储最后需要更新的用户 Map < Id, User > updateUserList = new Map < Id, User > (); Map < Id, User > userMap = new Map < Id, User > (); for (User u: userList) { userMap.put(u.Id, u); } //获取Olympus日历中的工作日 List < OlympusCalendar__c > OlyCalendar = [select Date__c, IsWorkDay__c from OlympusCalendar__c where Date__c >= : fromDate and Date__c < : toDate]; for (OlympusCalendar__c oly: OlyCalendar) { if (oly.IsWorkDay__c == 1) { workDay.add(oly.Date__c); } } system.debug('================' + workDay.size()); resultList = [select COUNT(Id) dailyReportNum, Reporter__r.Id Reporter__c from Daily_Report__c where Reported_Date__c >= : fromDate and Reported_Date__c < : toDate and Reporter__r.Id in : userMap.keySet() // and (Status__c ='申請中' or Status__c ='承認') and(Status__c = '申請中' or Status__c = '承認') group by Reporter__r.Id ]; // resultList_work = [select COUNT(Id) dailyReportNum, Reporter__r.Id Reporter__c from Daily_Report__c where Reported_Date__c = : workDay and Reporter__r.Id in : userMap.keySet() and(Status__c = '申請中' or Status__c = '承認') group by Reporter__r.Id ]; /*resultWorkDateList = [];*/ Map < Id, Integer > userNumMap = new Map < Id, Integer > (); Map < Id, Integer > userWorkNumMap = new Map < Id, Integer > (); if (resultList != null && resultList.size() > 0) { for (AggregateResult ar: resultList) { userNumMap.put((Id) ar.get('Reporter__c'), (Integer) ar.get('dailyReportNum')); } } if (resultList_work != null && resultList_work.size() > 0) { for (AggregateResult arw: resultList_work) { userWorkNumMap.put((Id) arw.get('Reporter__c'), (Integer) arw.get('dailyReportNum')); } } //该财年的奥林巴斯日历工作数 list < Date > worklist = updateWorkDate_CountN(fromDate1, endDate); system.debug('奥林巴斯日历:' + worklist); //0 :本财年 1:上财年 由于日历得1月份才更新 所以本财年 不会有123月日历 Map < Id, Integer[] > updateUserMap = updateWorkDate_CountM(0, worklist, toDate, fromDate1, endDate, userList, userMap); //上一财年的奥利巴斯日历工作数 list < Date > lastWorklist = updateWorkDate_CountN(fromDate2, endDate1); system.debug('奥林巴斯日历上财年:' + lastWorklist); //0 :本财年 1:上财年 由于日历得1月份才更新 所以本财年 不会有123月日历 Map < Id, Integer[] > updateUserLastMap = updateWorkDate_CountM(1, lastWorklist, toDate, fromDate2, endDate1, userList, userMap); List < User > updUsers = new List < User > (); system.debug('日报数:'+userNumMap); system.debug('用户:'+userMap); system.debug('用户:'+userMap); //更新本财年12月的工作日字段 String [] FieldList = new String[] {'Jan','Feb','Mar','Apr','May','June','July','Aug','Sep','Oct','Nov','Dec'}; for (Id i: userMap.keySet()) { Integer drNum = userNumMap.get(i); Integer drwNum = userWorkNumMap.get(i); system.debug('本期日报数'+drNum); system.debug('本期日报数(工作日)'+drwNum); User us = userMap.get(i); //本财年的工作数 Integer yearCount = 0; //上财年的工作数 Integer lastYearCount = 0; //需要更新的该财年工作日数 Integer[] userWorkDayCountList = updateUserMap.get(i); //需要更新的上财年的工作日数 Integer[] userLastWorkDayCountList = updateUserLastMap.get(i); if (userWorkDayCountList != null) { for (Integer t = 0; t < userWorkDayCountList.size(); t++) { if (userWorkDayCountList[t] != null) { yearCount += userWorkDayCountList[t]; } } } if (userLastWorkDayCountList != null) { for (Integer l = 0; l < userLastWorkDayCountList.size(); l++) { if (userLastWorkDayCountList[l] != null) { lastYearCount += userLastWorkDayCountList[l]; } } } Boolean updFlag = false; if (us != null) { if (us.Current_Daily_Report_Sum_work__c != drwNum) { us.Current_Daily_Report_Sum_work__c = drwNum; system.debug('==drwNum==' + drwNum); updFlag = true; }else if (drwNum == null){ us.Current_Daily_Report_Sum_work__c = 0; updFlag = true; } if (us.Current_Daily_Report_Sum__c != drNum) { us.Current_Daily_Report_Sum__c = drNum; system.debug('==drNum==' + drNum); updFlag = true; }else if (drNum == null){ us.Current_Daily_Report_Sum__c = 0; updFlag = true; } //更新本财年的15几p工作日字段 us.put(yearWorkDay, yearCount); //更新上财年的15几p工作日字段 us.put(lastYearWorkDay, lastYearCount); for(Integer x =0;x<12;x++){ us.put('The_financial_year_'+FieldList[x]+'__c',userWorkDayCountList[x]); us.put('Last_financial_year_'+FieldList[x]+'__c',userLastWorkDayCountList[x]); } updFlag = true; if (nextYearFlag) { us.put(yearField, drNum); updFlag = true; } if (updFlag) { updUsers.add(us); } } } system.debug('更新的用户:' + updUsers); if (updUsers.size() > 0) { update updUsers; } } global void finish(Database.BatchableContext BC) { //2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 start if(!Test.isRunningTest() &&IsNeedExecute==true){ //batch里调用下一个batch时,希望跟原有的Schedule里面传的条数保持一致 Id execBTId = Database.executebatch(new UpdateUserTextColBatch(true),10); } //2021-03-08 mzy WLIG-BYHD79 SFDC环境batch合并调查 end } global static List < Date > updateWorkDate_CountN(Date fromDate1, Date endDate) { //用于存储本财年奥林巴斯日历的工作日 List < Date > workDayNum = new List < Date > (); //用于存储每个用户的本财年的工作日数 List < Date > workDayCount = new List < Date > (); //用于存储id 和 更新的工作日数 Map < Id, Integer > userCountYearMap = new Map < Id, Integer > (); Map < Id, Integer[] > userCountMonthMap = new Map < Id, Integer[] > (); //根据上面不同财年的判断 获取不同财年的工作日 List < OlympusCalendar__c > OlyCalendar = [select Date__c, IsWorkDay__c from OlympusCalendar__c where Date__c >= : fromDate1 and Date__c < : endDate]; for (OlympusCalendar__c oly: OlyCalendar) { if (oly.IsWorkDay__c == 1) { workDayNum.add(oly.Date__c); } } return workDayNum; } //0 :本财年 1:上财年 由于日历得1月份才更新 所以本财年 不会有123月日历 global static Map < Id, Integer[] > updateWorkDate_CountM(Integer flag, List < Date > workDayNum, Date toDate, Date fromDate1, Date endDate1, List < User > userList, Map < Id, User > userMap) { //财年开始日 Date startDate = fromDate1; //财年结束日 Date endDate = endDate1; Boolean lastYear = false; //用于存储id 和 更新的工作日数 Map < Id, Integer > userCountYearMap = new Map < Id, Integer > (); Map < Id, Integer[] > userCountMonthMap = new Map < Id, Integer[] > (); for (User u: userList) { //定义变量 用于存储当前月的用户工作日 Integer Jan = 0; //定义变量 用于存储入职月份的工作日 Integer Jan2 = 0; //定义相差的月份 Integer monthDiff = 0; //当前是几月 Integer month = 0; //开始月 Integer monthFrom = 0; //本财年的工作数 Integer yearCount = 0; if (u.Use_Start_Date__c != null) { //本财年用户入职月和当前月相差几个月份 Integer userYear = u.Use_Start_Date__c.year(); Integer userMonth = u.Use_Start_Date__c.month(); //如果flag为空则说明要更新本财年的 要判断当前时间 //同一年 月份差直接 当前月-入职月 //先判断是否该财年入职 else则是该财年以前入职的 if ((startDate.year() == userYear && userMonth >= 4) || (endDate.year() == userYear && userMonth < 4)) { //说明是该财年上半年 入职的 if (startDate.year() == userYear || endDate.year() == userYear) { //说明上半年入职的 则直接当前月-入职月 monthDiff = 12 - userMonth; } else if (endDate.year() == toDate.year() && startDate.year() == userYear) { //说明当前时间到了下半年,入职是上半年 monthDiff = 12 - userMonth + 4; } monthFrom = userMonth; } else { if (startDate.year() >= userYear) { //说明上财年入职的 该财年已4月份开始计算 monthDiff = 12; monthFrom = 0; } else if (endDate.year() == userYear) { //说明还该财年还没入职 } } } //用于定义每个财年每个月的工作日 Integer[] monthWorkDayList = new Integer[12]; //每个用户每年的工作日 通过两部分构成 第一部分: 入职月 + 第二部分:该财年剩余月 //循环遍历日历 /*计算的是每年的工作日 按月拆分的工作日数 精琢技术 wql 2020/06/02 start 第二部分 :该财年12月*/ for (Integer i = 1; i <= 12; i++) { Integer countMonth = 0; for (Date d: workDayNum) { if (d.month() == i) { countMonth++; } } monthWorkDayList[i - 1] = countMonth; } for (Date d: workDayNum) { /*计算的是入职该用户的工作日 精琢技术 wql 2020/06/03 start 第一部分:入职月*/ if (monthFrom != 0) { if (d.month() == monthFrom) { if (d >= u.Use_Start_Date__c) { Jan2++; } } } /*计算的是入职该用户的工作日 精琢技术 wql 2020/06/03 end*/ } system.debug('第一次更新每财年每月:' + monthWorkDayList); /*计算的是每年的工作日 按月拆分的工作日数 精琢技术 wql 2020/06/02 end*/ system.debug('入职月工作日:' + Jan2); system.debug('入职月:' + monthFrom + '----' + '差:' + monthDiff); //存放每个用户的每月工作日 Integer[] monthList = monthWorkDate_CountM(flag, monthFrom, monthDiff, Jan2, monthWorkDayList); if (u.Use_Start_Date__c > endDate) { //说明该财年还未入职,则工作日数为0 Integer[] newWordList = new Integer[] {0,0,0,0,0,0,0,0,0,0,0,0}; monthList = newWordList; } system.debug('最后更新每财年每月:' + monthList); if (monthList != null) { for (Integer i = 0; i < monthList.size(); i++) { if (monthList[i] != null) { yearCount += monthList[i]; } } } userCountYearMap.put((Id) u.Id, (Integer) yearCount); userCountMonthMap.put((Id) u.Id, (Integer[]) monthList); } return userCountMonthMap; } /*month :当前月; monthFrom:入职月 ;monthDiff: 中间月; Jan : 当前月工作日 ; Jan2 : 入职月工作日 monthWorkDayList :每财年每个月的工作日*/ global static Integer[] monthWorkDate_CountM(Integer flag, Integer monthFrom, Integer monthDiff, Integer Jan2, Integer[] monthWorkDayList) { //flag 0 :本财年 1:上财年 由于日历得1月份才更新 所以本财年 不会有123月日历 //定义最后返回的用户十二月工作日 Integer[] userWorkDayList = new Integer[] {0,0,0,0,0,0,0,0,0,0,0,0}; if (monthFrom != 0) { //②计算中间月的工作日 if (monthDiff == 0) { //则说明是这个月入职的 //①先算第一部分 入职月的工作日 userWorkDayList[monthFrom - 1] = Jan2; //如果是上财年的123月 则奥林巴斯日历已经更新 if(flag == 1){ Integer b = 4; for (Integer j = 1; j <= b - 1; j++) { userWorkDayList[j - 1] = monthWorkDayList[j - 1]; } } } else { //则说明入职到现在一定有中间整月的情况 //①先算第一部分 入职月的工作日 userWorkDayList[monthFrom - 1] = Jan2; //计算有中间整月的情况 比如 4,5,6,7,8,9,10,11,12 1,2,3 Integer a = 12 - monthFrom; Integer b = 4; for (Integer i = 0; i < a; i++) { userWorkDayList[monthFrom + i] = monthWorkDayList[monthFrom + i]; } for (Integer j = 1; j <= b - 1; j++) { userWorkDayList[j - 1] = monthWorkDayList[j - 1]; } } } else { //以前财年入职的,更新该财年 全部工作日 for (Integer i = 0; i < 12; i++) { userWorkDayList[i] = monthWorkDayList[i]; } } //返回用户12月的工作日的数组 依次为1月、2月...12月 return userWorkDayList; } }