/* * @author 李 逸飛 * @date 2018.11.6 * @related OLY_OCM-473 * A Batch for generate/update Product_CategoryPrice_Table */ global without sharing class ET_Product_CategoryPrice_Table_Batch implements Database.Batchable, Database.Stateful{ global Integer totalCount = 0; // 总件数 global Integer executedCount = 0; global Integer successCount = 0; // 成功件数 global Integer failedCount = 0; // 失败件数 global String errMsgBody = ''; // 错误信息汇总 // global Boolean isAllFlag = false; global Database.QueryLocator start(Database.BatchableContext BC){ System.debug('********** ET_Product_CategoryPrice_Table_Batch ' + BC.getJobId() + 'start'); Date systemDate = Date.today(); systemDate = systemDate.addDays(-Integer.valueof(System.Label.ET_Date_Calculate)); Set s = new Set{'停止','有効','有効(再申請中)','失効(期限内生産済在庫対応)'}; Product2 p = [SELECT Plan_Term__c FROM Product2 WHERE Is_ET_APP__c = TRUE AND Category3__c <> '' AND SFDA_Status__c IN :s LIMIT 1]; String term = p.Plan_Term__c.left(4); /* * 按财年代码筛选本次 Batch 产生/更新的行 */ Product_CategoryPrice_Table__c [] pcts = [ SELECT Id FROM Product_CategoryPrice_Table__c WHERE OCM_Term__c = :term ]; /* * 清除表中临时统计信息 */ for(Product_CategoryPrice_Table__c pct: pcts) { pct.put('Product_Amount__c',0); pct.put('Product_Total_Price__c',0); } update pcts; /* * 构造 SOQL 查询, * 从产品表获取 { * Plan_Term__c: 计画财年 * Category3__c: 第三分类 * Intra_Trade_List_RMB__c: 内贸定价(RMB) * } * 字段 */ String query = 'SELECT Id, Intra_Trade_List_RMB__c, Asset_Model_No__c,' + ' Category3__c, Category4__c, Plan_Term__c' + ' FROM Product2' + ' where Is_ET_APP__c = true '; // if (true != this.isAllFlag) { // query += ' and LastModifiedDate >= :systemDate '; // } query += ' and Category3__c <> \'\' ' + ' and SFDA_Status__c in :s'; return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, List productList){ totalCount += productList.size(); Map> uniKeyToPDListMap = new Map>(); System.debug('ET_Product_CategoryPrice_Table_Batch execute start'); /* * 参照项目 ‘OLY财年’ 说明,财年应取产品计划财年前三码+'P' * 产品分类价格表项的 UniqueKey 以 计画财年:第三分类:第4分类 记入; * 以此 UniqueKey 分类产品 */ if(!productList.isEmpty()){ for (Product2 pd : productList){ String uniKey = pd.Plan_Term__c.left(4)+':'+pd.Category3__c+':'+pd.Category4__c; if ('吸引活检针' == pd.Category4__c && 'EUS' == pd.Category3__c) { if (pd.Asset_Model_No__c.startsWith('NA-U200H')) { uniKey = pd.Plan_Term__c.left(4) + ':' + pd.Category3__c + ':吸引活检针-EZ3P'; } else { uniKey = pd.Plan_Term__c.left(4) + ':' + pd.Category3__c + ':吸引活检针-EZ3P以外'; } } else if ('先端系粘膜切开刀' == pd.Category4__c && 'ESD' == pd.Category3__c) { if (pd.Asset_Model_No__c.startsWith('KD-655')) { uniKey = pd.Plan_Term__c.left(4) + ':' + pd.Category3__c + ':先端系粘膜切开刀-DualJ'; } else { uniKey = pd.Plan_Term__c.left(4) + ':' + pd.Category3__c + ':先端系粘膜切开刀-DualJ以外'; } } if(uniKeyToPDListMap.get(uniKey) == null){ uniKeyToPDListMap.put(uniKey,new List()); } List pdList = uniKeyToPDListMap.get(uniKey); pdList.add(pd); } } /* * 从产品分类价格表筛选本次执行中涉及的类目 */ Map PCPTableMap = new Map(); Product_CategoryPrice_Table__c [] pcts = [ SELECT Id, UniqueKey__c, Product_Amount__c, Product_Total_Price__c FROM Product_CategoryPrice_Table__c WHERE UniqueKey__c IN :uniKeyToPDListMap.keySet() ]; for(Product_CategoryPrice_Table__c pct: pcts) { PCPTableMap.put(pct.UniqueKey__c,pct); } /* * 创建或更新每条记录的总量与总金额 */ for(String uniKey: uniKeyToPDListMap.keySet()) { Product_CategoryPrice_Table__c pct = PCPTableMap.get(uniKey); if (pct == null) { String [] termAndCategories = uniKey.split(':'); pct = new Product_CategoryPrice_Table__c( UniqueKey__c = uniKey, OCM_Term__c = termAndCategories[0], Category3__c = termAndCategories[1], Category4__c = termAndCategories[2], Product_Total_Price__c = 0, Product_Amount__c = 0 ); PCPTableMap.put(uniKey, pct); } Decimal totalPrice = pct.Product_Total_Price__c; Decimal amount = pct.Product_Amount__c; List pdList = uniKeyToPDListMap.get(uniKey); for (Product2 pd : pdList) { totalPrice += pd.Intra_Trade_List_RMB__c; amount++; } pct.put('Product_Total_Price__c', totalPrice); pct.put('Product_Amount__c', amount); // Decimal avg = Math.floor((totalPrice / amount * 0.7)*100+0.5) / 100.0; // pct.put('Category4_5_Avg_Price__c',avg); } Database.UpsertResult[] urList = Database.upsert(PCPTableMap.values(),Product_CategoryPrice_Table__c.UniqueKey__c,false); Integer i = 0; for(Database.UpsertResult ur : urList) { if(ur.isSuccess()){ successCount++; } else{ failedCount++; for (Database.Error err : ur.getErrors()){ String msg = 'UniqueKey :' + PCPTableMap.values()[i].UniqueKey__c + ' ; ' + err.getStatusCode() + '; ' + err.getFields() + ' ; ' + err.getMessage(); errMsgBody += msg + '\n'; } } i++; } executedCount += productList.size(); System.debug('ET_Product_CategoryPrice_Table_Batch execute end'); } global void finish(Database.BatchableContext BC){ System.debug('ET_Product_CategoryPrice_Table_Batch finish method start'); String title = '产品分类价格表 Batch'; BatchEmailUtil eb = new BatchEmailUtil(); String[] emailList = new String[] {}; // 失败件数为0 寄出成功的mail if (failedCount == 0 && totalCount == executedCount) { String emailLabel = 'BatchNotify'; for (OrgWideEmailAddress tmpEmailObj : [SELECT Id, Address, DisplayName FROM OrgWideEmailAddress WHERE DisplayName = :emailLabel]) { emailList.add(tmpEmailObj.Address); } eb.successMail(emailList, null, title, executedCount); } else { if (totalCount != executedCount) { errMsgBody += '有一部分Batch没有运行, 请确认系统管理员。\n'; } eb.failedMail(title, errMsgBody, totalCount, executedCount, failedCount); } eb.send(); System.debug('ET_Product_CategoryPrice_Table_Batch finish method end'); } }