高章伟
2022-04-11 b63ff7db006c7fe022809e3272bbe11361231c02
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
/*
 * 这个触发器需要更新完历史数据后才能部署,
 * 一、删除时调用方法,传入OLD失单型号ID:
 *         1、找到是这个失单型号的所有保有设备,删除掉;
 *         2、这个需要做成共通方法,传进来失单报告,然后以便三、1使用;
 * 二、插入时调用方法,传入NEW失单型号:
 * 这个也需要写成共通方法,以供三、2使用;
 *         1、前提:
 *            1)失单型号的报告是失单报告或者部分失单报告;
 *            2)失单型号的询价所在医院的记录类型是HP;
 *         2、找到插入所有失单型号中有失单产品型号的数据;
 *         3、根据数量生成保有设备,把这个保有设备的型号设置为这个保有设备;
 * 三、更新:
 *         1、删除:
 *             1)从有产品型号更新为无产品型号;
 *          2)调用一的方法,删除掉保有设备;
 *         2、插入:
 *             1)从无产品型号更新为有产品型号;
 *             2)调用二的方法插入数据;
 *         3、更新:
 *             1)如果产品或者数量发生了变化,而且符合失单型号对报告的需求;
 *             2)调用四的方法更新保有设备;
 * 四、更新调用,传入New失单型号 list以及map;
 *        1、找到这个失单型号ID的所有失单保有设备;
 *         2、循环每个失单保有设备的失单数量:
 *             1)先用在失单数量下的保有设备,对比一下产品,有变化加入更新数据行列;
 *             2)用完这个失单下的所有保有设备,插入失单设备;
 *         3、循环完如果这个失单报告还有保有设备,记录下来以供删除;
 *        4、插入失单设备;
 *        5、更新设备;
 *        6、删除保有设备;
 * */
