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
global class CBF2batch implements Database.Batchable<SObject> , Database.Stateful {
    public String query;
    public String cbfId;
    public String xhId;
    private BatchIF_Log__c iflog;
 
    global CBF2batch() {
        this.query = query;
    }
 
    global CBF2batch(String cbfId,String xhId) {
        this.query = query;
        this.cbfId = cbfId;
        this.xhId = xhId;
    }
 
    global Database.QueryLocator start(Database.BatchableContext bc) {
        //添加邮件提醒 start
        system.debug('执行start');
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'CBF2batch';
        iflog.Log__c  = 'CBF2batch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
        //添加邮件提醒 end
      query = 'select id,name,cbf_execute__c from Account where Is_Active_Formula__c = \'有效\' and Acc_Record_Type__c = \'病院\'';
      if (cbfId != null && cbfId != '') {
          query += ' and id = :cbfId';
      }else {
          query += ' and id in(select Hospital__c from Repair__c  WHERE Cumulative_Uses__c != null AND Cumulative_Times__c != null)';
      }
      System.debug('执行结果:'+Database.getQueryLocator(query));
      return Database.getQueryLocator(query);
  }
 
  global void execute(Database.BatchableContext BC, list<Account> AccountList) {
      List<String> accountIds = new List<String>();
      for (Account acc : AccountList) {
          accountIds.add(acc.id);
      }
      iflog.Log3__c = JSON.serialize(accountIds);
      update iflog;
      List<Repair__c> repairList = [SELECT Id,
                                           Name,
                                          Cumulative_Uses__c, 
                                          Cumulative_Times__c, 
                                          Repair_Ordered_Date__c, 
                                          Cycle_between_failure__c, 
                                          Product_Unique_Value__c,
                                          OwnershipMachine_No__c,
                                          Repair_Inspection_Date__c,
                                          Difference_in_repair_intervals__c,
                                          Hospital__c
                                           FROM Repair__c 
                                           WHERE 
                                          Repair_Inspection_Date__c != null
                                           AND Hospital__c in: accountIds and OwnershipMachine_No__c = :xhId ORDER BY Repair_Ordered_Date__c Asc];
      try {
                 // 定义一个列表来存储查询结果
                  List<Repair__c> resultList = new List<Repair__c>();
    
                  // 通过map 对相同Product_Unique_Value__c 组合的数据进行分组
                  Map<String, List<Repair__c>> repairMap = new Map<String, List<Repair__c>>();
                  for(Repair__c r : repairList) {
                      if(repairMap.containsKey(r.Product_Unique_Value__c)) {
                          repairMap.get(r.Product_Unique_Value__c).add(r);
                      } else {
                          List<Repair__c> tempList = new List<Repair__c>();
                          tempList.add(r);
                          repairMap.put(r.Product_Unique_Value__c, tempList);
                      }
                  }
                  for(String key : repairMap.keySet()) {
                      Date prevDate = null; // 记录前一个日期
                      Id lastRepairId = null; // 记录上一个修理的Id
                      List<Repair__c> rList = repairMap.get(key);
                      for (Integer i = 0; i < rList.size(); i++) {
                          Repair__c repair = rList[i];
                          Date currentDate = repair.Repair_Inspection_Date__c;
                          if (i == 0) { // 如果是第一条记录
                              repair.Difference_in_repair_intervals__c = 0;
                          } else { // 如果不是第一条记录
                              if (rList[i-1].Cycle_between_failure__c != null) {
                                  Integer days = prevDate.daysBetween(currentDate);
                                  repair.Difference_in_repair_intervals__c = Math.abs(days);
                              }else {
                                  Integer days = prevDate.daysBetween(currentDate);
                                  repair.Difference_in_repair_intervals__c = Math.abs(days) + rList[i-1].Difference_in_repair_intervals__c;
                              }
                          }   
                          repair.LastRepair__c = lastRepairId; // 设置 LastRepair__c 字段为上一个修理的Id
                          
                          prevDate = currentDate; // 更新前一个日期为当前日期
                          lastRepairId = repair.Id; // 更新上一个修理的Id为当前修理的Id
                      }
                      resultList.addAll(rList);
                  }
                  
                  System.debug('更新数据打印:'+resultList);
                  Database.SaveResult[] saveTenderResults = Database.update(resultList, false);
 
                  for (Integer save = 0; save < saveTenderResults.size(); save++) {
                     Database.SaveResult sr = saveTenderResults[save];
                     if (!sr.isSuccess()) {
                        Database.Error emsg = sr.getErrors()[0];
                         iflog.ErrorLog__c += 'ERROR  ' + saveTenderResults[save].id + 'SS_oli:' + emsg + '\n';
                     }else {
                        iflog.Log2__c += saveTenderResults[save].id +',';
                     }
                  }
 
      } catch (Exception e) {
            // 记录错误消息
          String errorMessage = e.getMessage()+'===========>报错医院'+accountIds;
            iflog.ErrorLog__c += errorMessage;
            update iflog;
            return;
      }
  }
 
  global void finish(Database.BatchableContext BC) {
     iflog.Log__c += '\nCBFbatch end';
     update iflog;
  }
 
  public static Integer calculateDaysBetween(Date startDate, Date endDate) {
      // 使用Date类的daysBetween方法计算天数差异
      Integer days = startDate.daysBetween(endDate);
 
      return Math.abs(days); // 如果你希望天数始终为正数,可以使用Math.abs方法
  }
     
}