高章伟
2022-02-18 8b5f4c6c281cfa548f92de52c8021e37aa81901e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
    Schedule: UpdateAgencyProductTargetSchedule
    引合いの製品区分をAからBに変更したとき、A目標も対象にしないといけないため、Batch側で修正する目標は全部にしないといけないです。
    TODO 今後データ量増加により、変更差分のbatchにする仕組みを考える必要です。
 */
global class UpdateAgencyOppProductTargetBatch implements Database.Batchable<AggregateResult> {
    
    String term;
    Id rtId;
    
    global UpdateAgencyOppProductTargetBatch() {
        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> {
        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<AggregateResult> {
        private String query;
 
        public AggregateResultIterable(String soql){
            query = soql;
        }
 
        public Iterator<AggregateResult> Iterator(){
            return new AggregateResultIterator(query);
        }
    }
    
    global Iterable<AggregateResult> start(Database.BatchableContext BC) {
        //Id rtId = [select Id,DeveloperName from RecordType where IsActive = true and SobjectType = 'Agency_Opportunity__c' and DeveloperName = 'Target'].Id;
        //String query = 'select Id, Agency_Hospital__c, Department_Cateogy__c, Product_Category1__c, Product_Category2__c, Product_Category3__c' +
        //    '  from Agency_Opportunity__c' +
        //    ' where RecordTypeId = :rtId and tem_OCM_Term__c = :term and needBatch__c = true'; // TODO Wangwf and aoop.XXXXX < LastModifiedDate';
        String query = 'select Agency_ID__c ' +
            'from Agency_Opportunity__c ' +
            'where RecordTypeId = \''+rtId+'\' and OCM_Term__c = \''+term+'\' group by Agency_ID__c';
        //return Database.getQueryLocator(query);
        return new AggregateResultIterable(query);
    }
 
       global void execute(Database.BatchableContext BC, List<AggregateResult> scope) {
           //Id rtId = [select Id,DeveloperName from RecordType where IsActive = true and SobjectType = 'Agency_Opportunity__c' and DeveloperName = 'Target'].Id;
           Set<String> agencyIdSet = new Set<String>();
        for (AggregateResult so : scope) {
            String agencyId = (String)so.get('Agency_ID__c');
            agencyIdSet.add(agencyId);
        }
 
        List<Agency_Opportunity__c> targetList = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c from Agency_Opportunity__c 
                                                where RecordTypeId = :rtId and OCM_Term__c = :term and Agency_ID__c in :agencyIdSet and Is_OPDSIS_Target__c != true];
            
        AggregateResult[] product1Counts = [select Agency_Hospital__c, Department_Cateogy__c, Product_Category1__r.Name2__c pname, count(Id) cnt 
            from Agency_Opportunity__c 
            where Product_Category1__c != null and tem_OCM_Term__c = :term and Agency_ID__c in :agencyIdSet
            group by Agency_Hospital__c, Department_Cateogy__c , Product_Category1__r.Name2__c];
        Map<String, Integer> count1 = new Map<String, Integer>();
        for (AggregateResult product1Count : product1Counts) {
            String ahl = (String)product1Count.get('Agency_Hospital__c');
            String dc = (String)product1Count.get('Department_Cateogy__c');
            String name2 = (String)product1Count.get('pname');
            //String name2 = (String)p1.get('Name2__c');
            //String name2 = (String)((Map<String,Object>)product1Count.get('Product_Category1__r').get('Name2__c'));
            Integer cnt = (Integer)product1Count.get('cnt');
            String key = ahl+':'+dc+':'+name2;
 
            count1.put(key, cnt);
        }
 
        AggregateResult[] product2Counts = [select Agency_Hospital__c, Department_Cateogy__c, Product_Category2__r.Name2__c pname, count(Id) cnt 
            from Agency_Opportunity__c 
            where Product_Category2__c != null and tem_OCM_Term__c = :term and Agency_ID__c in :agencyIdSet
            group by Agency_Hospital__c, Department_Cateogy__c , Product_Category2__r.Name2__c];
        Map<String, Integer> count2 = new Map<String, Integer>();
        for (AggregateResult product2Count : product2Counts) {
            String ahl = (String)product2Count.get('Agency_Hospital__c');
            String dc = (String)product2Count.get('Department_Cateogy__c');
            String name2 = (String)product2Count.get('pname');
            //Map<String,Object> p2 = (Map<String,Object>)product2Count.get('Product_Category2__r');
            //String name2 = (String)p2.get('Name2__c');
            //String name2 = (String)product2Count.get('Product_Category2__r').get('Name2__c');
            Integer cnt = (Integer)product2Count.get('cnt');
            String key = ahl+':'+dc+':'+name2;
 
            count2.put(key, cnt);
        }
 
        AggregateResult[] product3Counts = [select Agency_Hospital__c, Department_Cateogy__c, Product_Category3__r.Name2__c pname, count(Id) cnt 
            from Agency_Opportunity__c 
            where Product_Category3__c != null and tem_OCM_Term__c = :term and Agency_ID__c in :agencyIdSet
            group by Agency_Hospital__c, Department_Cateogy__c , Product_Category3__r.Name2__c];
        Map<String, Integer> count3 = new Map<String, Integer>();
        for (AggregateResult product3Count : product3Counts) {
            String ahl = (String)product3Count.get('Agency_Hospital__c');
            String dc = (String)product3Count.get('Department_Cateogy__c');
            String name2 = (String)product3Count.get('pname');
            //Map<String,Object> p3 = (Map<String,Object>)product3Count.get('Product_Category3__r');
            //String name2 = (String)p3.get('Name2__c');
            //String name2 = (String)product3Count.get('Product_Category3__r').get('Name2__c');
            Integer cnt = (Integer)product3Count.get('cnt');
            String key = ahl+':'+dc+':'+name2;
 
            count3.put(key, cnt);
        }
 
        for (Agency_Opportunity__c target : targetList) {
            String key = target.Agency_Hospital_Target__c+':'+target.Department_Cateogy__c+':'+target.Product_Category__r.Name2__c;
            Integer count = 0;
            if (count1.containsKey(key)) {
                count += count1.get(key);
            }
            if (count2.containsKey(key)) {
                count += count2.get(key);
            }
            if (count3.containsKey(key)) {
                count += count3.get(key);
            }
            target.Product_Category_Opp_Count__c = count;
            if (count == 0) target.Product_Category_Opp_Count__c = null;
        }
 
        if (targetList.size() > 0) {
            update targetList;
        }
           
        //Set<String> pcIdSet = new Set<String>();
        //for (Agency_Opportunity__c aopp : scope) {
        //    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);
 
        //List<Agency_Opportunity__c> targetList = [select Id, Agency_Hospital_Target__c, Department_Cateogy__c, Product_Category__r.Name2__c from Agency_Opportunity__c 
        //                                            where RecordTypeId = :rtId and OCM_Term__c = :term /*and Product_Category__c in :pcIdSet*/ and Department_Cateogy__c != null];
 
 
    }
    
    global void finish(Database.BatchableContext BC) {
        //do nothing
    }
    
}