/* 发货 到货 出库 的明细2 每个月做快照 */ public without sharing class SSdetails2Batch implements Database.Batchable, Database.Stateful { public String query; public Integer FIELDMAX = 200; public String testId; public BatchIF_Log__c iflog; public Date tempDate; //查询开始日 public Date startDay; //查询结束日 public Date endDay; //今天 Date today = Date.today(); public SSdetails2Batch() { this.query = query; //获取当前月的第一天 Date tempDay = Date.newInstance(today.year(), today.month(), 1); //结束日 当前月第一天的的前一天 endDay = tempDay.addDays(-1); //开始日, 结束日当月的第一天 startDay = Date.newInstance(endDay.year(), endDay.month(), 1); iflog = new BatchIF_Log__c(); iflog.Type__c = 'details2Snapshot'; iflog.Log__c = 'SSdetails2Batch start\n'; iflog.Log__c += '开始日期:'+startDay +'\n'; iflog.Log__c += '结束日期:'+endDay +'\n'; iflog.ErrorLog__c = ''; insert iflog; } //传入了id 则以id为条件啊进行查询,不需要日期了 public SSdetails2Batch(String testId) { this.query = query; this.testId = testId; iflog = new BatchIF_Log__c(); iflog.Type__c = 'details2Snapshot'; iflog.Log__c = 'SSdetails2Batch start\n'; iflog.Log__c += '传入id:'+testId +'\n'; iflog.ErrorLog__c = ''; insert iflog; } //快照 传入日期的 发货 到货 出库 数据 // public SSdetails2Batch(Date tempDate) { // this.query = query; // this.testId = testId; // //开始日 传入日期的前一天 // startDay = tempDate.addDays(-1); // //结束日, 传入日期的后一天 // endDay = tempDate.addDays(1); // iflog = new BatchIF_Log__c(); // iflog.Type__c = 'details2Snapshot'; // iflog.Log__c = 'SSdetails2Batch start\n'; // iflog.ErrorLog__c = ''; // insert iflog; // } public Database.QueryLocator start(Database.BatchableContext bc) { //从快照表里取得待查询的字段 SS_Batch_Column_Mapping__c columnsmap = SS_Batch_Column_Mapping__c.getValues('Consumable_order_details2__c'); Set apiTempSet = new Set(); for (Integer i = 1; i <= FIELDMAX; i++) { String lpadI = ('00' + i).right(3); String fromColumn = 'From_Column_' + lpadI + '__c'; String apiStr = String.valueOf(columnsmap.get(fromColumn)); if (String.isBlank(apiStr) == false) { apiTempSet.add(apiStr); } } // query = 'select id, '+String.join(new List(apiTempSet), ',') + ' from Consumable_order_details2__c where '; if (testId != null && testId != '') { query += ' id = :testId'; }else{ // query += ' (Deliver_date__c >= :startDay and Deliver_date__c <= :endDay) '; query += ' (Deliver_date__c >= :startDay and Deliver_date__c <= :endDay) '; query += ' or (Arrive_date__c >= :startDay and Arrive_date__c <= :endDay) '; query += ' or (Product_OutDate__c >= :startDay and Product_OutDate__c <= :endDay)'; } return Database.getQueryLocator(query); } public void execute(Database.BatchableContext BC, list detailList) { //获取待快照的表中字段 SS_Batch_Column_Mapping__c condet2map = SS_Batch_Column_Mapping__c.getValues('Consumable_order_details2__c'); Schema.SObjectType condetType = Schema.getGlobalDescribe().get(String.valueOf(condet2map.get('SS_TableName__c'))); //待添加的数据(快照表) List insList = new List(); for (Consumable_order_details2__c contet2 : detailList) { //创建新的快照表对象 SObject orderDetail2 = condetType.newSObject(); for (Integer i = 1; i <= FIELDMAX; i++) { String lpadI = ('00' + i).right(3); String fromColumn = 'From_Column_' + lpadI + '__c'; //获取到明细2表的api名称 String apiStr = String.valueOf(condet2map.get(fromColumn)); if (String.isBlank(apiStr) == false) { String ssColumn = 'SS_Column_' + lpadI + '__c'; //快照表的api String ssApiStr = String.valueOf(condet2map.get(ssColumn)); try { //赋值 orderDetail2.put(ssApiStr, getValue(contet2, apiStr)); } catch (Exception e) { iflog.ErrorLog__c = 'ERROR ' + String.valueOf(condet2map.get('SS_TableName__c')) + ' [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n'; } } } insList.add(orderDetail2); } if (insList.size() > 0) { Database.SaveResult[] lsr = Database.insert(insList, false); for (Integer tIdx = 0; tIdx < lsr.size(); tIdx++) { Database.SaveResult sr = lsr[tIdx]; //插入失败 保存失败原因 if (!sr.isSuccess()) { Database.Error emsg = sr.getErrors()[0]; iflog.ErrorLog__c += '插入失败: ' + insList[tIdx].Id +' error:'+ emsg + '\n'; } } } } public static Object getValue(SObject sobj, String field) { List fieldPathList = field.split('\\.'); Object rtn = null; for (Integer i = 0; i < fieldPathList.size(); i++) { String fieldPath = fieldPathList[i]; if (i == fieldPathList.size() - 1) { rtn = sobj.get(fieldPath); System.debug(rtn + '= sobj.get(' + fieldPath + ')'); } else { sobj = sobj.getSObject(fieldPath); if (sobj == null) { break; } System.debug(sobj + '= sobj.getSObject(' + fieldPath + ')'); } } return rtn; } public void finish(Database.BatchableContext BC) { iflog.Log__c += '\nSSdetails2Batch 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; } } /*public without sharing class SSdetails2Batch implements Database.Batchable, Database.Stateful { public static Integer FIELDMAX = 200; private final List TEST_ID = null; private BatchIF_Log__c iflog; public SSdetails2Batch() { iflog = new BatchIF_Log__c(); iflog.Type__c = 'details2Snapshot'; iflog.Log__c = 'SSdetails2Batch start\n'; iflog.ErrorLog__c = ''; insert iflog; } //消耗品明细2的数据快照到一个新的快照,连续接受参数。 public SSdetails2Batch(List testId) { TEST_ID = testId; System.debug('TEST_ID=' + TEST_ID); iflog = new BatchIF_Log__c(); iflog.Type__c = 'details2Snapshot'; iflog.Log__c = 'SSdetails2Batch start\n'; iflog.ErrorLog__c = ''; insert iflog; } //创造soql public static String makeSql(SS_Batch_Column_Mapping__c setting, Set apiTempSet) { apiTempSet.add('Id'); for (Integer i = 1; i <= FIELDMAX; i++) { String fromColumn = 'From_Column_' + ('00' + i).right(3) + '__c'; String apiStr = String.valueOf(setting.get(fromColumn)); if (String.isBlank(apiStr) == false && apiTempSet.contains(apiStr) == false) { apiTempSet.add(apiStr); } } String soql = 'Select ' + String.join(new List(apiTempSet), ',') + ' from ' + setting.Name; return soql; } //取值 public static Object getValue(SObject sobj, String field) { List fieldPathList = field.split('\\.'); Object rtn = null; for (Integer i = 0; i < fieldPathList.size(); i++) { String fieldPath = fieldPathList[i]; if (i == fieldPathList.size() - 1) { rtn = sobj.get(fieldPath); System.debug(rtn + '= sobj.get(' + fieldPath + ')'); } else { sobj = sobj.getSObject(fieldPath); if (sobj == null) { break; } System.debug(sobj + '= sobj.getSObject(' + fieldPath + ')'); } } return rtn; } //在start中,执行查询并合并所有项目 public Database.QueryLocator start(Database.BatchableContext BC) { // 从 condet2map 生成 select 项 SS_Batch_Column_Mapping__c condet2map = SS_Batch_Column_Mapping__c.getValues('Consumable_order_details2__c'); Set apiTempSet = new Set(); for (Integer i = 1; i <= FIELDMAX; i++) { String lpadI = ('00' + i).right(3); String fromColumn = 'From_Column_' + lpadI + '__c'; String apiStr = String.valueOf(condet2map.get(fromColumn)); if (String.isBlank(apiStr) == false) { String ssColumn = 'SS_Column_' + lpadI + '__c'; String ssApiStr = String.valueOf(condet2map.get(ssColumn)); if (ssApiStr.toLowerCase().startsWith('Consumable_order_details2__c')) { // 更新消耗品明细2中的字段,并检索原始数据以确定是否有任何更改 System.debug('ssApiStr=' + ssApiStr + ', substring(28)=' + ssApiStr.substring(28)); apiTempSet.add(ssApiStr.substring(28)); } } } String soql = makeSql(condet2map, apiTempSet); if (TEST_ID <> null) { soql += ' where Id IN: TEST_ID'; } else { // SS_Prospect_5days_list__c の対象かどうか、loopの中単独判断 // soql += ' where StageName = \'引合\''; // CHAN-AUE3TB Batch SSOpportunity的执行数据筛选 Date nowDay = Date.today(); Integer nowMonth = nowDay.month(); soql += ' where (CALENDAR_MONTH(Deliver_date__c) = :nowMonth or CALENDAR_MONTH(Arrive_date__c) = :nowMonth or CALENDAR_MONTH(Product_OutDate__c)= :nowMonth)'; } System.debug('soql=' + soql); return Database.getQueryLocator(soql); } public void execute(Database.BatchableContext BC, List oppList) { List updSelfList = new List(); List insSSOppList = new List(); List insSSOppId = new List(); List insSSOliList = new List(); // 商談 SS_Batch_Column_Mapping__c condet2map = SS_Batch_Column_Mapping__c.getValues('Consumable_order_details2__c'); Schema.SObjectType condetType = Schema.getGlobalDescribe().get(String.valueOf(condet2map.get('SS_TableName__c'))); for (Consumable_order_details2__c contet2 : oppList) { Boolean updSelfFlg = false; SObject orderDetail2 = condetType.newSObject(); for (Integer i = 1; i <= FIELDMAX; i++) { String lpadI = ('00' + i).right(3); String fromColumn = 'From_Column_' + lpadI + '__c'; String apiStr = String.valueOf(condet2map.get(fromColumn)); if (String.isBlank(apiStr) == false) { String ssColumn = 'SS_Column_' + lpadI + '__c'; String ssApiStr = String.valueOf(condet2map.get(ssColumn)); if (ssApiStr.toLowerCase().startsWith('Consumable_order_details2__c')) { // 更新每月初追溯清单中的字段,以确定是否有任何更改 if (contet2.get(ssApiStr.substring(12)) != contet2.get(apiStr)) { try { contet2.put(ssApiStr.substring(12), contet2.get(apiStr)); updSelfFlg = true; } catch (Exception e) { iflog.ErrorLog__c = 'ERROR [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n'; } } } else { try { orderDetail2.put(ssApiStr, getValue(contet2, apiStr)); } catch (Exception e) { iflog.ErrorLog__c = 'ERROR ' + String.valueOf(condet2map.get('SS_TableName__c')) + ' [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n'; } } } } if (updSelfFlg) { updSelfList.add(contet2); } // SS_Prospect_5days_list__c の対象かどうか、loopの中単独判断 //if (contet2.StageName == '引合') { Date nowDay = Date.today(); Integer nowMonth = nowDay.month(); if ((contet2.Deliver_date__c != null && contet2.Deliver_date__c.month() == nowMonth) || (contet2.Arrive_date__c != null && contet2.Arrive_date__c.month() == nowMonth) || (contet2.Product_OutDate__c != null && contet2.Product_OutDate__c.month() == nowMonth)) { insSSOppList.add(orderDetail2); insSSOppId.add(contet2.Id); } } // エラーをlogに書き出す if (updSelfList.size() > 0) { System.debug('updSelfList:' + updSelfList); Database.SaveResult[] lsr = Database.update(updSelfList, false); for (Integer tIdx = 0; tIdx < lsr.size(); tIdx++) { Database.SaveResult sr = lsr[tIdx]; System.debug('sr.isSuccess:' + sr.isSuccess()); if (!sr.isSuccess()) { Database.Error emsg = sr.getErrors()[0]; //update by Gzw 2020-10-30 start if (!String.valueOf(emsg.getStatusCode()).contains('INACTIVE_OWNER_OR_USER')) { iflog.ErrorLog__c += 'ERROR ' + updSelfList[tIdx].Bar_Code__c + ' Consumable_order_details2__c:' + emsg + '\n'; } // iflog.ErrorLog__c += 'ERROR ' + updSelfList[tIdx].Opportunity_No__c + ' Opportunity:' + emsg + '\n'; //update by Gzw 2020-10-30 end } } } //insert insSSOppList; Database.SaveResult[] lsr2 = Database.insert(insSSOppList, false); for (Integer tIdx = 0; tIdx < lsr2.size(); tIdx++) { Database.SaveResult sr = lsr2[tIdx]; if (!sr.isSuccess()) { Database.Error emsg = sr.getErrors()[0]; //update by rentx 2020-10-27 start if (!String.valueOf(emsg.getStatusCode()).contains('INACTIVE_OWNER_OR_USER')) { iflog.ErrorLog__c += 'ERROR ' + insSSOppList[tIdx].get('Bar_Code__c') + ' SS_opp:' + emsg + '\n'; } //update by rentx 2020-10-27 end // iflog.ErrorLog__c += 'ERROR ' + insSSOppList[tIdx].get('Opportunity_No__c') + ' SS_opp:' + emsg + '\n'; } } //insert insSSOliList; Database.SaveResult[] lsr3 = Database.insert(insSSOliList, false); for (Integer tIdx = 0; tIdx < lsr3.size(); tIdx++) { Database.SaveResult sr = lsr3[tIdx]; if (!sr.isSuccess()) { Database.Error emsg = sr.getErrors()[0]; //update by Gzw 2020-10-30 start if (!String.valueOf(emsg.getStatusCode()).contains('INACTIVE_OWNER_OR_USER')) { iflog.ErrorLog__c += 'ERROR ' + insSSOliList[tIdx].get('Bar_Code__c') + ' SS_oli:' + emsg + '\n'; } // iflog.ErrorLog__c += 'ERROR ' + insSSOliList[tIdx].get('Opportunity_number__c') + ' SS_oli:' + emsg + '\n'; //update by Gzw 2020-10-30 end } } } public void finish(Database.BatchableContext BC) { if (Test.isRunningTest() == false && TEST_ID == null) { Database.executeBatch(new SSBackorderBatch(null), 100); } iflog.Log__c += '\nSSdetails2Batch 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; } }*/