public without sharing class PCLLostProduct2AssetHandler extends Oly_TriggerHandler {
    private Map<Id, PCLLostProduct__c> newMap;
    private Map<Id, PCLLostProduct__c> oldMap;
    private List<PCLLostProduct__c> newList;
    private List<PCLLostProduct__c> oldList;
    public PCLLostProduct2AssetHandler() {
        this.newMap = (Map<Id, PCLLostProduct__c>) Trigger.newMap;
        this.oldMap = (Map<Id, PCLLostProduct__c>) Trigger.oldMap;
        this.newList = (List<PCLLostProduct__c>) Trigger.new;
        this.oldList = (List<PCLLostProduct__c>) Trigger.old;
    }
    protected override void afterUpdate() {
        updateProduct2Asset(newList,oldMap);
    }
 
    protected override void afterInsert() {
        insertLostAsset(newList);
    }
    protected override void beforedelete() {
        deleteLostAsset(oldMap.keySet());
    }
 
    private void deleteLostAsset( set<id> oldIDList){
        list<Asset> delAstList = new list<Asset>();
        if(oldIDList.size()> 0) {
            delAstList =
            [select id
             from asset
             where LostProduct__c in: oldIDList];
        }
        if(delAstList.size() > 0) {
            delete delAstList;
        }
    }
 
    private void insertLostAsset(List<PCLLostProduct__c> newList){
        list<asset> InsertAssetlist = new list<asset>();
        for (PCLLostProduct__c LostProduct : newList) {
            // 部分失单或失单报告型号而且询价上的医院真是医院
            if ((LostProduct.lcrRecordType_DevName__c == 'PCL_Lost_report' ||
                 LostProduct.lcrRecordType_DevName__c == 'PCL_PartLost_report'
                 ) && LostProduct.HP_RecordType_DevName__c == 'HP'
                && string.isNotBlank(LostProduct.LostProduct__c))
            {
                for(integer i = 0; i <integer.valueof(lostProduct.Quantity__c); i++) {
                    InsertAssetlist.add(buildAsset (lostProduct));
                }
            }
        }
 
        if(InsertAssetlist.size() > 0) {
            insert InsertAssetlist;
        }
    }
    private void updateProduct2Asset(List<PCLLostProduct__c> newList,
                                     Map<Id, PCLLostProduct__c> oldMap){
        // 要被删除数据的ID的set
        set<id> oldDelIDList = new set<id>();
        // 要被插入的保有设备的失单型号的new的list
        list<PCLLostProduct__c> newInsertList =
            new list<PCLLostProduct__c>();
        //需要走更新流程的失单型号
        List<PCLLostProduct__c> newUpdateList =
            new List<PCLLostProduct__c>();
        //需要走更新流程的失单型号IDSet
        set<ID> newUpIDSet = new set<ID>();
 
        // for循环,判断哪些需要增加、删除或更新
        for( PCLLostProduct__c NewLsP : newList) {
            PCLLostProduct__c oldLsP = oldMap.get(NewLsP.id);
            //1、产品型号有值变为产品型号为空,需要删除;
            if(string.isNotBlank(oldLsP.LostProduct__c) &&
               string.isBlank(NewLsP.LostProduct__c)) {
                oldDelIDList.add(NewLsP.id);
            }
            //2、产品型号为空变为产品型号有值,需要插入失单保有设备;
            if(string.isBlank(oldLsP.LostProduct__c) &&
               string.isNotBlank(NewLsP.LostProduct__c)) {
                newInsertList.add(NewLsP);
            }
            // 3、如果
            //   1)新失单型号所在的报告是失单报告或者部分失单报告;
            //   2)所在询价的医院是医院
            //   3)失单型号产品不为空;
            //   4)产品更改或者数量更改;
            //  那么是需要更新的数据
            if ((NewLsP.lcrRecordType_DevName__c == 'PCL_Lost_report'
                 || NewLsP.lcrRecordType_DevName__c == 'PCL_PartLost_report'
                 ) && NewLsP.HP_RecordType_DevName__c == 'HP'
                && string.isNotBlank(NewLsP.LostProduct__c)
                && ( NewLsP.LostProduct__c != oldLsP.LostProduct__c
                     || NewLsP.Quantity__c != oldLsP.Quantity__c
                     )
                )
            {
                newUpdateList.add(NewLsP);
                newUpIDSet.add(NewLsP.Id);
            }
 
        }
 
        // 删除数据
        if(oldDelIDList.size() > 0) {
            deleteLostAsset(oldDelIDList);
        }
        // 插入数据
        if(newInsertList.size()>0) {
            insertLostAsset(newInsertList);
        }
        // 更新数据
        if(newUpdateList.size()>0) {
            updateLsAHandler(newUpdateList,newUpIDSet);
        }
 
    }
 
    private void updateLsAHandler(List<PCLLostProduct__c> newList,set<Id> newIDSet) {
 
        //需要插入和更新的保有设备数据
        list<asset> upsertAstList = new List<asset>();
 
        //需要删除的保有设备数据
        list<asset> delAstList = new List<asset>();
 
        // 构建map,以便判断是否需要删除或者更新已有保有设备;
        map<id, list<asset> > LsPID2Asset = new map<id, list<asset> >();
 
        // 检索这个失单型号下面所有保有项目
        list<asset> oldAssetList = [
            select id, LostProduct__c, Product2Id,
            Status, Asset_Owner__c, IsCompetitorProduct
            from asset
            where LostProduct__c in : newIDSet
        ];
 
        for(asset tempAst: oldAssetList) {
            list<asset> tempAstList = new List<asset>();
            if(LsPID2Asset.containsKey(tempAst.LostProduct__c)) {
                tempAstList = LsPID2Asset.get(tempAst.LostProduct__c);
            }
            tempAstList.add(tempAst);
            LsPID2Asset.put(tempAst.LostProduct__c, tempAstList);
        }
        // 循环现有失单型号,
        for(PCLLostProduct__c tempLsP : newList) {
            // 获取当前失单型号的所有失单保有设备
            list<asset> tempAstList = LsPID2Asset.get( tempLsP.id );
            for(integer i = 0; i < integer.valueOf(tempLsP.Quantity__c); i++) {
                asset tempAst = buildAsset(tempLsP);
                // 如果当前失单型号还有值,那么获取一个更新,否则就插入
                if(tempAstList !=null && tempAstList.size() > 0) {
                    asset oldAst = tempAstList.remove(0);
                    // 如果发生变化以后,才需要更新
                    if(tempAst.Product2Id != oldAst.Product2Id ||
                       tempAst.Status != oldAst.Status ||
                       tempAst.Asset_Owner__c != oldAst.Asset_Owner__c ||
                       tempAst.IsCompetitorProduct != oldAst.IsCompetitorProduct
                       ) {
                        tempAst.id = oldAst.id;
                        upsertAstList.add(tempAst);
                    }
                }
                else{
                    upsertAstList.add(tempAst);
                }
            }
            // 如果还有多出来的,那么这些就是需要删除的失单保有设备
            if(tempAstList !=null && tempAstList.size()> 0) {
                delAstList.addAll(tempAstList);
            }
        }
        // 插入或者更新失单保有设备
        if(upsertAstList.size() > 0) {
            upsert upsertAstList;
        }
        // 删除多的失单保有设备
        if(delAstList.size() > 0) {
            delete delAstList;
        }
    }
 
    private asset buildAsset(PCLLostProduct__c LostProduct){
        Asset Ast = new Asset(
            Name = '*',
            // CHAN-CCR6MW gzw 【委托】【保有设备】保有设备发货日逻辑 start
            Posting_Date__c = Date.today(),
            // CHAN-CCR6MW gzw 【委托】【保有设备】保有设备发货日逻辑 end
            Product2Id = LostProduct.LostProduct__c,
            Opportunity__c = LostProduct.Opportunity__c,
            InstallDate = LostProduct.Submit_Day__c,
            Hospital__c = LostProduct.LostHP__c,
            Department_Class__c = LostProduct.LostDepartment_Class__c,
            AccountId = LostProduct.LostAccount__c,
            Status = '使用中',
            Asset_Owner__c = '病院資産',
            IsCompetitorProduct = True,
            LostProduct__c = LostProduct.id
            );
        return ast;
    }
}