高章伟
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
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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
global class CreatePassiveTaskBatch implements Database.Batchable<sObject>, Database.Stateful  {
 
    //自定义设置是根据当前年度产品生产预计所声明的api与产品名,
    //因为每年产品生产都有所变更,所以每年在产品生产任务确定后,
    //都要核对自定义设置中的产品api与产品名
    //此batch需要核对的是 PlanMonthAndAmount/PlanMonthAndAmountName/OPD_PlanMonth
    //自定义设置opd计划月与对应的opd计划数Api
    SS_Batch_Column_Mapping__c planMonthAndAmount = SS_Batch_Column_Mapping__c.getValues('PlanMonthAndAmount');
    //自定义设置opd计划月api与对应的opd计划数名字
    SS_Batch_Column_Mapping__c PlanMonthAndAmountName = SS_Batch_Column_Mapping__c.getValues('PlanMonthAndAmountName');
    // 报错的询价ID
    public String logstr = '';
    // 报错信息
    public String errorstr = '';
    public List<String> emailMessages = new List<String>();
    public Integer totalCount = 0; // 总件数
    public Integer failedCount = 0; // 失败件数
    Integer FIELDMAX = 30;
    //自定义设置opd计划数
    List<String> opdNumberList = new List<String>();
 
    //销售本部
    public String Salesdepartment_DeptClass;   // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 
 
    public String  testId ;  // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 
 
 
    //定义拼接opd计划月Api的自定义设置
    String planMonth = '';
    //定义拼接opd计划数Api的自定义设置
    String planNumber = '';
    //自定义设置opd计划月api与名字Map
    Map<String, String> opdPlanMonthMap =  new Map<String, String>();
    //opd计划月API与opd计划数Api的Map
    Map<String, String> planMonthAndAmountMap =  new Map<String, String>();
    //opd计划月api对应的opd计划数名字
    Map<String, list<String>> PlanMonthAndAmountNameMap =  new Map<String, list<String>>();
    Date dt = Date.today();
    string HPID = '';
 
    string departmentID = '';
    Boolean isAutoexec = false; //20210203 zh SWAG-BXQDHZ 是否自动执行
 
    //针对于单独某个医院
    global CreatePassiveTaskBatch(String TestID) {
        HPID = TestID;
        isAutoexec = false; //20210203 zh SWAG-BXQDHZ
    }
    //针对于单独某个战略科室
    global CreatePassiveTaskBatch(String TestID, boolean a) {
        departmentID = TestID;
        isAutoexec = false; //20210203 zh SWAG-BXQDHZ
    }
 
    global CreatePassiveTaskBatch() {
    }
    global CreatePassiveTaskBatch(Boolean tempOPD) {
        isAutoexec = tempOPD; //20210203 zh SWAG-BXQDHZ
    }
 
    // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 start
    //针对于单独某个销售本部
    global CreatePassiveTaskBatch(String TestSalesdepartment,String b) {
        this.Salesdepartment_DeptClass = TestSalesdepartment;
        this.isAutoexec = false; //20210203 zh SWAG-BXQDHZ
    }
     global CreatePassiveTaskBatch(String TestSalesdepartment,String b,string testId) {
        this.Salesdepartment_DeptClass = TestSalesdepartment;
        this.testId = testId;
        this.isAutoexec = false; //20210203 zh SWAG-BXQDHZ
    }
    // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 end
 
    global Database.QueryLocator start(Database.BatchableContext BC) {
 
        // 规定年份格式(今年四月份到下一年4月份为一年)(如:今年-1867+p 135p)
        //Datetime dt;
        Date dateToday = Date.today();
        Date nextmonth = dateToday.addMonths(1);
        //system.debug('nextmonth' + nextmonth);
        Integer year = nextmonth.year();
        Integer month = nextmonth.month() ;
        //system.debug('month' + month);
        if (month < 4) {
            year = year - 1;
        }
        String ThisPeriod = year - 1867 + 'P';
        //Integer ThisYear = Integer.valueOf(dt.year());
        //String  ThisPeriod =  ThisYear - 1867 + 'P';
        //String CurrentPeriodPaymentAmountBatchTest = data.valueOf(SUBSTR(data,6,7)) + '月';
        //String OPD_PlanMonth;
        //String OPD_Number;
 
        //opd计划月api不为空的拼接定义
        String planMonthString = '';
        String planMonthWhere = '';
 
        //获取自定义设置opd计划月api与opd计划数的名字
        for (Integer i = 1; i <= FIELDMAX; i++) {
            String lpadI = ('00' + i).right(3);
            String fromColumn = 'From_Column_' + lpadI + '__c';
            //system.debug('fromColumn' + fromColumn);
            // api
            String apiStr = String.valueOf(PlanMonthAndAmountName.get(fromColumn));
            String ssColumn = 'SS_Column_' + lpadI + '__c';
            // api对应的名字
            String ssApiStr = String.valueOf(PlanMonthAndAmountName.get(ssColumn));
            //system.debug('apiStr' + apiStr);
 
            // HWAG-BUD4B7 2021.6.2 Start
            if (!String.isBlank(apiStr) && !String.isBlank(ssApiStr)) {
                list<string> ppdValue = ssApiStr.split(',');
                //system.debug('apiStr111' + apiStr + 'ssApiStr' + ssApiStr);
                //apiStr存计划月api
                //ppdValue存计划月数的名字
                PlanMonthAndAmountNameMap.put(apiStr, ppdValue);
            }
        }
 
        //获取自定义设置opd计划月api与opd计划数的api
        for (Integer i = 1; i <= FIELDMAX; i++) {
            String lpadI = ('00' + i).right(3);
            String fromColumn = 'From_Column_' + lpadI + '__c';
            //system.debug('fromColumn' + fromColumn);
            String apiStr = String.valueOf(planMonthAndAmount.get(fromColumn));
            //system.debug('apiStr' + apiStr);
            if (!String.isBlank(apiStr)) {
                String ssColumn = 'SS_Column_' + lpadI + '__c';
                String ssApiStr = String.valueOf(planMonthAndAmount.get(ssColumn));
                //system.debug('apiStr111' + apiStr + 'ssApiStr' + ssApiStr);
                planMonthAndAmountMap.put(apiStr, ssApiStr);
            }
        }
 
        // 遍历计划月api,用来获取opd计划月和opd计划数及计划月不为空的条件
        //拼接opd计划月api
        for (String apiKey : planMonthAndAmountMap.keySet()) {
            planMonth += ' , ' + apiKey;
            //拼接opd计划数api
            planNumber += ' , ' + planMonthAndAmountMap.get(apiKey);
            //不为空计划月不为空的拼接
            planMonthString += apiKey + '!=null or ';
        }
        // 计划月不为空的条件
        planMonthWhere = planMonthString.substring(0, planMonthString.length() - 3);
        system.debug('planMonth: ' + planMonth);
        system.debug('planNumber: ' + planNumber);
        system.debug('planMonthWhere: ' + planMonthWhere);
        system.debug('ThisPeriod:' + ThisPeriod);
        //检索今年全部的目标客户
        String soql = 'select id, name , Account__c , Account__r.name, Account__r.ownerid ,Account__r.owner.IsActive,Product_Leader__r.IsActive,Product_Leader__c ';
        soql += planMonth;
        soql += planNumber;
        // 本月暂时不对华东的任务进行派发
        soql += ' from Account_Number_of_target__c where ' +
            '  OCM_Period__c = : ThisPeriod and ';
        soql += '(';
        soql += planMonthWhere;
        soql += ')';
        // 检索 计划月不为空,OCSM期 = 规定年份 的目标客户
        // select id, name , Account__c , Account__r.name, Account__r.ownerid planMonth planNumber
        // from Account_Number_of_target__c where OCM_Period__c = : ThisPeriod and apiKey != null;
        if (string.isNotBlank(HPID)) {
            soql += ' and Account__r.parentID =: HPID ';
        }
        // 针对于单独某个医院(目标客户的母公司 = 医院)
        // select id, name , Account__c , Account__r.name, Account__r.ownerid planMonth planNumber
        // from Account_Number_of_target__c where OCM_Period__c = : ThisPeriod and apiKey != null
        // and Account__r.parentID =: HPID;
        if (string.isNotBlank(departmentID)) {
            soql += ' and Account__c =: departmentID ';
        }
        // 针对于单独某个战略科室(战略科室=战略科室)
        // select id, name , Account__c , Account__r.name, Account__r.ownerid planMonth planNumber
        // from Account_Number_of_target__c where OCM_Period__c = : ThisPeriod and apiKey != null
        // and Account__c =: departmentID;
 
        // 针对于单独某个销售本部 (销售本部 = 销售本部)        
        // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发  start
        if (string.isNotBlank(Salesdepartment_DeptClass)){
            soql += ' and Account__r.Salesdepartment_DeptClass__c =: Salesdepartment_DeptClass ';
        }
        if (String.isNotBlank(testId)){
            soql += ' and id =: testId';
        }
        // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发  end
 
        /* SFDC-BVN43P 额外判断,如果不是非要执行,那么如果战略科室所在
         * 医院是无效医院,那么就不针对这家战略科室下达任务 start
        */
        if (string.isBlank(HPID) && string.isBlank(departmentID)) {
            soql += ' and Account__r.Parent.Is_Active__c = \'有効\'  ';
        }
        // SFDC-BVN43P end
        //20210311 zh SWAG-BYX9W7 【委托】OPD任务 3月运行
        // 除15号(从自定义标签中获取)外 并且 不自动执行时 检索到的目标客户为空
        Integer runDay = Integer.valueOf(Label.OPD_RunTime);
        //20210203 zh SWAG-BXQDHZ start
        if (Date.today().day() != runDay && isAutoexec == true) {
            soql = 'select id from Account_Number_of_target__c where Name=\'\' and Name!=\'\' ';
        }
        //20210203 zh SWAG-BXQDHZ end
        system.debug('测试 :' + soql);
        //初始化,得到想要处理的数据(目标客户)
        return Database.getQueryLocator(soql);
    }
 
    global void execute(DataBase.BatchableContext BC, List<Account_Number_of_target__c> ANOTList) {
        //system.debug('进入execute');
        //任务List
        List<task__c> taskList =  new List<task__c>();
        List<String> anotAccountIdList = new List<String>();
        //科室与opd计划Map
        Map<String, List<OPDPlan__c>> anIdAndOpdlanMap =  new Map<String, List<OPDPlan__c>>();
        //opd计划月Api与opd计划产品名
        SS_Batch_Column_Mapping__c mpdMapping = SS_Batch_Column_Mapping__c.getValues('OPD_PlanMonth');
 
        //获取自定义设置opd计划月api与对应的产品名,将其存入Map中
        for (Integer i = 1; i <= FIELDMAX; i++) {
            String lpadI = ('00' + i).right(3);
            String fromColumn = 'From_Column_' + lpadI + '__c';
            //system.debug('fromColumn' + fromColumn);
            String apiStr = String.valueOf(mpdMapping.get(fromColumn));
            //system.debug('apiStr' + apiStr);
            if (String.isBlank(apiStr) == false && apiStr != null) {
                String ssColumn = 'SS_Column_' + lpadI + '__c';
                String ssApiStr = String.valueOf(mpdMapping.get(ssColumn));
                //system.debug('apiStr111' + apiStr + 'ssApiStr' + ssApiStr);
                opdPlanMonthMap.put(apiStr, ssApiStr);
            }
        }
 
        //2.战略客户IdList
        // 将战略客户转换成字符串(取其前15),存入List中
        for (Account_Number_of_target__c anot : ANOTList) {
            //system.debug(anot.name + ' :' + anot.id);
            String anotAccount = String.valueOf(anot.Account__c);
            anotAccountIdList.add(anotAccount.substring(0, 15));
        }
        //OPDPlan__c op = [select OCM_category_ID__c from OPDPlan__c];
        //system.debug('op+++++++++++++++++' + op);
        system.debug('anotAccountIdList:' + anotAccountIdList);
        // SWAG-BZL93B 改为运行财年的计划中、完毕未报告的OPD计划 start
        // 原代码
        /*
 
        Date firstDay = Date.today().toStartOfMonth();
        Date nextDate = firstDay.addMonths(1);
        Date nextTwoDate =  firstDay.addMonths(2);
        List<OPDPlan__c> OPDPlanAllList =
            [select id, PlanProdDetail__c, OCM_category_Name__c,
             OCM_category_ID__c, OPD_Customers_Target__c,
             OPDPlan_ImplementDate__c from OPDPlan__c
             where OCM_category_ID__c in:anotAccountIdList
             and OPDPlan_ImplementDate__c >= : nextDate
             and OPDPlan_ImplementDate__c < : nextTwoDate
             and (Status__c != '取消' or Status__c != '完毕' or Status__c != '草案中')];
        */
        // 定义Fy开始日和结束日(作为检索opd计划的条件)
        Integer year = Date.today().year();
        Integer month = Date.today().month() ;
        if (month < 3) {
            year--;
        }
        Date FYfirstDay = date.newInstance(year, 4, 1);
        Date FYLastDay = FYfirstDay.addMonths(12);
        // OPD计划实施日期:OPDPlan_ImplementDate__c
        // 战略科室ID:OCM_category_ID__c
        // 状态为计划中或完毕未报告 并且 OPD计划实施日期大于等于Fy开始日 并且 小于 结束日 并且 每个战略科室对应的opd计划(opd计划所关联的战略科室被包含在所有战略科室中)
        List<OPDPlan__c> OPDPlanAllList =
            [select id, PlanProdDetail__c, OCM_category_Name__c,
             OCM_category_ID__c, OPD_Customers_Target__c,
             OPDPlan_ImplementDate__c from OPDPlan__c
             where OCM_category_ID__c in:anotAccountIdList
             and OPDPlan_ImplementDate__c >= : FYfirstDay
             and OPDPlan_ImplementDate__c < : FYLastDay
             and (Status__c = '计划中'  or Status__c = '完毕未报告')];
        // SWAG-BZL93B 改为运行财年的计划中、完毕未报告的OPD计划 end
        //3.战略客户下全部的Opd计划
        // 1、创建一个存opd计划Id的list<String>
        // 2、遍历存战略科室Id的list(String)
        // 3、遍历检索出来的opd计划
        //    4、将 战略科室(key)检索出来的opd计划 (value)
        //    5、将 opd计划存入list(String)
        system.debug('OPDPlanAllList:' + OPDPlanAllList);
        for (String opdpId : anotAccountIdList) {
            list<OPDPlan__c> tempOPDList = new List<OPDPlan__c>();
            for (OPDPlan__c opdp : OPDPlanAllList) {
                //system.debug('opdpId' + opdpId);
                //system.debug('opdp.OCM_category_ID__c' + opdp.OCM_category_ID__c);
                if (opdpId == opdp.OCM_category_ID__c) {
                    // 战略科室与opd计划
                    tempOPDList.add(opdp);
 
                }
                anIdAndOpdlanMap.put(opdpId, tempOPDList);
            }
        }
        //system.debug('anIdAndOpdlanMap:' + anIdAndOpdlanMap);
        //List<Plan_Rental_Equipment__c> preList = [select name from Plan_Rental_Equipment__c where OPD_Plan__c in: opIdList ];
 
        //6 目标客户
        // 遍历目标客户
            //遍历opd计划月Api,opd计划月Api(key) 产品名(value)
                //获取客户opd月值,如果客户opd计划月值为空的话,跳出循环
                //opd计划月的值(将其转换成String类型)
                // 如果 opd计划月的值 不等于空 将 opd计划月的值赋值给(Integer类型的变量)
                // 如果 opd计划月的值为空 或 opd计划月大于下个月(当前月的值+1) 则跳出循环 
                // 如果以上条件不满足
        for (Account_Number_of_target__c anot : ANOTList) {
 
            
            //产品明细
            String producDetail = '';
            //opd计划
            String ocn = '';
            String al = '';
            //遍历opd计划月Api,opd计划月Api(key) 产品名(value)
            for (String planMonthAndAmountMapKey : opdPlanMonthMap.keySet()) {
                //system.debug( anot.name + '的计划月:' + planMonthAndAmountMapKey);
                //然后再在这里写对应的opd数是否为空
                Boolean anotFlage = true;
                boolean FlagBl = true;
                //获取客户opd月值,如果客户opd计划月值为空的话,跳出循环
                if (anot.get(planMonthAndAmountMapKey) == null) {
                    continue;
                }
                //opd计划月的值(将其转换成String类型)
                String opdNu = String.valueOf(anot.get(planMonthAndAmountMapKey));
                Integer MonthNumber;
                // 如果 opd计划月的值 不等于空 将 opd计划月的值赋值给(Integer类型的变量)
                if (!String.isBlank(opdNu)) {
                    // 月份
                    MonthNumber = Integer.valueOf(opdNu.substring(0, opdNu.length() - 1));
                }
                // opd计划月
                if (MonthNumber < 4) {
                    MonthNumber += 12;
                }
                // 下个月
                Integer dm = datetime.now().month() + 1;
                if (dm < 4) {
                    dm += 12;
                }
                // 如果 opd计划月的值为空 或 opd计划月大于下个月(当前月的值+1) 则跳出循环 
                if (String.isBlank(opdNu) || MonthNumber > dm) {
                    continue;
                } else {
                    //opd计划数api数组
                    String[] opdNumberAmountValue;
                    //符合条件的opd计划月下的opd计划数
                    String planMonthAndAmountMapValue = '';
                    //获取opd计划数api,将其以‘,’为分隔符存入list(String)中
                    planMonthAndAmountMapValue = planMonthAndAmountMap.get(planMonthAndAmountMapKey);
                    opdNumberAmountValue = planMonthAndAmountMapValue.split(',');
                    // 遍历 opd计划数api {
                    //     1、判断对应的opd数是否为空 如果 
                    //         1、不为空 
                    //             1、boolean变量为false
                    //         2、为空
                    //             1、获取 opd计划 (如果没有,则新创一个opd)
                    //             2、循环比对已存在的计划出借备品信息和理论上存在的计划出借备品信息
                    //                 1、如果 有计划出借备品信息 则 将计划出借备品信息以‘;’为分隔符存入list(String)中
                    //                     1、遍历计划出借备品信息
                    //                         1、得到每一个备品
                    //                         2、得到每一个计划数名字(通过map获取全部的计划数名字,再将其遍历获取单个计划书名字,之后将其备品与计划数名字进行对比,如果相等(表示有对应的opd计划)则跳出循环)
                    // }
                    for (String nav : opdNumberAmountValue) {
                        FlagBl = true;
                        nav = nav == null ? nav : nav.trim();
                        //system.debug('nav:'+nav);
                        //system.debug('sss:'+anot.get(nav));
                        // anot.get(nav):客户opd计划数的值
                        if (!String.isBlank(String.valueOf(anot.get(nav))) && Integer.valueOf(anot.get(nav)) != 0 ) {
                            anotFlage = false;
                            //system.debug('sss:'+anot.get(nav));
                        } else {
                            //for(String ocnId : anIdAndOpdlanMap.keySet()){
                            //opd计划
                            List<OPDPlan__c> OPDPlanList = anIdAndOpdlanMap.get(
                                                               string.valueOf(anot.Account__c).substring(0, 15));
                            //system.debug('anot.Account__c:' + anot.Account__c);
                            //system.debug('OPDPlanList' + OPDPlanList.get(0));
                            if (OPDPlanList == null ) {
                                OPDPlanList = new List<OPDPlan__c>();
                            }
                            //system.debug('OPDPlanList' + OPDPlanList.get(0));
                            //循环比对已存在的计划出借备品信息和理论上存在的计划出借备品信息
                            for (OPDPlan__c opdp : OPDPlanList) {
                                //system.debug('planMonthAndAmountMapKey:' + planMonthAndAmountMapKey);
                                //system.debug('opdp:' + opdp);
 
                                //opd计划.计划出借备品信息
                                String ppd = opdp.PlanProdDetail__c;
                                String[] ppdValue;
                                // 如果 有计划出借备品信息 则 将计划出借备品信息以‘;’为分隔符存入list(String)中
                                //     1、遍历计划出借备品信息
                                //         1、得到每一个备品
                                //         2、得到每一个计划数名字(通过map获取全部的计划数名字,再将其遍历获取单个计划书名字,之后将其备品与计划数名字进行对比,如果相等(表示有对应的opd计划)则跳出循环)
                                if (!String.isBlank(ppd) ) {
                                    // 备品
                                    ppdValue = ppd.split(';');
                                    //system.debug('计划出借备品信息' + ppdValue);
                                    for (String ppdVa : ppdValue) {
                                        //system.debug('nav:'+nav);
                                        // 备品
                                        ppdVa = ppdVa.trim().substring(0, ppdVa.trim().length() - 2);
                                        //system.debug('ppdVa1:' + ppdVa);
                                        // opd计划数的名字,planMonthAndAmountMapKey(opd计划月)
                                        list<string> stringList = PlanMonthAndAmountNameMap.get(planMonthAndAmountMapKey);
                                        //system.debug('stringList:' + stringList);
                                        for (string str : stringList) {
                                            //system.debug('str:' + str);
                                            // 备品 = 计划数的名字
                                            if (str.equals(ppdVa)) {
                                                //system.debug('anotFlage:' + anotFlage);
                                                FlagBl = false;
                                                anotFlage = false;
                                            }
                                        }
 
                                    }
                                }
 
                                //ocn = opdp.OCM_category_Name__c;
                                //al = opdp.Account_Laboratory__c;
                                //}
                            }
                            if (FlagBl = false) {
                                continue;
                            }
 
                        }
                    }
 
                    if (anotFlage == false) {
                        continue;
                    }
                    // 将产品名: opd计划月的值 赋值给 产品明细变量上
                    producDetail +=
                        opdPlanMonthMap.get(planMonthAndAmountMapKey) + ':' + opdNu + ';';
                }
            }
            system.debug( anot.name + '的产品明细:' + producDetail);
            // 如果产品明细不为空 则任务的
            //     被分配者-战略科室的所有人
            //     所有人-所有人
            //     产品明细-产品明细
            //     记录类型-OPD
            //     任务区分-‘被动任务’
            //     任务名称-‘用户拜访:’ + 战略科室名
            //     客户-战略科室
            //     任务状态2-‘01 分配’
            //     将任务添加到list(task__c)
 
            if (!string.isBlank(producDetail) && ((anot.Product_Leader__c !=null && anot.Product_Leader__r.IsActive) || (anot.Account__c !=null && anot.Account__r.owner.IsActive))) {//2021-08-30 yjk 增加判断任务对应的用户必须为IsActive
                ocn = anot.Account__r.name;
                al = anot.Account__c;
                task__c newTask = new task__c();
                // 被分配者
                // 2021-06-16  mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 start
                if(anot.Product_Leader__c != null){
                    newTask.assignee__c = anot.Product_Leader__c;
 
                    newTask.ownerid = anot.Product_Leader__c;
                }else{                    
                    newTask.assignee__c = anot.Account__r.ownerid;
 
                    newTask.ownerid = anot.Account__r.ownerid;
                }
                // 2021-06-16 mzy SWAG-C3VA6S 【委托】华东 OPD任务 更改为产品担当派发 end
 
                // 产品明细
                newTask.ProductDetails__c = producDetail;
                newTask.RecordTypeId =
                    Schema.SObjectType.task__c.getRecordTypeInfosByDeveloperName().get('OPD').getRecordTypeId();
                // 任务区分
                newTask.taskDifferent__c = '被动任务';
                // 任务名称
                newTask.Name = '用户拜访:' + ocn;
                // 客户
                newTask.account__c = al;
                //newTask.OpportunityId__c = opdp.Id;
                // 任务状态2
                newTask.taskStatus__c = '01 分配';
                taskList.add(newTask);
 
            }
        }
 
        // 如果list中有任务 则
        //     将该任务添加到数据库中
        //     计数,添加了几条
        //     循环,任务的条数
        //         如果没添加成功,将‘被动任务’:该任务 存到日志中,将第几条的报错信息存到错误日志中,计数总共没添加成功几条
 
        // 2021-12-13 yjk 取消OPD任务的派发
        // if (taskList.size() > 0) {
        //     Database.SaveResult[] saveResults = Database.insert(taskList, false);
        //     totalCount = + saveResults.size();
        //     for (Integer i = 0; i < saveResults.size(); i++) {
        //         if (!saveResults.get(i).isSuccess()) {
        //             logstr += '被动任务:' + taskList.get(i).Account__c + ' ,';
        //             errorstr += saveResults.get(i).getErrors() + '\n';
        //             failedCount ++;
        //         }
        //     }
        // }
    }
    // 创建日志(用来存添加失败的任务,以及每一条添加失败的信息)
 
    global void finish(Database.BatchableContext BC) {
        BatchIF_Log__c batchIfLog = new BatchIF_Log__c();
        batchIfLog.Type__c = 'CreatePassiveTaskBatch';
        if (logstr.length() > 60000) {
            logstr = logstr.substring(0, 60000);
        }
        batchIfLog.Log__c = logstr;
        logstr += '\nCreatePassiveTaskBatchEnd';
        if (errorstr.length() > 60000) {
            batchIfLog.ErrorLog__c = errorstr.substring(0, 60000);
        } else {
            batchIfLog.ErrorLog__c = errorstr.substring(0, errorstr.length());
            integer i = 0;
            i++;
            i++;
            I++;
            i++;
            i++;
            i++;
        }
        insert batchIfLog;
        emailMessages.add('失败日志ID为:' + batchIfLog.Id);
        sendFieldEmail();
 
        //2021-07-12  mzy update start  SLA定期任务开发
        if(!System.Test.isRunningTest() && isAutoexec == true){
            Database.executebatch(new CreateNewMaintenanceTaskBatch(true));
        }
        //2021-07-12  mzy  update end  SLA定期任务开发
    }
    // 发送提醒邮件
        // 1、如果战略科室为空 并且 医院为空 则
        //     定义两个数组(一个为空,一个存接收邮件者,一个存抄送人)及一个标题 
        //     如果邮件信息有值 并且 失败总数大于0 则
        //         发送失败邮件的内容为:接收人,抄送人,标题,将全部的错误日志显示出来,总数,成功数,失败数
        //         如果!Test.isRunningTest,则发送
        
    private void sendFieldEmail() {
        // HWAG-BUD4B7 2021.6.3 Start
        if (isAutoexec) {
        // HWAG-BUD4B7 2021.6.3 End
            PretechBatchEmailUtil be = new PretechBatchEmailUtil();
            String[] toList = new String[] {UserInfo.getUserEmail()};
            String title = '创建被动任务失败';
            String[] ccList = new String[] {};
            if (System.Test.isRunningTest()) {
                be.successMail('', 1);
            }
            if (emailMessages.size() > 0 && failedCount > 0) {
                be.failedMail(toList, ccList, title,
                              String.join(this.emailMessages, '\n'),
                              totalCount, totalCount - failedCount, failedCount, '', true);
                if (!System.Test.isRunningTest())
                    be.send();
            }
        }
    }
 
}