/**
|
* Created by T on 2020/5/14.
|
*/
|
|
public with sharing class MonthEndAutoJudgeBatch implements Database.Batchable<SObject>, Database.Stateful {
|
public final List<Id> 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<Id> 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<String> paymentStatus = new List<String>();
|
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<Statu_Achievements__c> staList) {
|
Savepoint sp = Database.setSavepoint();
|
// 获取本月1号
|
Date toDate = Date.today();
|
Date mon1stDate = Date.newInstance(toDate.year(), toDate.month(), 1);
|
try {
|
// 需要更新的数据
|
List<Statu_Achievements__c> updateList = new List<Statu_Achievements__c>();
|
// 只要标记为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<OpportunitySpecialApply__c> newOpportunitySpecialApply = new List<OpportunitySpecialApply__c>();
|
// 将直接修改注残 改为 新建询价注残特殊对应审批
|
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<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;
|
}
|
|
}
|