public with sharing class MonthEndAutoJudgeNotUpdateBatch implements Database.Batchable<SObject>, Database.Stateful {
|
public final List<Id> TEST_ID = null;
|
private BatchIF_Log__c iflog;
|
|
// 当前年月
|
private Integer yearInteger = Date.today().year();
|
private Integer monInteger = Date.today().month();
|
|
public MonthEndAutoJudgeNotUpdateBatch(){}
|
/**
|
*
|
*
|
* @param testId 测试的Id 集合
|
* @param flag 用于筛选数据的条件
|
*/
|
public MonthEndAutoJudgeNotUpdateBatch(List<Id> testId) {
|
TEST_ID = testId;
|
System.debug('TEST_ID=' + TEST_ID);
|
iflog = new BatchIF_Log__c();
|
iflog.Type__c = 'MonthEndAutoJudgeNotUpdateBatch';
|
iflog.Log__c = 'MonthEndAutoJudgeNotUpdateBatch start\n';
|
iflog.ErrorLog__c = '';
|
insert iflog;
|
}
|
|
/**
|
* startには、queryを実行、引合全件
|
*/
|
public Database.QueryLocator start(Database.BatchableContext BC) {
|
System.debug('start====');
|
String staSql = 'SELECT id,Name,Owner__c,CreatedDate,Special_Apply_Reason__c,';
|
staSql += ' Shipping_Scheduled_Date__c,DeliveryDate__c,DeliveryStatus__c,';
|
staSql += ' PaymentStatus__c,Monthly_forecast_shipping__c,NM_forecast_shipping__c,';
|
staSql += ' End_User_contract__c,ContractReceivedDate__c FROM Statu_Achievements__c';
|
staSql += ' where (( OverviewStatus__c <> \'无效合同\' and (OverviewStatus__c <> \'订单完成\' or (SS_backorderID__c <> null and OverviewStatus_SS_IsEqual__c = false))) or Forecast_Equal__c=false) ';
|
|
// 当前月的第一个工作日 +1便于做判断
|
Date firstWorkDate = getFirstWorkDayOfMonth().addDays(1);
|
// 当前月的最后五个工作日中最小的那天
|
Date minOfLastFiveWorkDate = getLastWorkDay();
|
|
// 付款状态
|
List<String> paymentStatus = new List<String>();
|
paymentStatus.add('尾款完成');
|
paymentStatus.add('100%预付完成');
|
paymentStatus.add('不需付款');
|
paymentStatus.add('尾款支付');
|
|
// 排除预测发货日为null的数据
|
// 第一个工作日记录的预测对象的注残
|
// 最后五个工作日前,提交用户合同并付全款
|
staSql += ' AND Shipping_Scheduled_Date__c <> null' +
|
' AND ContractReceivedDate__c < :minOfLastFiveWorkDate' +
|
' AND End_User_contract__c = \'已提交\'' +
|
' AND PaymentStatus__c IN :paymentStatus';
|
|
// 如果给定id值,跑指定id的数据
|
if (TEST_ID != null && TEST_ID.size() > 0) {
|
if (!Test.isRunningTest()) {
|
staSql += ' AND CreatedDate < :firstWorkDate AND id IN :TEST_ID ';
|
} else {
|
staSql += ' AND id IN :TEST_ID';
|
}
|
// 如果没有给定值,默认跑全部数据,如果在正式环境还需添加创建日期的条件
|
} else {
|
if (!Test.isRunningTest()) {
|
staSql += ' AND CreatedDate < :firstWorkDate ';
|
}
|
}
|
|
// System.debug('staSql=' + staSql);
|
return Database.getQueryLocator(staSql);
|
}
|
|
public void execute(Database.BatchableContext BC, List<Statu_Achievements__c> staList) {
|
// System.debug('stalist=' + staList.size());
|
|
// 迭代所有数据
|
for (Statu_Achievements__c sa : staList) {
|
|
// 有本月发货预测的标记
|
if ('本月发货预测'.equals(sa.Monthly_forecast_shipping__c)) {
|
// 本月没有发货
|
if (!('部分交付'.equals(sa.DeliveryStatus__c)) && !('已完全交付'.equals(sa.DeliveryStatus__c)) && sa.DeliveryDate__c == null) {
|
clearMonthlyForecastShipping(sa);
|
}
|
|
// 如果发货了
|
if (sa.DeliveryDate__c != null && !String.isBlank(sa.DeliveryStatus__c) && !('未交付'.equals(sa.DeliveryStatus__c))) {
|
// 但发货日不在本年本月 或者发货日根本不在本年 删除本月预测
|
if ((sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() != monInteger) || sa.DeliveryDate__c.year() != yearInteger) {
|
clearMonthlyForecastShipping(sa);
|
}
|
}
|
}
|
|
// 如果符合本月预测的时间但没有做本月发货预测的标记
|
if (sa.Shipping_Scheduled_Date__c.year() == yearInteger && sa.Shipping_Scheduled_Date__c.month() == monInteger) {
|
// 如果之前做过次月预测的标记删除
|
clearNMForecastShipping(sa);
|
// 已发货
|
if (!String.isBlank(sa.DeliveryStatus__c) && !('未交付'.equals(sa.DeliveryStatus__c))) {
|
// 已发货后说明有发货日期,查看是否本月发货 如果是本月发货添加发货标记
|
if (sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() == monInteger) {
|
// 添加本月发货预测
|
if (String.isBlank(sa.Monthly_forecast_shipping__c)){
|
sa.Monthly_forecast_shipping__c = '本月发货预测';
|
// System.debug('添加本月');
|
iflog.Log__c += 'Name: '+sa.Name+' 添加本月发货预测\n';
|
sa.Special_Apply_Reason__c += ' 系统自动,添加本月发货预测';
|
}
|
|
}
|
}
|
}
|
|
// 有次月发货预测标记 或者时间是次月预测
|
if ('次月发货预测'.equals(sa.NM_forecast_shipping__c) || isNMForecastShipping(sa)) {
|
// 并且在本月完成全部发货
|
if ('已完全交付'.equals(sa.DeliveryStatus__c) && sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() == monInteger) {
|
clearMonthlyForecastShipping(sa);
|
clearNMForecastShipping(sa);
|
}
|
|
// 如果发货了
|
if (sa.DeliveryDate__c != null && !String.isBlank(sa.DeliveryStatus__c) && !('未交付'.equals(sa.DeliveryStatus__c))) {
|
// 但发货日不在本年本月 或者发货日根本不在本年 删除次月预测
|
if ((sa.DeliveryDate__c.year() == yearInteger && sa.DeliveryDate__c.month() != monInteger) || sa.DeliveryDate__c.year() != yearInteger) {
|
clearNMForecastShipping(sa);
|
}
|
}
|
}
|
|
// 当月没有完成全部发货
|
if (!('已完全交付'.equals(sa.DeliveryStatus__c))) {
|
// 如果月份是12月
|
// 次月为 下一年的一月份
|
// 如果没有次月发货预测的标记 判断是否符合条件
|
if (isNMForecastShipping(sa)) {
|
// 添加次月时无论如何删除掉本月
|
clearMonthlyForecastShipping(sa);
|
if (String.isBlank(sa.NM_forecast_shipping__c)) {
|
sa.NM_forecast_shipping__c = '次月发货预测';
|
// System.debug('添加次月');
|
iflog.Log__c += 'Name: '+sa.Name+' 添加次月发货预测\n';
|
sa.Special_Apply_Reason__c += ' 系统自动,添加次月发货预测';
|
}
|
// 如果不是次月预测 但有标记 删除该标记
|
} else {
|
clearNMForecastShipping(sa);
|
}
|
}
|
|
}
|
|
// 不会做修改
|
// Database.update(staList);
|
}
|
|
public void finish(Database.BatchableContext BC) {
|
iflog.Log__c += 'MonthEndAutoJudgeNotUpdateBatch 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
|
*/
|
public void clearMonthlyForecastShipping(Statu_Achievements__c sa) {
|
if (!String.isBlank(sa.Monthly_forecast_shipping__c)) {
|
sa.Monthly_forecast_shipping__c = null;
|
// System.debug('删除 本月');
|
iflog.Log__c += 'Name: '+sa.Name+' 删除本月发货预测\n';
|
sa.Special_Apply_Reason__c += ' 系统自动,删除本月发货预测';
|
}
|
}
|
|
/**
|
* 删除次月发货预测
|
*
|
* @param sa
|
*/
|
public void clearNMForecastShipping(Statu_Achievements__c sa) {
|
if (!String.isBlank(sa.NM_forecast_shipping__c)) {
|
sa.NM_forecast_shipping__c = null;
|
System.debug('删除 次月');
|
iflog.Log__c += 'Name: '+sa.Name+' 删除次月发货预测\n';
|
sa.Special_Apply_Reason__c += ' 系统自动,删除次月发货预测';
|
}
|
}
|
|
/**
|
* 判断是否是 次月预测
|
*
|
* @param sa
|
*
|
* @return
|
*/
|
public boolean isNMForecastShipping(Statu_Achievements__c sa) {
|
return (sa.Shipping_Scheduled_Date__c.year() == yearInteger && sa.Shipping_Scheduled_Date__c.month() == monInteger + 1) ||
|
(sa.Shipping_Scheduled_Date__c.year() == yearInteger + 1 && sa.Shipping_Scheduled_Date__c.month() == 1 && monInteger == 12);
|
}
|
|
/**
|
* 获取当前月份的第一个工作日
|
*
|
* @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<OlympusCalendar__c> 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<OlympusCalendar__c> 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<OlympusCalendar__c> :' + olympusCalendarDates);
|
Date result;
|
if (olympusCalendarDates.size() > 0) {
|
result = olympusCalendarDates.get(olympusCalendarDates.size() - 1).Date__c;
|
// System.debug('result' + result);
|
}
|
return result;
|
}
|
|
}
|