/* Schedule: UpdateAgencyProductTargetSchedule 週報の製品区分をAからBに変更したとき、A目標も対象にしないといけないため、Batch側で修正する目標は全部にしないといけないです。 TODO 今後データ量増加により、変更差分のbatchにする仕組みを考える必要です。 */ global class UpdateAgencyRptProductTargetBatch implements Database.Batchable { String term; Id rtId; global UpdateAgencyRptProductTargetBatch() { Date dateToday = Date.today(); Integer year = dateToday.year(); Integer month = dateToday.month(); if (month < 4) { year -= 1; } term = String.valueOf(year - 1867) + 'P'; rtId = [select Id,DeveloperName from RecordType where IsActive = true and SobjectType = 'Agency_Opportunity__c' and DeveloperName = 'Target'].Id; } public class AggregateResultIterator implements Iterator { AggregateResult [] results {get;set;} // tracks which result item is returned Integer index {get; set;} public AggregateResultIterator(String query) { index = 0; // Fire query here to load the results results = Database.query(query); } public boolean hasNext(){ return results != null && !results.isEmpty() && index < results.size(); } public AggregateResult next(){ return results[index++]; } } public class AggregateResultIterable implements Iterable { private String query; public AggregateResultIterable(String soql){ query = soql; } public Iterator Iterator(){ return new AggregateResultIterator(query); } } global Iterable start(Database.BatchableContext BC) { //String query = 'select Id, Target_Product__c, Agency_Hospital__c, Department_Cateogy__c, Product_Category1__c, Product_Category2__c, Product_Category3__c' + // ' from Agency_Report__c ' + // ' where needBatch__c = true'; //rtId = [select Id,DeveloperName from RecordType where IsActive = true and SobjectType = 'Agency_Opportunity__c' and DeveloperName = 'Target'].Id; String query = 'select Agency_ID__c ' + 'from Agency_Opportunity__c ' + 'where RecordTypeId = \''+rtId+'\' and OCM_Term__c = \''+term+'\' group by Agency_ID__c'; return new AggregateResultIterable(query); } global void execute(Database.BatchableContext BC, List scope) { Integer m = Date.today().month(); Integer y = Date.today().year(); y = m > 3 ? y : y - 1; //Id rtId = [select Id,DeveloperName from RecordType where IsActive = true and SobjectType = 'Agency_Opportunity__c' and DeveloperName = 'Target'].Id; //Set pcIdSet = new Set(); //for (SObject so : scope) { // Agency_Report__c aopp = (Agency_Report__c) so; // pcIdSet.add(aopp.Product_Category1__c); // pcIdSet.add(aopp.Product_Category2__c); // pcIdSet.add(aopp.Product_Category3__c); // aopp.BatchUpdateDatetime__c = Datetime.now(); //} //if (scope.size() > 0) { // update scope; //} //system.debug(pcIdSet); Set agencyIdSet = new Set(); for (AggregateResult so : scope) { String agencyId = (String)so.get('Agency_ID__c'); agencyIdSet.add(agencyId); } List targetList = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c, Product_Category__r.OPD_Flg__c, Product_Category__r.SIS_Flg__c from Agency_Opportunity__c where RecordTypeId = :rtId and Agency_ID__c in :agencyIdSet and Is_OPDSIS_Target__c = true]; //group by 产品1的count数 AggregateResult[] product1Counts = [select Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category1__r.Name2__c pname, count(Id) cnt, max(Report_Date__c) rpDate from Agency_Report__c where Product_Category1__c != null and FISCAL_YEAR(Report_Date__c) = :y and Agency_ID__c in :agencyIdSet group by Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category1__r.Name2__c order by max(Report_Date__c)]; //OPD/SIS用 Map count1 = new Map(); //非OPD/SIS用 Map count1_Target = new Map(); Map maxDate1 = new Map(); Map maxDate1_Target = new Map(); for (AggregateResult product1Count : product1Counts) { String ahl = (String)product1Count.get('Agency_Hospital__c'); String pt = (String)((String)product1Count.get('Purpose_Type__c')).right(3); String pname = (String)product1Count.get('pname'); String dc = (String)product1Count.get('Department_Cateogy__c'); Integer cnt = (Integer)product1Count.get('cnt'); Date rpDate = (Date)product1Count.get('rpDate'); //key = 医院+战略科室+OPD/SIS+产品名 String key = ahl+':'+dc+':'+pt+':'+pname; if (pt != 'OPD' && pt != 'SIS') { //key = 医院+战略科室+产品名 key = ahl+':'+dc+':'+pname; if(count1_Target.containsKey(key)) { cnt = count1_Target.get(key) + cnt; } count1_Target.put(key, cnt); maxDate1_Target.put(key, rpDate); } else { if(count1.containsKey(key)) { cnt = count1.get(key) + cnt; } count1.put(key, cnt); maxDate1.put(key, rpDate); } } AggregateResult[] product2Counts = [select Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category2__r.Name2__c pname, count(Id) cnt, max(Report_Date__c) rpDate from Agency_Report__c where Product_Category2__c != null and FISCAL_YEAR(Report_Date__c) = :y and Agency_ID__c in :agencyIdSet group by Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category2__r.Name2__c order by max(Report_Date__c)]; Map count2 = new Map(); Map count2_Target = new Map(); Map maxDate2 = new Map(); Map maxDate2_Target = new Map(); for (AggregateResult product2Count : product2Counts) { String ahl = (String)product2Count.get('Agency_Hospital__c'); String pt = (String)((String)product2Count.get('Purpose_Type__c')).right(3); String pname = (String)product2Count.get('pname'); String dc = (String)product2Count.get('Department_Cateogy__c'); Integer cnt = (Integer)product2Count.get('cnt'); Date rpDate = (Date)product2Count.get('rpDate'); String key = ahl+':'+dc+':'+pt+':'+pname; if (pt != 'OPD' && pt != 'SIS') { //key = 医院+战略科室+产品名 key = ahl+':'+dc+':'+pname; if(count2_Target.containsKey(key)) { cnt = count2_Target.get(key) + cnt; } count2_Target.put(key, cnt); maxDate2_Target.put(key, rpDate); } else { if(count2.containsKey(key)) { cnt = count2.get(key) + cnt; } count2.put(key, cnt); maxDate2.put(key, rpDate); } } AggregateResult[] product3Counts = [select Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category3__r.Name2__c pname, count(Id) cnt, max(Report_Date__c) rpDate from Agency_Report__c where Product_Category3__c != null and FISCAL_YEAR(Report_Date__c) = :y and Agency_ID__c in :agencyIdSet group by Agency_Hospital__c, Department_Cateogy__c, Purpose_Type__c, Product_Category3__r.Name2__c order by max(Report_Date__c)]; Map count3 = new Map(); Map count3_Target = new Map(); Map maxDate3 = new Map(); Map maxDate3_Target = new Map(); for (AggregateResult product3Count : product3Counts) { String ahl = (String)product3Count.get('Agency_Hospital__c'); String pt = (String)((String)product3Count.get('Purpose_Type__c')).right(3); String pname = (String)product3Count.get('pname'); String dc = (String)product3Count.get('Department_Cateogy__c'); Integer cnt = (Integer)product3Count.get('cnt'); Date rpDate = (Date)product3Count.get('rpDate'); String key = ahl+':'+dc+':'+pt+':'+pname; if (pt != 'OPD' && pt != 'SIS') { //key = 医院+战略科室+产品名 key = ahl+':'+dc+':'+pname; if(count3_Target.containsKey(key)) { cnt = count3_Target.get(key) + cnt; } count3_Target.put(key, cnt); maxDate3_Target.put(key, rpDate); } else { if(count3.containsKey(key)) { cnt = count3.get(key) + cnt; } count3.put(key, cnt); maxDate3.put(key, rpDate); } } for (Agency_Opportunity__c target : targetList) { String pt = target.Product_Category__r.OPD_Flg__c ? 'OPD' : target.Product_Category__r.SIS_Flg__c ? 'SIS' : ''; String key = target.Agency_Hospital_Target__c+':'+target.Department_Cateogy__c+':'+pt+':'+target.Product_Category__r.Name2__c; //system.debug(key); Integer count = 0; Date mDate = null; if (count1.containsKey(key)) { count += count1.get(key); Date m1Date = maxDate1.get(key); if (mDate == null || m1Date > mDate) { mDate = m1Date; } } if (count2.containsKey(key)) { count += count2.get(key); Date m2Date = maxDate2.get(key); if (mDate == null || m2Date > mDate) { mDate = m2Date; } } if (count3.containsKey(key)) { count += count3.get(key); Date m3Date = maxDate3.get(key); if (mDate == null || m3Date > mDate) { mDate = m3Date; } } target.Product_Category_Rpt_Count__c = count; if (mDate != null) target.MaxActivityDate__c = mDate; if (count == 0) target.Product_Category_Rpt_Count__c = null; } List targetList2 = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c, Product_Category__r.OPD_Flg__c, Product_Category__r.SIS_Flg__c from Agency_Opportunity__c where RecordTypeId = :rtId and Agency_ID__c in :agencyIdSet and Is_OPDSIS_Target__c != true]; for (Agency_Opportunity__c target : targetList2) { String key = target.Agency_Hospital_Target__c+':'+target.Department_Cateogy__c+':'+target.Product_Category__r.Name2__c; Integer count = 0; Date mDate = null; if (count1_Target.containsKey(key)) { count += count1_Target.get(key); Date m1Date = maxDate1_Target.get(key); if (mDate == null || m1Date > mDate) { mDate = m1Date; } } if (count2_Target.containsKey(key)) { count += count2_Target.get(key); Date m2Date = maxDate2_Target.get(key); if (mDate == null || m2Date > mDate) { mDate = m2Date; } } if (count3_Target.containsKey(key)) { count += count3_Target.get(key); Date m3Date = maxDate3_Target.get(key); if (mDate == null || m3Date > mDate) { mDate = m3Date; } } if (mDate != null) target.MaxActivityDate__c = mDate; target.Product_Category_Rpt_Count__c = count; if (count == 0) target.Product_Category_Rpt_Count__c = null; } if (targetList.size() > 0) { update targetList; } if (targetList2.size() > 0) { update targetList2; } //List targetList = new List(); //List targetList2 = new List(); //for (Agency_Opportunity__c so : scope) { // if (so.Department_Cateogy__c == null) { // targetList.add(so); // } else { // targetList2.add(so); // } //} //List targetList = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c, Product_Category__r.OPD_Flg__c, Product_Category__r.SIS_Flg__c from Agency_Opportunity__c // where RecordTypeId = :rtId /*and Product_Category__c in :pcIdSet*/ and Department_Cateogy__c = null]; //system.debug(targetList); //List targetList2 = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c, Product_Category__r.OPD_Flg__c, Product_Category__r.SIS_Flg__c from Agency_Opportunity__c // where RecordTypeId = :rtId and Product_Category__c in :pcIdSet and Department_Cateogy__c != null]; } global void finish(Database.BatchableContext BC) { } }