/** * Created by T on 2020/5/14. */ public with sharing class MonthEndAutoJudgeBatch implements Database.Batchable, Database.Stateful { public final List TEST_ID = null; private BatchIF_Log__c iflog; // Special_Apply_Reason__c 临时存储数据用 20200916 Gzw update // 当前年月 private Integer yearInteger = Date.today().year(); private Integer monInteger = Date.today().month(); public MonthEndAutoJudgeBatch(){ iflog = new BatchIF_Log__c(); iflog.Type__c = 'MonthEndAutoJudgeBatch'; iflog.Log__c = 'MonthEndAutoJudgeBatch start\n'; iflog.ErrorLog__c = ''; insert iflog; } /** * * * @param testId 测试的Id 集合 * @param flag 用于筛选数据的条件 */ public MonthEndAutoJudgeBatch(List testId) { TEST_ID = testId; iflog = new BatchIF_Log__c(); iflog.Type__c = 'MonthEndAutoJudgeBatch'; iflog.Log__c = 'MonthEndAutoJudgeBatch start\n'; iflog.ErrorLog__c = ''; insert iflog; } /** * startには、queryを実行、引合全件 */ public Database.QueryLocator start(Database.BatchableContext BC) { String staSql = 'SELECT id,Name,Owner__c,CreatedDate,Special_Apply_Reason__c,Opportunity__c,'; staSql += ' Shipping_Scheduled_Date_For_Report__c,DeliveryDate__c,DeliveryStatus__c,isManualApprove__c,'; staSql += ' PaymentStatus__c,Monthly_forecast_shipping__c,NM_forecast_shipping__c,FirstApproveDate__c,'; staSql += ' End_User_contract__c,ContractReceivedDate__c,LastDay_of_MonthDelivery__c FROM Statu_Achievements__c'; // 判断条件,测试跳过 String condition = ' where (( OverviewStatus__c <> \'无效合同\' and (OverviewStatus__c <> \'订单完成\' or (SS_backorderID__c <> null and OverviewStatus_SS_IsEqual__c = false))) or Forecast_Equal__c=false) '; // 手动审批的注残跳过 condition += ' and isManualApprove__c = false '; // 特殊对应中关于最后一天发货的情况 // LastDay_of_MonthDelivery__c // 当前月的第一个工作日 +1便于做判断 Date firstWorkDate = getFirstWorkDayOfMonth().addDays(1); // 当前月的最后五个工作日中最小的那天 Date minOfLastFiveWorkDate = getLastWorkDay(); // 付款状态 List paymentStatus = new List(); paymentStatus.add('尾款完成'); paymentStatus.add('100%预付完成'); paymentStatus.add('不需付款'); paymentStatus.add('尾款支付'); // Gzw 20200831 追加新状态 paymentStatus.add('100%预付款'); // 排除预测发货日为null的数据 // 第一个工作日记录的预测对象的注残 // 最后五个工作日前,提交用户合同并付全款 // Gzw 20200831 去掉预测发货日条件 start // condition += ' and Shipping_Scheduled_Date_For_Report__c <> null' + // Gzw 20200831 去掉预测发货日条件 end // 由14.收到合同日 改为 18.付全款日期或 17.预付款日期 // ' AND ContractReceivedDate__c < :minOfLastFiveWorkDate' + condition += ' and PaymentJudge__c < :minOfLastFiveWorkDate ' + ' and End_User_contract__c = \'已提交\'' + ' and PaymentStatus__c IN :paymentStatus' + ' and ForecastAccuracyObject__c = True ' + ' and CreatedDate < :firstWorkDate '; if (TEST_ID != null && TEST_ID.size() > 0) { staSql += ' where id in :TEST_ID'; } else { staSql += condition; } // System.debug('staSql=' + staSql); return Database.getQueryLocator(staSql); } public void execute(Database.BatchableContext BC, List staList) { Savepoint sp = Database.setSavepoint(); // 获取本月1号 Date toDate = Date.today(); Date mon1stDate = Date.newInstance(toDate.year(), toDate.month(), 1); try { // 需要更新的数据 List updateList = new List(); // 只要标记为true,代表修改过注残,添加到需要更新的集合中 Boolean flag = false; // 迭代所有数据 for (Statu_Achievements__c sa : staList) { // if (String.isBlank(sa.Special_Apply_Reason__c)) { sa.Special_Apply_Reason__c = ''; // } // 有本月发货预测的标记 if ('本月发货预测'.equals(sa.Monthly_forecast_shipping__c)) { // 本月没有发货 // 如果助理勾选了最后一天发货,如果有本月发预测,系统不修改预测 // Gzw 20200831 删除本月发货预测 条件扩展 // DeliveryDate__c == null ——》 DeliveryDate__c == null || DeliveryDate__c < 本月 // 去掉 部分交付 // if (!('部分交付'.equals(sa.DeliveryStatus__c)) && !('已完全交付'.equals(sa.DeliveryStatus__c)) if (!('已完全交付'.equals(sa.DeliveryStatus__c)) && (sa.DeliveryDate__c == null || sa.DeliveryDate__c < mon1stDate )&& sa.LastDay_of_MonthDelivery__c == false) { sa.Monthly_forecast_shipping__c = '删除本月发货预测'; iflog.Log__c += 'Name: '+sa.Name+' 删除本月发货预测\n'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 start // sa.Special_Apply_Reason__c += ' 删除本月发货预测'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 end flag = true; } } if (!String.isBlank(sa.DeliveryStatus__c) && !('未交付'.equals(sa.DeliveryStatus__c))) { // 已发货后说明有发货日期,查看是否本月发货 如果是本月发货添加发货标记 // 如果助理勾选了最后一天发货,添加本月发货 // Gzw 202008902 注残预测标识:需要增加看初审日是本月之前的。 // 获取本月1号 // Date toDate = Date.today(); // Date mon1stDate = Date.newInstance(toDate.year(), toDate.month(), 1); if (((sa.DeliveryDate__c != null && sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() == monInteger) || sa.LastDay_of_MonthDelivery__c) && sa.FirstApproveDate__c < mon1stDate ) { // 添加本月发货预测 if (String.isBlank(sa.Monthly_forecast_shipping__c)){ sa.Monthly_forecast_shipping__c = '新增本月发货预测'; iflog.Log__c += 'Name: '+sa.Name+' 新增本月发货预测\n'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 start sa.Special_Apply_Reason__c = ' 提前完成备货'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 end flag = true; } } } // 有次月发货预测标记 if ('次月发货预测'.equals(sa.NM_forecast_shipping__c)) { // 并且在本月完成全部发货 if (('已完全交付'.equals(sa.DeliveryStatus__c) && sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() == monInteger) || sa.LastDay_of_MonthDelivery__c) { sa.NM_forecast_shipping__c = '删除次月发货预测'; iflog.Log__c += 'Name: '+sa.Name+' 删除次月发货预测\n'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 start // sa.Special_Apply_Reason__c += ' 删除次月发货预测'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 end flag = true; } } // 如果到本月跑Batch时还没有全部发货 : 当月全部发货为否,并且符合次月预测时间,添加次月预测标记 // Gzw 20200821 注残次月预测标识:需要增加看初审日是本月之前的。 if (!('已完全交付'.equals(sa.DeliveryStatus__c))) { // 如果月份是12月 // 次月为 下一年的一月份 // 如果没有次月发货预测的标记 判断是否符合条件 // 如果助理勾选了,如果有本月发预测,系统不修改预测 if (isNMForecastShipping(sa)) { System.debug('----------------- ' + isNMForecastShipping(sa)); if (String.isBlank(sa.NM_forecast_shipping__c) && !(String.isNotBlank(sa.Monthly_forecast_shipping__c) && sa.LastDay_of_MonthDelivery__c)) { sa.NM_forecast_shipping__c = '新增次月发货预测'; // System.debug('添加次月'); iflog.Log__c += 'Name: '+sa.Name+' 新增次月发货预测\n'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 start sa.Special_Apply_Reason__c = ' 货期推迟'; // WLIG-BT26AE Gzw 新增预测时,添加理由 20200916 end flag = true; } } } if(flag){ System.debug('1111111111111 ' + sa.Special_Apply_Reason__c); updateList.add(sa); flag = false; } } List newOpportunitySpecialApply = new List(); // 将直接修改注残 改为 新建询价注残特殊对应审批 for (Statu_Achievements__c upSa : updateList){ System.debug('222222222222 ' + upSa.Special_Apply_Reason__c); OpportunitySpecialApply__c spec = new OpportunitySpecialApply__c(); // spec.Status__c = '草案中'; spec.Status__c = '已批准'; //spec.Apply_Content__c = String.isBlank(upSa.Monthly_forecast_shipping__c) ? '删除本月发货预测' : '新增本月发货预测'; //spec.NMApply_Content_c__c = String.isBlank(upSa.NM_forecast_shipping__c) ? '删除次月发货预测' : '新增次月发货预测'; if (upSa.Monthly_forecast_shipping__c == '删除本月发货预测' || upSa.Monthly_forecast_shipping__c == '新增本月发货预测') { spec.Apply_Content__c = upSa.Monthly_forecast_shipping__c; } if (upSa.NM_forecast_shipping__c == '删除次月发货预测' || upSa.NM_forecast_shipping__c == '新增次月发货预测') { spec.NMApply_Content_c__c = upSa.NM_forecast_shipping__c; } spec.Apply_Reason__c = String.isBlank(upSa.Special_Apply_Reason__c) ? '其他' : upSa.Special_Apply_Reason__c; if (spec.Apply_Reason__c == '其他') { spec.Apply_Memo__c = upSa.Monthly_forecast_shipping__c + upSa.NM_forecast_shipping__c; } spec.Approval_Date__c = Date.today(); spec.Achievements__c = upSa.Id; spec.Opportunity__c = upSa.Opportunity__c; spec.RecordTypeId = Schema.SObjectType.OpportunitySpecialApply__c.getRecordTypeInfosByDeveloperName().get('AchievementsRecordType').getRecordTypeId(); newOpportunitySpecialApply.add(spec); } insert newOpportunitySpecialApply; }catch (Exception e){ iflog.ErrorLog__c += e.getMessage(); Database.rollback(sp); } // Database.update(updateList); } public void finish(Database.BatchableContext BC) { iflog.Log__c += 'MonthEndAutoJudgeBatch 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; } /** * 判断是否是 次月预测 * * @param sa * * @return */ // Gzw 20200821 注残次月预测标识:需要增加看初审日是本月之前的。 public boolean isNMForecastShipping(Statu_Achievements__c sa) { // 获取本月1号 Date toDate = Date.today(); Date mon1stDate = Date.newInstance(toDate.year(), toDate.month(), 1); // mon1stDate = mon1stDate.addMonths(1); System.debug('+++++++++++++++++++ ' + sa.FirstApproveDate__c + mon1stDate); return (((sa.Shipping_Scheduled_Date_For_Report__c.year() == yearInteger && sa.Shipping_Scheduled_Date_For_Report__c.month() == monInteger + 1) || (sa.Shipping_Scheduled_Date_For_Report__c.year() == yearInteger + 1 && sa.Shipping_Scheduled_Date_For_Report__c.month() == 1 && monInteger == 12)) && sa.FirstApproveDate__c < mon1stDate); } /** * 获取当前月份的第一个工作日 * * @return */ public Date getFirstWorkDayOfMonth() { // 获取当前月份的第一天 Date firstDayOfMonth = Date.today().toStartOfMonth(); // 将月份推到下一个月 Date nextMonth = Date.newInstance(firstDayOfMonth.year(), firstDayOfMonth.month() + 1, 1); // 获取当前月份最后一天 // System.debug('lastDay:' + nextMonth.addDays(-1)); Date lastDayOfMonth = nextMonth.addDays(-1); // 此表会维护一个工作日的日历 其中排除掉了周末及节假日 此处通过排序加limit 1 只拿到第一个工作日 List olympusCalendarDate = [ Select Date__c From OlympusCalendar__c Where Date__c >= :firstDayOfMonth And Date__c <= :lastDayOfMonth And IsWorkDay__c = 1 ORDER BY Date__c LIMIT 1 ]; Date firstWorkDayOfMonth = null; if (olympusCalendarDate.size() > 0) { firstWorkDayOfMonth = olympusCalendarDate.get(0).Date__c; } // System.debug('firstWorkDayOfMonth' + firstWorkDayOfMonth); return firstWorkDayOfMonth; } /** * 获取最后五个工作日中的最小的那天 * * @return */ public Date getLastWorkDay() { // 获取当前月份的第一天 Date firstDayOfMonth = Date.today().toStartOfMonth(); // 将月份推到下一个月 Date nextMonth = Date.newInstance(firstDayOfMonth.year(), firstDayOfMonth.month() + 1, 1); // 获取当前月份最后一天 // System.debug('lastDay:' + nextMonth.addDays(-1)); Date lastDayOfMonth = nextMonth.addDays(-1); // 此表会维护一个工作日的日历 其中排除掉了周末及节假日 此处通过排序加limit 5 拿到最后五个工作日 List olympusCalendarDates = [ Select Date__c From OlympusCalendar__c Where Date__c >= :firstDayOfMonth And Date__c <= :lastDayOfMonth And IsWorkDay__c = 1 ORDER BY Date__c DESC LIMIT 5 ]; // System.debug('List :' + olympusCalendarDates); Date result; if (olympusCalendarDates.size() > 0) { result = olympusCalendarDates.get(olympusCalendarDates.size() - 1).Date__c; // System.debug('result' + result); } return result; } }