高章伟
2022-05-16 2e38b5c0b5e2ce302aed60be311f1c56986b1c06
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
public without sharing class SSOpportunityBatch implements Database.Batchable<SObject>, Database.Stateful {
    public static Integer FIELDMAX = 200;
    private final List<Id> TEST_ID = null;
    private BatchIF_Log__c iflog;
 
    /**
     * コンスタント、パラメータを受け取る
     */
    public SSOpportunityBatch(List<Id> testId) {
        TEST_ID = testId;
        System.debug('TEST_ID=' + TEST_ID);
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushNotification';
        iflog.Log__c  = 'SSOpportunityBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
    }
    
    public static String makeSql(SS_Batch_Column_Mapping__c setting, Set<String> 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<String>(apiTempSet), ',') + ' from ' + setting.Name;
        return soql;
    }
 
    public static Object getValue(SObject sobj, String field) {
        List<String> 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には、queryを実行、引合全件
     */
    public Database.QueryLocator start(Database.BatchableContext BC) {
        // select項目を oppMapping より生成
        SS_Batch_Column_Mapping__c oppMapping = SS_Batch_Column_Mapping__c.getValues('Opportunity');
        Set<String> apiTempSet = new Set<String>();
        apiTempSet.add('StageName');
        for (Integer i = 1; i <= FIELDMAX; i++) {
            String lpadI = ('00' + i).right(3);
            String fromColumn = 'From_Column_' + lpadI + '__c';
            String apiStr = String.valueOf(oppMapping.get(fromColumn));
            if (String.isBlank(apiStr) == false) {
                String ssColumn = 'SS_Column_' + lpadI + '__c';
                String ssApiStr = String.valueOf(oppMapping.get(ssColumn));
                if (ssApiStr.toLowerCase().startsWith('opportunity.')) {
                    // 商談の項目を更新、変更があるかどうか判断するため、元データも取得
                    System.debug('ssApiStr=' + ssApiStr + ', substring(12)=' + ssApiStr.substring(12));
                    apiTempSet.add(ssApiStr.substring(12));
                }
            }
        }
        String soql = makeSql(oppMapping, 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();
            nowDay = nowDay.addDays(-15);
            Integer iyear = nowDay.year();
            if (nowDay.month() < 4) {
                iyear -= 1;
            }
            Date thisYd = Date.valueOf(iyear + '-4-1');
            soql += ' where StageName = \'引合\' or StageName = \'注残\' or StageName = \'出荷\' or ((StageName = \'完了\' or StageName = \'削除\' or StageName = \'敗戦\') and SFDCLast_Process_Date__c >= :thisYd)';
            soql += '  or (StageName = \'完了\' and Shipping_Finished_Day_Func__c >= :thisYd)';
        }
        System.debug('soql=' + soql);
        return Database.getQueryLocator(soql);
    }
    
    public void execute(Database.BatchableContext BC, List<Opportunity> oppList) {
        List<Opportunity> updSelfList = new List<Opportunity>();
        List<SObject> insSSOppList = new List<SObject>();
        List<Id> insSSOppId = new List<Id>();
        List<SObject> insSSOliList = new List<SObject>();
        // 商談
        SS_Batch_Column_Mapping__c oppMapping = SS_Batch_Column_Mapping__c.getValues('Opportunity');
        Schema.SObjectType ssOppType = Schema.getGlobalDescribe().get(String.valueOf(oppMapping.get('SS_TableName__c')));
        for (Opportunity opp : oppList) {
            Boolean updSelfFlg = false;
            SObject insSSOpp = ssOppType.newSObject();
            for (Integer i = 1; i <= FIELDMAX; i++) {
                String lpadI = ('00' + i).right(3);
                String fromColumn = 'From_Column_' + lpadI + '__c';
                String apiStr = String.valueOf(oppMapping.get(fromColumn));
                if (String.isBlank(apiStr) == false) {
                    String ssColumn = 'SS_Column_' + lpadI + '__c';
                    String ssApiStr = String.valueOf(oppMapping.get(ssColumn));
                    if (ssApiStr.toLowerCase().startsWith('opportunity.')) {
                        // 商談の項目を更新、変更があるかどうか判断する
                        if (opp.get(ssApiStr.substring(12)) != opp.get(apiStr)) {
                            try {
                                opp.put(ssApiStr.substring(12), opp.get(apiStr));
                                updSelfFlg = true;
                            } catch (Exception e) {
                                iflog.ErrorLog__c = 'ERROR [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n';
                            }
                        }
                    } else {
                        try {
                            insSSOpp.put(ssApiStr, getValue(opp, apiStr));
                        } catch (Exception e) {
                            iflog.ErrorLog__c = 'ERROR ' + String.valueOf(oppMapping.get('SS_TableName__c')) + ' [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n';
                        }
                    }
                }
            }
            if (updSelfFlg) {
                updSelfList.add(opp);
            }
            // SS_Prospect_5days_list__c  の対象かどうか、loopの中単独判断
            //if (opp.StageName == '引合') {
            if (opp.StageName == '引合' || opp.StageName == '注残' || opp.StageName == '出荷' || opp.StageName == '完了' || opp.StageName == '削除') {
                insSSOppList.add(insSSOpp);
                insSSOppId.add(opp.Id);
            }
        }
 
        // 商談商品
        SS_Batch_Column_Mapping__c oliMapping = SS_Batch_Column_Mapping__c.getValues('OpportunityLineItem');
        // select項目を oliMapping より生成
        Set<String> apiTempSet = new Set<String>();
        String oliSql = makeSql(oliMapping, apiTempSet);
        oliSql += ' where OpportunityId IN :insSSOppId';
        Schema.SObjectType ssOliType = Schema.getGlobalDescribe().get(String.valueOf(oliMapping.get('SS_TableName__c')));
        for (OpportunityLineItem oli : Database.query(oliSql)) {
            SObject insSSOli = ssOliType.newSObject();
            insSSOliList.add(insSSOli);
            for (Integer i = 1; i <= FIELDMAX; i++) {
                String lpadI = ('00' + i).right(3);
                String fromColumn = 'From_Column_' + lpadI + '__c';
                String apiStr = String.valueOf(oliMapping.get(fromColumn));
                if (String.isBlank(apiStr) == false) {
                    String ssColumn = 'SS_Column_' + lpadI + '__c';
                    String ssApiStr = String.valueOf(oliMapping.get(ssColumn));
                    try {
                        insSSOli.put(ssApiStr, getValue(oli, apiStr));
                    } catch (Exception e) {
                        iflog.ErrorLog__c = 'ERROR ' + String.valueOf(oppMapping.get('SS_TableName__c')) + ' [' + apiStr + '] => [' + ssApiStr + ']' + e.getMessage() + '\n';
                    }
                }
            }
        }
 
        if (Oly_TriggerHandler.isBypassed('PowerBIBaseHandler') == false) {
            Oly_TriggerHandler.bypass('PowerBIBaseHandler');
        }
 
        // エラーをlogに書き出す
        if (updSelfList.size() > 0) {
System.debug('updSelfList:' + updSelfList);
            // SWAG-CE55BX 预测优化 start
            StaticParameter.EscapeOppandStaTrigger = true;
            // SWAG-CE55BX 预测优化 end
            Database.SaveResult[] lsr = Database.update(updSelfList, false);
            List<Opportunity> reuseUpdateList = new List<Opportunity>();
            for (Integer tIdx = 0; tIdx < lsr.size(); tIdx++) {
                Database.SaveResult sr = lsr[tIdx];
System.debug('sr.isSuccess:' + sr.isSuccess());
                if (!sr.isSuccess()) {
                    //wangweipeng   20210618   获取没有update的数据
                    reuseUpdateList.add(updSelfList[tIdx]);
 
 
                    /*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].Opportunity_No__c + ' Opportunity:' + emsg + '\n';
                    }
                        // iflog.ErrorLog__c += 'ERROR ' + updSelfList[tIdx].Opportunity_No__c + ' Opportunity:' + emsg + '\n';
                    //update by Gzw 2020-10-30 end
                    */
                }
            }
 
            //wangweipeng  20210618  如果update失败,重复更新,最多3次,如果失败记录日志  start 
            if(reuseUpdateList != null && reuseUpdateList.size() > 0){
                reuseUpdate(reuseUpdateList,1);
            }
            //wangweipeng  20210618  如果update失败,重复更新,最多3次,如果失败记录日志  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('Opportunity_No__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];
                iflog.ErrorLog__c += 'ERROR  ' + insSSOliList[tIdx].get('Opportunity_number__c') + '  SS_oli:' + emsg + '\n';
            }
        }
    }
    
    public void finish(Database.BatchableContext BC) {
 
        if (Test.isRunningTest() == false && TEST_ID == null) {
            Database.executeBatch(new SSBackorderBatch(null), 100);
        }
 
        iflog.Log__c += '\nSSOpportunityBatch 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;
    }
 
    //wangweipeng  20210618  如果update失败,重复更新,最多3次,如果失败记录日志  start 
    //参数:updSelfList   要重新插入的数据     indexUpdate   第几次插入
    public void reuseUpdate(List<Opportunity> updSelfList,Integer indexUpdate){
        System.debug('这是此方法走的第:'+indexUpdate+' 次了。');
        // SWAG-CE55BX 预测优化 start
        StaticParameter.EscapeOppandStaTrigger = true;
        // SWAG-CE55BX 预测优化 end
        Database.SaveResult[] lsr = Database.update(updSelfList, false);
        List<Opportunity> reuseUpdateList = new List<Opportunity>();
        for (Integer tIdx = 0; tIdx < lsr.size(); tIdx++) {
            Database.SaveResult sr = lsr[tIdx];
            if (!sr.isSuccess()) {
                if(indexUpdate >= 3){
                    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].Opportunity_No__c + ' Opportunity:' + emsg + '\n';
                    }
                        // iflog.ErrorLog__c += 'ERROR ' + updSelfList[tIdx].Opportunity_No__c + ' Opportunity:' + emsg + '\n';
                    //update by Gzw 2020-10-30 end
                }else{
                    //获取没有update的数据
                    reuseUpdateList.add(updSelfList[tIdx]);
                }
            }
        }
        if(indexUpdate < 3){
            indexUpdate ++;
            if(reuseUpdateList != null && reuseUpdateList.size() > 0){
                reuseUpdate(reuseUpdateList,indexUpdate);
            }
        }
    }
    //wangweipeng  20210618  如果update失败,重复更新,最多3次,如果失败记录日志  end
}