· 6 years ago · Nov 14, 2019, 10:16 PM
1/*
2Description : Manager class for Sold_Service_Modification__c object
3Created by : Tomasz Bogdański (tomasz.bogdanski@enxoo.com)
4Date created : 2016-03-14
5************************************************************************/
6public without sharing class CPQ_SSM01_Manager {
7 public static Schema.DescribeSObjectResult ssmobj = Schema.getGlobalDescribe().get('Sold_Service_Modification__c').getDescribe();
8 public static Map<String, Schema.SObjectField> ssmschemaFieldMap = ssmobj.fields.getMap();
9
10 public static Schema.DescribeSObjectResult obj = Schema.getGlobalDescribe().get('Sold_Service__c').getDescribe();
11 public static Map<String, Schema.SObjectField> schemaFieldMap = obj.fields.getMap();
12
13 public static Map<Id, String> ssOliMap = new Map<Id, String>();
14 public static Map<Id, Sold_Service_Modification__c> alreadyExistingSSM = new Map<Id, Sold_Service_Modification__c>();
15 public static Set<String> ssmFields = CPQ_Utils01_SObjectHelperCls.getFieldDescriptions('Sold_Service_Modification__c').keyset();
16 //Map used to save SSM related to cease & reprovide action
17 public static Map<String, String> ceaseReprovideMap = new Map<String, String>();
18 public static Map<Id, Opportunity> oppMap;
19
20 public CPQ_SSM01_Manager(){}
21
22 public static Map<Id, Sold_Service_Modification__c> createSoldServiceModifications(List<CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper> soldServiceProductList, List<CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper> soldServiceComponentList, List<Sold_Service_Modification__c> ssmFromIFC) {
23 CPQ_Utils04_RequestStateCls.setOn('STAGE_AUTOMATION');
24 Map<Id, Sold_Service_Modification__c> parentSSMMap = new Map<Id, Sold_Service_Modification__c>();
25 Map<Id, Sold_Service_Modification__c> soldServiceModMap = new Map<Id, Sold_Service_Modification__c>();
26 Set<Id> oppIds = new Set<Id>();
27 Set<Id> quoteItemIds = new Set<Id>();
28 List<Id> ssProcessedIds = new List<Id>();
29 Map<Id, String> ssChildsProcessedIds = new Map<Id, String>(); //component ss id, parent ss id
30
31 List<Id> ssPrevInstanceIds = new List<Id>();
32 List<CPQ_QuoteItem__c> quoteItems = new List<CPQ_QuoteItem__c>();
33 Map<Id,List<X3rd_Party_Services__c>> ssToTpsMap = new Map<Id,List<X3rd_Party_Services__c>>();
34 Map<Id,List<X3rd_Party_Services__c>> ssToTpsChildMap = new Map<Id,List<X3rd_Party_Services__c>>();
35
36 if(soldServiceProductList != null) {
37 for(CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper ss : soldServiceProductList) {
38 if(!oppIds.contains(ss.soldService.Opp_Link__c)) {
39 oppIds.add(ss.soldService.Opp_Link__c);
40 }
41 ssProcessedIds.add(ss.soldService.Id);
42 if(ss.oldSoldService != null && ss.parallelBuild) {
43 ssPrevInstanceIds.add(ss.oldSoldService.Id);
44 }
45 if(ss.quoteItem != null) {
46 quoteItems.add(ss.quoteItem);
47 }
48 }
49 }
50
51
52 if(soldServiceComponentList != null) {
53 for(CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper ss : soldServiceComponentList) {
54 if(!oppIds.contains(ss.soldService.Opp_Link__c)) {
55 oppIds.add(ss.soldService.Opp_Link__c);
56 }
57 ssProcessedIds.add(ss.soldService.Id);
58 ssChildsProcessedIds.put(ss.soldService.CRM_Parent_Sold_Service__c, ss.soldService.CRM_Parent_Sold_Service__c);
59 if(ss.oldSoldService != null && ss.parallelBuild) {
60 ssPrevInstanceIds.add(ss.oldSoldService.Id);
61 }
62 if(ss.quoteItem != null) {
63 quoteItems.add(ss.quoteItem);
64 }
65 }
66 }
67
68 if(UserInfo.getLastName() == 'Rudnicki') {
69 ERR_UTL01_ErrorManagerCls.logError(JSON.serialize(soldServiceComponentList), 'Integration', null, 'C', 'CPQ_SSM01_Manager', 'createSoldServiceModifications', '2.6.1');
70 }
71 oppMap = new Map<Id, Opportunity>([SELECT Id, PopUp__c, TSIC_Contracting_Company__c, TSIC_Contracting_Company__r.TSIC_Contracting_Company_Name__c, TSIC_Contracting_Company__r.FDC_Code__c FROM Opportunity WHERE Id IN : oppIds]);
72
73 String oldServicesQuery = 'select Renewed_To__r.RFS_Date__c, ' + CPQ_Utils01_SObjectHelperCls.getFieldListForSOQL('Sold_Service__c', null, null) + ' from Sold_Service__c where Id in:ssProcessedIds OR Id in :ssPrevInstanceIds';
74 Map<Id, Sold_Service__c> idToServiceMap = new Map<Id, Sold_Service__c>((List<Sold_Service__c>)Database.query(oldServicesQuery));
75
76 //this query fetches only newly created tpses (by any action) to be reattached from sold service to its modification
77 for(X3rd_Party_Services__c tps : [SELECT Id, Sold_Service__c, Sold_Service__r.CRM_Parent_Sold_Service__c, Sold_Service_Modification__c, MRE__c, OTE_COGS__c, OTE_Capex__c, TPI_Final_MRE__c, TPI_Final_OTE_COGS__c, Status__c, CurrencyIsoCode FROM X3rd_Party_Services__c WHERE (Sold_Service__c IN :ssProcessedIds OR Sold_Service__c IN :ssPrevInstanceIds) AND Sold_Service_Modification__c = null]) {
78 List<X3rd_Party_Services__c> tempList = ssToTpsMap.get(tps.Sold_Service__c);
79 if(tempList == null) {
80 tempList = new List<X3rd_Party_Services__c>();
81 }
82 tempList.add(tps);
83
84 // child tpses add
85 if (tps.Sold_Service__r.CRM_Parent_Sold_Service__c != null) {
86 List<X3rd_Party_Services__c> tempChildList = ssToTpsChildMap.get(tps.Sold_Service__r.CRM_Parent_Sold_Service__c);
87 if(tempChildList == null) {
88 tempChildList = new List<X3rd_Party_Services__c>();
89 }
90 tempChildList.add(tps);
91 ssToTpsChildMap.put(tps.Sold_Service__r.CRM_Parent_Sold_Service__c, tempChildList);
92 }
93
94 ssToTpsMap.put(tps.Sold_Service__c, tempList);
95 }
96
97 Map<Id, Sold_Service__c> currentlyUsedSS = new Map<Id, Sold_Service__c>();
98
99
100 Map<Id, CPQ_QuoteItem__c> quoteItemAttrMap = new Map<Id, CPQ_QuoteItem__c>();
101 if(!quoteItems.isEmpty()) {
102 for(CPQ_QuoteItem__c items : quoteItems) {
103 quoteItemAttrMap.put(items.Quote__r.Opportunity__c, items);
104 }
105 }
106
107 CPQ_Utils04_RequestStateCls.setOn('SOLD_SERVICE_SYNCED');
108 CPQ_Utils04_RequestStateCls.setOn('RUN_SS_ROLLUPS_ONES');
109
110 Boolean fromTrigger = CPQ_Utils04_RequestStateCls.isOn('MODIFICATION') && CPQ_Utils04_RequestStateCls.isOn('SOLD_SERVICE_SYNCED');
111 CPQ_Utils04_RequestStateCls.setOn('SOLD_SERVICE_SYNCED');
112 CPQ_Utils04_RequestStateCls.setOn('MODIFICATION');
113
114 if(soldServiceProductList != null) {
115 parentSSMMap = mapSoldServiceModificationFields(soldServiceProductList, idToServiceMap, quoteItemAttrMap, ssToTpsMap, null, ssToTpsChildMap, ssChildsProcessedIds);
116 if(System.isBatch() && CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm != null){
117 CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm.putAll(parentSSMMap);
118 }
119 }
120 if(soldServiceComponentList != null) {
121 soldServiceModMap = mapSoldServiceModificationFields(soldServiceComponentList, idToServiceMap, quoteItemAttrMap, ssToTpsMap, parentSSMMap, null, null);
122 }
123
124 soldServiceModMap.putAll(parentSSMMap);
125 if(!fromTrigger) {
126 CPQ_Utils04_RequestStateCls.setOff('SOLD_SERVICE_SYNCED');
127 CPQ_Utils04_RequestStateCls.setOff('MODIFICATION');
128 }
129 //if(System.isQueueable()) CPQ_Utils04_RequestStateCls.setOn('DISMANTLE_QUEUEABLE');
130
131 for(Sold_Service_Modification__c ssmIFC : ssmFromIFC){
132 if(!soldServiceModMap.containsKey(ssmIFC.Sold_Service__c)){
133 soldServiceModMap.put(ssmIFC.Sold_Service__c, ssmIFC);
134 }
135 else if(ssmIFC.Action__c == 'Change' && ssmIFC.Stage__c == ApplicationConstant.SSM_STAGE_LIVE){
136 System.debug('ssmIFC.Stage__c: ' + ssmIFC.Stage__c);
137 soldServiceModMap.get(ssmIFC.Sold_Service__c).Stage__c = ssmIFC.Stage__c;
138 }
139 }
140 upsert soldServiceModMap.values();
141
142 /**
143 *** Logic used to retrieve SSM for cease & reprovide in order to fill in the lookup field from Cease to Reprovide SSM record
144 **/
145 List<Sold_Service_Modification__c> ceaseUpdateSSM = new List<Sold_Service_Modification__c>();
146 for(Sold_Service_Modification__c ssmRecords : soldServiceModMap.values()) {
147 if(ceaseReprovideMap.containsKey(ssmRecords.Upsert_Cease_Key__c)) {
148 ssmRecords.TECH_Related_SSM__r = new Sold_Service_Modification__c(Upsert_Cease_Key__c = ceaseReprovideMap.get(ssmRecords.Upsert_Cease_Key__c));
149 ceaseUpdateSSM.add(ssmRecords);
150 }
151 }
152 CPQ_Utils04_RequestStateCls.setOn('CPQ_SSM_SoldServiceModificationAllTriggers');
153 update ceaseUpdateSSM;
154 CPQ_Utils04_RequestStateCls.setOff('CPQ_SSM_SoldServiceModificationAllTriggers');
155
156 return soldServiceModMap;
157 }
158
159
160 /************************************************************************
161 Description : creates default modification for new Sold Services on Add operation.
162 soldService - Sold Services for which Sold Service Modifications are created
163 No of DML stmt : 2
164 ************************************************************************/
165 public static Map<Id, Sold_Service_Modification__c> mapSoldServiceModificationFields(List<CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper> soldServiceList, Map<Id, Sold_Service__c> idToServiceMap, Map<Id, CPQ_QuoteItem__c> quoteItemAttrMap, Map<Id,List<X3rd_Party_Services__c>> ssToTpsMap, Map<Id, Sold_Service_Modification__c> parentSSM, Map<Id,List<X3rd_Party_Services__c>> ssChildsToTpsMap, Map<Id, String> ssChildsToTPS) {
166 Map<Id, Sold_Service_Modification__c> result = new Map<Id, Sold_Service_Modification__c>();
167 List<Sold_Service__c> ssToUpdate = new List<Sold_Service__c>();
168 Set<Id> ssDuplicates = new Set<Id>();
169 List<X3rd_Party_Services__c> tpsToUpdate = new List<X3rd_Party_Services__c>();
170 Map<Id, String> ssToCeaseAndReprovideType = new Map<Id, String>();
171
172 Set<Id> oppLineItemsIds = new Set<Id>();
173 for(CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper singleService : soldServiceList){
174 oppLineItemsIds.add(singleService.quoteItem.OpportunityLineItem_ID__c);
175 }
176
177 Map<Id,Id> ss2ssm = new Map<Id,Id>();
178 List<OpportunityLineItem> oliList = [SELECT Existing_Object_ID__c, Existing_SSM_Id__c FROM OpportunityLineItem WHERE id IN :oppLineItemsIds AND Existing_Object_ID__c <> null];
179 for(OpportunityLineItem oli : oliList){
180 ss2ssm.put(oli.Existing_Object_ID__c, oli.Existing_SSM_Id__c);
181 }
182
183 Id devRecordTypeId = Schema.SObjectType.Sold_Service_Modification__c.getRecordTypeInfosByName().get('Sold Service Modification').getRecordTypeId();
184 for(CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper singleService : soldServiceList) {
185 ssToCeaseAndReprovideType.put(singleService.soldService.Id, singleService.quoteItem.Cease_and_Reprovide_Type__c);
186
187 String strSobjects = ' ';
188 Sold_Service_Modification__c soldServiceMod = new Sold_Service_Modification__c();
189 Sold_Service_Modification__c oldSoldServiceMod;
190
191 Sold_Service__c updatedSS = new Sold_Service__c(Id = singleService.soldService.Id);
192 if(singleService.quoteItem != null) {
193 Decimal leadTime = singleService.quoteItem.Lead_Time__c == null ? 0 : singleService.quoteItem.Lead_Time__c;
194 soldServiceMod.Estimated_Delivery_Date__c = singleService.quoteItem.Opportunity__r.CloseDate.addDays(leadTime.intValue());
195 }
196
197 //@@ Maciej Rudnicki (maciej.rudnicki@enxoo.com) default field fill
198 if(ApplicationConstant.SOLDSERVICEMOD_FIELDS_LINKNET_ADDRESSING.contains(singleService.SoldService.Type_of_Service_Description__c)) {
199 soldServiceMod.Linknet_IPv4_Addressing__c = '/31';
200 }
201
202 System.debug('@@ MARUD Diverse_from__c :: ' + singleService.SoldService.Diverse_from__c);
203 //@@ Maciej Rudnicki (maciej.rudnicki@enxoo.com) default field fill
204 if(singleService.SoldService.Diverse_from__c != null) {
205 soldServiceMod.Diverse_from__c = singleService.SoldService.Diverse_from__c;
206 }
207
208 soldServiceMod.Sold_Service__c = singleService.soldService.Id;
209 soldServiceMod.CRM_Account__c = singleService.soldService.CRM_Account__c;
210 soldServiceMod.RecordTypeId = devRecordTypeId;
211 soldServiceMod.Opp_Link__c = singleService.soldService.Opp_Link__c;
212
213 if(singleService.quoteItem.A_Port__c != null){
214 soldServiceMod.LAG_LACP__c = singleService.quoteItem.A_Port__r.LAG_LACP__c;
215 soldServiceMod.LAG_LACP_Details__c = singleService.quoteItem.A_Port__r.LAG_LACP_Details__c;
216 }
217
218 if(singleService.quoteItem != null){
219 soldServiceMod.Quote_Item__c = singleService.quoteItem.Id;
220 }
221
222 String h1 = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
223 String newSSMupsertKey = h1.substring(0, 8) + '-' + h1.substring(8, 12) + '-' + h1.substring(12, 16) + '-' + h1.substring(16, 20) + '-' + h1.substring(20);
224
225 soldServiceMod.Upsert_Cease_Key__c = newSSMupsertKey;
226
227
228 if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_ADD) {
229
230 Set<String> doNotCopy = new Set<String>{'Id', 'RecordType', 'RecordTypeId', 'Name', 'Details__c', 'TECH_Mod_Attributes_List__c', 'Stage__c',
231 'Account__c', 'Action__c', 'Sold_Service__c', 'TECH_Definition_JSON__c', 'Latest_Service_Comment__c',
232 'Escalation_Status__c', 'Internal_Escalation_Level__c', 'Modification_Cycle_Time__c', 'Missed_Delivery_Date_Reason__c',
233 'Minimum_Status_Assignment__c', 'Minimum_Status_TPS__c', 'WO_Group_Status_SSCR__c', 'Maximum_RFS_Date_Assignment__c',
234 'Maximum_RFS_Date_TPS__c','Committed_Delivery_Date__c', 'Date_Sold_Service_Stage_was_modified__c', 'RFS_Date__c', 'Estimated_Delivery_Date__c',
235 'FDC_Code__c', 'TSIC_Contracting_Company2__c'};
236 Set<String> fieldsToCopy = ssmFields;
237 fieldsToCopy.removeAll(doNotCopy);
238 soldServiceMod.Name = singleService.soldService.Name + ' '+ singleService.soldService.Item_Action__c + ' '+ String.valueOf(System.today());
239 soldServiceMod.Action__c = singleService.soldService.Item_Action__c;
240
241 Sold_Service__c oldService = idToServiceMap.get(singleService.soldService.Id);
242
243 buildSsmJSON(singleService.soldService, oldService, soldServiceMod);
244
245 //since API names between Sold Service and its Modfication match API Names we can copy automaticly all of them:
246 for(String field : fieldsToCopy) {
247 try {
248 if(singleService.soldService.get(field) != null) soldServiceMod.put(field,singleService.soldService.get(field));
249 } catch(Exception e) {
250 System.debug('XXX cannot convert field: '+field);
251 }
252 }
253
254 syncStage(updatedSS, soldServiceMod);
255 if(singleService.soldService.CRM_Parent_Sold_Service__c != null && (!parentSSM.isEmpty() || (CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm != null && !CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm.isEmpty() ) ) ) {
256 Sold_Service_Modification__c tempSsm;
257 if(CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm != null && CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm.containsKey(singleService.soldService.CRM_Parent_Sold_Service__c)){
258 tempSsm = CPQ_PRD08_CreateSoldServiceBatchHlpr.ss2ssm.get(singleService.soldService.CRM_Parent_Sold_Service__c);
259 } else {
260 tempSsm = parentSSM.get(singleService.soldService.CRM_Parent_Sold_Service__c);
261 }
262 if(tempSsm != null){
263 soldServiceMod.CRM_Parent_Sold_Service_Modification__c = tempSsm.Id;
264 soldServiceMod.FDC_Code__c = tempSsm.FDC_Code__c;
265 }
266 }
267 } else if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_RENEWAL
268 || singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CHANGE
269 || singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE) {
270
271 soldServiceMod.Name = singleService.soldService.Name + ' '+ singleService.soldService.Item_Action__c + ' '+
272 //we use created date for migration purposes
273 String.valueOf(singleService.soldService.CreatedDate != null ? (Date) singleService.soldService.CreatedDate : System.today());
274
275 Set<String> doNotCopy = new Set<String>{'Id', 'RecordType', 'RecordTypeId', 'Name', 'Stage__c', 'Details__c', 'TECH_Mod_Attributes_List__c', 'TECH_Cease_Parallel_Build__c', 'Action__c', 'Account__c', 'Sold_Service__c',
276 'TECH_Definition_JSON__c', 'Latest_Service_Comment__c' , 'Escalation_Status__c', 'Internal_Escalation_Level__c', 'Modification_Cycle_Time__c', 'Missed_Delivery_Date_Reason__c',
277 'Minimum_Status_Assignment__c', 'Minimum_Status_TPS__c', 'WO_Group_Status_SSCR__c', 'Maximum_RFS_Date_Assignment__c', 'Maximum_RFS_Date_TPS__c','Committed_Delivery_Date__c',
278 'Date_Sold_Service_Stage_was_modified__c', 'RFS_Date__c', 'Estimated_Delivery_Date__c', 'Dismantle_Notes__c', 'Person_requesting_the_dismantle__c', 'Specification_Received_Date__c',
279 'FDC_Code__c', 'TSIC_Contracting_Company2__c'};
280 Set<String> fieldsToCopy = ssmFields;
281 fieldsToCopy.removeAll(doNotCopy);
282
283 //since API names between Sold Service and its Modfication match API Names we can copy automaticly all of them:
284 for(String field : fieldsToCopy) {
285 try {
286 if(singleService.soldService.get(field) != null) soldServiceMod.put(field,singleService.soldService.get(field));
287 } catch(Exception e) {
288 System.debug('XXX cannot convert field: '+ field);
289 }
290 }
291
292 if(parentSSM != null) {
293 if(parentSSM.containsKey(singleService.soldService.CRM_Parent_Sold_Service__c)) soldServiceMod.CRM_Parent_Sold_Service_Modification__c = parentSSM.get(singleService.soldService.CRM_Parent_Sold_Service__c).Id;
294 }
295
296 if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_RENEWAL) {
297 soldServiceMod.Action__c = CPQ_PRD04_SoldServiceMappingHlpr.ACTION_RENEWAL;
298 soldServiceMod.Stage__c = ApplicationConstant.SSM_STAGE_RENEWAL_PENDING;
299 if(idToServiceMap.containsKey(singleService.soldService.Id)) buildSsmJSON(singleService.soldService, idToServiceMap.get(singleService.soldService.Id), soldServiceMod);
300 } else if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CHANGE) {
301 soldServiceMod.Action__c = CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CHANGE;
302 if(idToServiceMap.containsKey(singleService.soldService.Id)) buildSsmJSON(singleService.soldService, idToServiceMap.get(singleService.soldService.Id), soldServiceMod);
303 } else if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE) {
304 soldServiceMod.Action__c = CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE;
305 if(singleService.parallelBuild) {
306 soldServiceMod.Action__c = ApplicationConstant.SSM_ITEM_ACTION_REPROVIDE_PARALLEL;
307 if(singleService.oldSoldService != null) soldServiceMod.Sold_Service_Previous_Instance__c = singleService.oldSoldService.Id;
308 soldServiceMod.TECH_Cease_Parallel_Build__c = true;
309 soldServiceMod.Stage__c = ApplicationConstant.SSM_STAGE_NEW;
310 soldServiceMod.Name = singleService.soldService.Name + ' '+ ApplicationConstant.SSM_ITEM_ACTION_REPROVIDE_PARALLEL + ' '+
311 //we use created date for migration purposes
312 String.valueOf(singleService.soldService.CreatedDate != null ? (Date) singleService.soldService.CreatedDate : System.today());
313
314 soldServiceMod.Item_Type__c = CPQ_PRD04_SoldServiceMappingHlpr.PROD_TYPE_OPERATIONAL;
315 // REPROVIDE Dismantle Request Received Date
316 //soldServiceMod.Specification_Received_Date__c = singleService.soldService.CreatedDate != null ? (Date) singleService.soldService.CreatedDate : System.today();
317 soldServiceMod.Service_Description__c =singleService.soldService.Service_Description__c;
318
319
320 //if(idToServiceMap.containsKey(singleService.soldService.Id)) {
321 // Sold_Service__c oldService = idToServiceMap.get(singleService.soldService.Id);
322 // DateTime datetimeBuffer = oldService.Renewed_To__r.RFS_Date__c;
323 // try {
324 // soldServiceMod.Date_for_Dismantle__c = datetimeBuffer.addDays((Integer)soldServiceMod.Days_of_Parallel_Running__c);
325 // } catch(NullPointerException npe) {
326 // soldServiceMod.Date_for_Dismantle__c = datetimeBuffer;
327 // }
328 //}
329
330
331 if(parentSSM != null) {
332 if(parentSSM.containsKey(singleService.soldService.CRM_Parent_Sold_Service__c)) soldServiceMod.CRM_Parent_Sold_Service_Modification__c = parentSSM.get(singleService.soldService.CRM_Parent_Sold_Service__c).Id;
333 }
334 oldSoldServiceMod = new Sold_Service_Modification__c();
335 oldSoldServiceMod.TECH_Cease_Parallel_Build__c = true;
336 oldSoldServiceMod.Stage__c = ApplicationConstant.SSM_STAGE_NEW;
337 oldSoldServiceMod.Sold_Service__c = singleService.oldSoldService.Id;
338 oldSoldServiceMod.CRM_Account__c = singleService.oldSoldService.CRM_Account__c;
339 oldSoldServiceMod.RecordTypeId = devRecordTypeId;
340 oldSoldServiceMod.Opp_Link__c = singleService.oldSoldService.Opp_Link__c;
341 oldSoldServiceMod.Action__c = ApplicationConstant.SSM_ITEM_ACTION_CEASE_PARALLEL;
342 if(singleService.SoldService != null) oldSoldServiceMod.Next_Sold_Service_Instance__c = singleService.SoldService.Id;
343 //TSIC Contracting Company and FDC Code from Opunity -> Tsic Contracting company relation
344 if (oppMap != null && oldSoldServiceMod.Opp_Link__c != null && oppMap.get(oldSoldServiceMod.Opp_Link__c) != null && oppMap.get(oldSoldServiceMod.Opp_Link__c).TSIC_Contracting_Company__c != null) {
345 oldSoldServiceMod.FDC_Code__c = oppMap.get(oldSoldServiceMod.Opp_Link__c).TSIC_Contracting_Company__r.FDC_Code__c;
346 oldSoldServiceMod.TSIC_Contracting_Company2__c = oppMap.get(oldSoldServiceMod.Opp_Link__c).TSIC_Contracting_Company__r.TSIC_Contracting_Company_Name__c;
347 }
348
349 //Dismantle details fields
350 oldSoldServiceMod.Person_requesting_the_dismantle__c = singleService.soldService.Person_requesting_the_dismantle__c;
351 oldSoldServiceMod.Dismantle_Notes__c = singleService.soldService.Dismantle_Notes__c;
352 oldSoldServiceMod.Specification_Received_Date__c = singleService.soldService.Specification_Received_Date__c;
353
354
355 String h2 = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
356 String oldSSMupsertKey = h2.substring(0, 8) + '-' + h2.substring(8, 12) + '-' + h2.substring(12, 16) + '-' + h2.substring(16, 20) + '-' + h2.substring(20);
357
358 oldSoldServiceMod.Upsert_Cease_Key__c = oldSSMupsertKey;
359
360 if(!ceaseReprovideMap.containsKey(oldSSMupsertKey)) {
361 ceaseReprovideMap.put(oldSSMupsertKey, newSSMupsertKey);
362 }
363
364 //oldSoldServiceMod.TECH_Related_SSM__r = new Sold_Service_Modification__c(Upsert_Cease_Key__c = soldServiceMod.Upsert_Cease_Key__c);
365
366 oldSoldServiceMod.Name = singleService.oldSoldService.Name + ' '+ ApplicationConstant.SSM_ITEM_ACTION_CEASE_PARALLEL + ' ' +
367 //we use created date for migration purposes
368 String.valueOf(singleService.oldSoldService.CreatedDate != null ? (Date) singleService.oldSoldService.CreatedDate : System.today());
369
370 for(String field : fieldsToCopy) {
371 try {
372 if(singleService.oldSoldService.get(field) != null) oldSoldServiceMod.put(field,singleService.oldSoldService.get(field));
373 } catch(Exception e) {
374 System.debug('XXX cannot convert field: '+field);
375 }
376 }
377 Sold_Service__c updatedOldSS = new Sold_Service__c(Id = singleService.oldSoldService.Id);
378 syncStage(updatedOldSS, oldSoldServiceMod);
379 if(!ssDuplicates.contains(updatedOldSS.Id)) {
380 ssDuplicates.add(updatedOldSS.Id);
381 ssToUpdate.add(updatedOldSS);
382 }
383
384 Id ssID;
385 if(oldSoldServiceMod.Sold_Service__c != null) ssID = oldSoldServiceMod.Sold_Service__c;
386 Set<String> locationFieldsToQuery = new Set<String>{'A_Connector__c','A_Demarc_Type__c','B_Demarc_Type__c','B_Connector__c', 'A_Interface__c','B_Interface__c','A_Port_Type__c', 'B_Port_Type__c','A_Demarc_Site__c','B_Demarc_Site__c','A_Rack_Cabinet__c','B_Rack_Cabinet__c','A_Room__c','B_Room__c','A_Floor__c','B_Floor__c','A_Demarc_Comments__c','B_Demarc_Comments__c','A_Site__c', 'B_Site__c','Service_Description__c', 'A_Port__c', 'A_Location__c', 'A_Homing_Gateway_Location__c', 'B_Port__c', 'B_Location__c', 'B_Homing_Gateway_Location__c'};
387 String queryString = 'SELECT ' + SoldServiceUtility.buildQueryFields(locationFieldsToQuery) + ' FROM Sold_Service__c WHERE id =: ssID';
388
389 for(Sold_Service__c ss :(List<Sold_Service__c>)Database.query(queryString)){
390
391
392 for(String field : locationFieldsToQuery){
393 try {
394 oldSoldServiceMod.put(field, ss.get(field));
395
396 }catch(Exception e) {
397
398 System.debug('XXX cannot convert field: '+field);
399
400 }
401 }
402 }
403
404 }
405
406 //Location must be fetched from old sold service as SSM is 'Cease'. For 'Reprovide' SSM, it is fetched earlier from new SS
407
408
409
410
411 Sold_Service__c oldService;
412 if(singleService.oldSoldService != null) {
413 oldService = idToServiceMap.get(singleService.oldSoldService.Id);
414 } else {
415 oldService = idToServiceMap.get(singleService.soldService.Id);
416 }
417 buildSsmJSON(singleService.soldService, oldService, soldServiceMod);
418 }
419 syncStage(updatedSS, soldServiceMod);
420
421
422 } else if(singleService.soldService.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_DISMANTLE) {
423
424 soldServiceMod.Name = singleService.soldService.Name + ' '+ singleService.soldService.Item_Action__c + ' '+ String.valueOf(System.today());
425 soldServiceMod.Opp_Link__c = singleService.soldService.Opp_Link__c;
426 soldServiceMod.Stage__c = ApplicationConstant.SSM_STAGE_NEW;
427 soldServiceMod.Action__c = CPQ_PRD04_SoldServiceMappingHlpr.ACTION_DISMANTLE;
428 soldServiceMod.Date_for_Dismantle__c = singleService.soldService.Date_for_Dismantle__c;
429 soldServiceMod.Person_requesting_the_dismantle__c = singleService.soldService.Person_requesting_the_dismantle__c;
430 soldServiceMod.Dismantle_Notes__c = singleService.soldService.Dismantle_Notes__c;
431 soldServiceMod.Specification_Received_Date__c = singleService.soldService.Specification_Received_Date__c;
432 soldServiceMod.RecordTypeId = devRecordTypeId;
433 soldServiceMod.Sold_Service__c = singleService.soldService.Id;
434 soldServiceMod.A_Cabling_Point__c = singleService.soldService.A_Cabling_Point__c;
435 soldServiceMod.B_Cabling_Point__c = singleService.soldService.B_Cabling_Point__c;
436
437 if (parentSSM != null)
438 soldServiceMod.Dismantle_Related_Services__c = ApplicationConstant.SOLDSERVICE_DISMANTLE_CHILD_SERVICES_YES;
439 else
440 soldServiceMod.Dismantle_Related_Services__c = ApplicationConstant.SOLDSERVICE_DISMANTLE_CHILD_SERVICES_NO;
441
442 syncStage(updatedSS, soldServiceMod);
443
444 Set<String> doNotCopy = new Set<String>{'Id', 'Delivery_Coordinator__c', 'OLI_Link_name__c', 'OLI_Link_ID__c', 'RecordType', 'RecordTypeId',
445 'Latest_Service_Comment__c' , 'Escalation_Status__c',
446 'Internal_Escalation_Level__c', 'Modification_Cycle_Time__c',
447 'Missed_Delivery_Date_Reason__c', 'Minimum_Status_Assignment__c',
448 'Minimum_Status_TPS__c', 'WO_Group_Status_SSCR__c',
449 'Maximum_RFS_Date_Assignment__c', 'Maximum_RFS_Date_TPS__c',
450 'Committed_Delivery_Date__c', 'Date_Sold_Service_Stage_was_modified__c',
451 'RFS_Date__c', 'Name', 'Stage__c', 'CreatedBy', 'CreatedDate',
452 'LastModifiedDate', 'CreatedById', 'Details__c', 'TECH_Mod_Attributes_List__c',
453 'TECH_Cease_Parallel_Build__c', 'Action__c', 'Account__c', 'Sold_Service__c',
454 'CRM_Parent_Sold_Service__c', 'TECH_Definition_JSON__c', 'Estimated_Delivery_Date__c', 'Opp_Link__c',
455 'Sold_Service_Opportunity__c'};
456 Set<String> fieldsToCopy = ssmFields;
457 fieldsToCopy.removeAll(doNotCopy);
458 Sold_Service__c soldServiceSource = idToServiceMap.get(singleService.soldService.Id);
459 //since API names between Sold Service and its Modfication match API Names we can copy automaticly all of them:
460 String helper = '';
461 for(String field : fieldsToCopy) {
462 try {
463 helper += '{' + field + ' - > ' + soldServiceSource.get(field) + ' },';
464 if(soldServiceSource.get(field) != null) soldServiceMod.put(field,soldServiceSource.get(field));
465 } catch(Exception e) {
466 System.debug('XXX cannot convert field: '+field);
467 }
468 }
469 if(parentSSM != null) {
470 if(parentSSM.containsKey(singleService.soldService.CRM_Parent_Sold_Service__c)) soldServiceMod.CRM_Parent_Sold_Service_Modification__c = parentSSM.get(singleService.soldService.CRM_Parent_Sold_Service__c).Id;
471 }
472
473 } else if(singleService.soldService.Item_Action__c == null || singleService.soldService.Item_Action__c == '') {//this should happen only during migration of bad data. Still has to be handled.
474 soldServiceMod = new Sold_Service_Modification__c();
475 Set<String> doNotCopy = new Set<String>{'Id', 'RecordType', 'RecordTypeId', 'Stage__c', 'Sold_Service__c', 'TECH_Definition_JSON__c', 'Latest_Service_Comment__c',
476 'Escalation_Status__c', 'Internal_Escalation_Level__c', 'Modification_Cycle_Time__c', 'Missed_Delivery_Date_Reason__c',
477 'Minimum_Status_Assignment__c', 'Minimum_Status_TPS__c', 'WO_Group_Status_SSCR__c', 'Maximum_RFS_Date_Assignment__c',
478 'Maximum_RFS_Date_TPS__c','Committed_Delivery_Date__c', 'Date_Sold_Service_Stage_was_modified__c', 'RFS_Date__c', 'Estimated_Delivery_Date__c'};
479 Set<String> fieldsToCopy = ssmFields;
480 fieldsToCopy.removeAll(doNotCopy);
481
482 //since API names between Sold Service and its Modfication match API Names we can copy automaticly all of them:
483 for(String field : fieldsToCopy) {
484 try {
485 soldServiceMod.put(field,singleService.soldService.get(field));
486 } catch(Exception e) {
487 System.debug('XXX cannot convert field: '+field);
488 }
489 }
490
491 soldServiceMod.RecordTypeId = devRecordTypeId;
492 soldServiceMod.TECH_Definition_JSON__c = strSobjects;
493 soldServiceMod.Sold_Service__c = singleService.soldService.Id;
494 }
495
496 if (oppMap != null && soldServiceMod.Opp_Link__c != null && oppMap.get(soldServiceMod.Opp_Link__c) != null && oppMap.get(soldServiceMod.Opp_Link__c).TSIC_Contracting_Company__c != null) {
497 soldServiceMod.FDC_Code__c = oppMap.get(soldServiceMod.Opp_Link__c).TSIC_Contracting_Company__r.FDC_Code__c;
498 soldServiceMod.TSIC_Contracting_Company2__c = oppMap.get(soldServiceMod.Opp_Link__c).TSIC_Contracting_Company__r.TSIC_Contracting_Company_Name__c;
499 }
500
501
502 if(!(ss2ssm.containsKey(soldServiceMod.Sold_Service__c) && soldServiceMod.Action__c == 'Add')){
503 if(soldServiceMod != null && !result.containsKey(singleService.soldService.Id)) {
504 result.put(singleService.soldService.Id, soldServiceMod);
505 }if(oldSoldServiceMod != null && !result.containsKey(singleService.oldSoldService.Id)) {
506 result.put(singleService.oldSoldService.Id, oldSoldServiceMod);
507 }
508 if(!ssDuplicates.contains(updatedSS.Id)) {
509 ssDuplicates.add(updatedSS.Id);
510 ssToUpdate.add(updatedSS);
511 }
512 }
513 }
514
515 Map<Id, List<String>> existingModifications = checkExistingSSM(result);
516
517 List<Opportunity> oppList = Trigger.new;
518
519 if(oppList!= null) {
520 for(Id ssId : result.keyset()) {
521 if(existingModifications.containsKey(ssId)) {
522 for(Opportunity singleOpp : oppList) {
523 if(singleOpp.Id == result.get(ssId).Opp_Link__c) {
524 if(!alreadyExistingSSM.isEmpty() && !existingModifications.get(ssID).isEmpty()) {
525 singleOpp.addError('There is already open SSM record: <a target="_blank" href="/' + alreadyExistingSSM.get(ssId).Id +'">'+alreadyExistingSSM.get(ssId).Name+'</a> below attributes must be corrected: ' +'<br/> ' + existingModifications.get(ssID), false);
526 }
527 }
528 }
529 }
530 }
531 }
532
533 Set<Id> ssIds = new Set<Id>();
534 Set<Id> oppIds = new Set<Id>();
535 for(Sold_Service_Modification__c ssm : result.values()){
536 ssIds.add(ssm.Sold_Service__c);
537 oppIds.add(ssm.Opp_Link__c);
538 }
539
540 List<CPQ_QuoteItem__c> ssmChildQiList = [SELECT Id, Existing_Object_ID__r.CRM_Parent_Sold_Service__c
541 FROM CPQ_QuoteItem__c
542 WHERE Existing_Object_ID__r.CRM_Parent_Sold_Service__c = :ssIds
543 AND Item_Action__c = :ApplicationConstant.OLI_ITEM_ACTION_DESCRIPTION_IN_FLIGHT_CHANGE
544 AND Opportunity__c = :oppIds];
545
546 Map<Id, CPQ_QuoteItem__c> ss2QiMap = new Map<Id, CPQ_QuoteItem__c>();
547 for(CPQ_QuoteItem__c qi : ssmChildQiList){
548 ss2QiMap.put(qi.Existing_Object_ID__r.CRM_Parent_Sold_Service__c, qi);
549 }
550
551 for(Sold_Service_Modification__c ssm : result.values()){
552 if(ss2QiMap.containsKey(ssm.Sold_Service__c) && ssm.Action__c == ApplicationConstant.ACTION_CHANGE){
553 ssm.Stage__c = ApplicationConstant.SSM_STAGE_LIVE;
554 }
555 }
556
557 //PRTUS - 05-11-17 TSIC-1581 // to chceck, currently this records are upserted later, which breaks flow
558 if(result != null && result.size() > 0 ) {
559 //if(result != null && result.size() > 0 && existingModifications != null && existingModifications.isEmpty()) {
560 System.debug(LoggingLevel.WARN, 'SSM RECORDS = '+result.values());
561
562 CPQ_Utils04_RequestStateCls.setOn('SSM_UPDATE_FLAG');
563 insert result.values();
564 CPQ_Utils04_RequestStateCls.setOff('SSM_UPDATE_FLAG');
565 }
566
567 //based on Action handle TPSes
568 for(Id ssID : result.keySet()) {
569 Sold_Service_Modification__c soldServiceMod = result.get(ssId);
570 Id ssForTps;
571 if(soldServiceMod.TECH_Cease_Parallel_Build__c == true && soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_REPROVIDE) {
572 ssForTps = soldServiceMod.Sold_Service__c;
573 } else if (soldServiceMod.TECH_Cease_Parallel_Build__c == true) {
574 ssForTps = soldServiceMod.Sold_Service_Previous_Instance__c;
575 } else {
576 ssForTps = soldServiceMod.Sold_Service__c;
577 }
578
579 if(soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_ADD || soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_RENEWAL || soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_REPROVIDE ||
580 (soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE && soldServiceMod.Quote_Item__r.Cease_and_Reprovide_Type__c == CPQ_PRD04_SoldServiceMappingHlpr.CEASE_PARALLEL_BUILD)) {
581 if(ssToTpsMap.get(ssForTps) != null) {
582 for(X3rd_Party_Services__c tps : ssToTpsMap.get(ssForTps)) {
583 tps.Sold_Service_Modification__c = soldServiceMod.Id;
584 }
585 }
586 } else if(soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CHANGE ||
587 (soldServiceMod.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE && ssToCeaseAndReprovideType.get(ssForTps) == CPQ_PRD04_SoldServiceMappingHlpr.CEASE_HOT_CUT)) {
588 if (ssToTpsMap.get(ssForTps) != null) {
589 for (X3rd_Party_Services__c tps : ssToTpsMap.get(ssForTps)) {
590 tps.Sold_Service_Modification__c = soldServiceMod.Id;
591 }
592 }
593 }
594 for(CPQ_PRD04_SoldServiceMappingHlpr.soldServiceWrapper singleService : soldServiceList) {
595 if(soldServiceMod.Sold_Service__c == singleService.soldService.Id) {
596 if(singleService.soldService.OLI_Link_ID__c != null) {
597 ssOliMap.put(soldServiceMod.Id, singleService.soldService.OLI_Link_ID__c);
598 }
599 }
600 }
601 if (ssToTpsMap.get(ssForTps) != null || ssChildsToTpsMap != null)
602 soldServiceMod = ThirdPartyServiceTriggerHandler.setSoldServiceModificationFinancial(ssToTpsMap.get(ssForTps), ssChildsToTpsMap, soldServiceMod, ssChildsToTPS);
603 }
604
605
606 for(List<X3rd_Party_Services__c> tpsList : ssToTpsMap.values()) {
607 tpsToUpdate.addAll(tpsList);
608 }
609
610 update tpsToUpdate;
611
612 update ssToUpdate;
613
614 return result;
615 }
616
617 public static void syncStage(Sold_Service__c ss, Sold_Service_Modification__c ssm) {
618 String key = ssm.Action__c;
619 if(ssm.Stage__c != null && key != null){
620 if (ssm.Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_CEASE) {
621 key = ApplicationConstant.HOT_CUT_BLOCK;
622 } else if (ssm.Action__c == ApplicationConstant.SSM_ITEM_ACTION_REPROVIDE_PARALLEL) {
623 key = ApplicationConstant.C_AND_R_NEW_BLOCK;
624 } else if (ssm.Action__c == ApplicationConstant.SSM_ITEM_ACTION_CEASE_PARALLEL) {
625 key = ApplicationConstant.C_AND_R_BLOCK;
626 }
627
628 if (ssm.Stage__c != null && ApplicationConstant.stageMap.containsKey(key + '_' + ssm.Stage__c)){
629 key += '_' + ssm.Stage__c;
630 }
631
632 ss.Stage__c = ApplicationConstant.stageMap.get(key).stage;
633 System.debug('@@@MAGAR STAGE key: '+key);
634 System.debug('@@@MAGAR STAGE GETKEY: '+ApplicationConstant.stageMap.get(key));
635 System.debug('@@@MAGAR STAGE : '+ApplicationConstant.stageMap.get(key).stage);
636 if (!(ss.Stage__c == ApplicationConstant.SOLDSERVICE_STAGE_DISMANTLE_PENDING && ss.Status__c == ApplicationConstant.SOLDSERVICE_STATUS_INACTIVE)) {
637
638 System.debug('@@@MAGAR jeste w tym ciezkim ifie : '+ApplicationConstant.stageMap.get(key).stage);
639 ss.Status__c = ApplicationConstant.stageMap.get(key).status;
640 }
641 }
642 }
643
644 public static Map<Id, List<String>> checkExistingSSM(Map<Id, Sold_Service_Modification__c> soldServiceModMap) {
645 Map<Id, Sold_Service__c> currentlyUsedSS = new Map<Id, Sold_Service__c>();
646 Map<Id, List<String>> result = new Map<Id, List<String>>();
647 /**
648 ** Check if there are some open SSM modifying same atributes, if yes display warning message
649 **/
650 for(Sold_Service_Modification__c existingSSM : [SELECT Id, Sold_Service__c, Name, Action__c, TECH_Mod_Attributes_List__c FROM Sold_Service_Modification__c WHERE Sold_Service__c IN : soldServiceModMap.keyset() AND (Stage__c != :ApplicationConstant.SSM_STAGE_LIVE AND Stage__c != :ApplicationConstant.SSM_STAGE_CANCELLED AND Stage__c != :ApplicationConstant.SSM_STAGE_REJECTED)]) {
651 if(existingSSM.TECH_Mod_Attributes_List__c!= null && existingSSM.Action__c != ApplicationConstant.ACTION_DISMANTLE) {
652 List<String> currentlyUpdatingFields = existingSSM.TECH_Mod_Attributes_List__c.split('\r\n');
653 if(soldServiceModMap.containsKey(existingSSM.Sold_Service__c) && soldServiceModMap.get(existingSSM.Sold_Service__c).TECH_Mod_Attributes_List__c != null) {
654 List<String> alreadyExistingUpdates = soldServiceModMap.get(existingSSM.Sold_Service__c).TECH_Mod_Attributes_List__c.split('\r\n');
655
656 List<String> sameValues = new List<String>();
657 for(String attribute : currentlyUpdatingFields) {
658 for(String oldAttribute : alreadyExistingUpdates) {
659 if(attribute == oldAttribute) {
660 sameValues.add(attribute);
661 }
662 }
663 }
664 if(result.containsKey(existingSSM.Sold_Service__c)) {
665 result.get(existingSSM.Sold_Service__c).addAll(sameValues);
666 } else {
667 result.put(existingSSM.Sold_Service__c, sameValues);
668 }
669 }
670
671 if(!alreadyExistingSSM.containsKey(existingSSM.Sold_Service__c)) alreadyExistingSSM.put(existingSSM.Sold_Service__c, existingSSM);
672 }
673 }
674 return result;
675 }
676
677 public static void refreshConnectedWoOfGivenType(Map<Id, Sold_Service_Modification__c> ssmInputMap, String woType, String woRecordTypeId) {
678 List<WorkOrder> woToUpdateList = [
679 SELECT Id
680 FROM WorkOrder
681 WHERE Sold_Service_Modification__c IN :ssmInputMap.keySet()
682 AND RecordTypeId = :woRecordTypeId
683 AND Type__c = :woType
684 ];
685
686 if (woToUpdateList != null && !woToUpdateList.isEmpty()) update woToUpdateList;
687 }
688
689 /**
690 * @author Grzegorz Długosz - grzegorz.dlugosz@enxoo.com
691 * @description This method is used to refresh work orders based on input arguments.
692 * Its needed mostly for milestone recalculations.
693 * @param ssmInputMap - ssms for which work orders need to be refreshed
694 * @param woTypes - types of work orders that need to be refreshed
695 * @param woRecordTypeId - record type of work orders that need to be refreshed
696 */
697 public static void refreshConnectedWoOfGivenTypes(Map<Id, Sold_Service_Modification__c> ssmInputMap, List<String> woTypes, String woRecordTypeId) {
698 List<WorkOrder> woToUpdateList = [
699 SELECT Id
700 FROM WorkOrder
701 WHERE Sold_Service_Modification__c IN :ssmInputMap.keySet()
702 AND RecordTypeId = :woRecordTypeId
703 AND Type__c IN :woTypes
704 ];
705
706 if (woToUpdateList != null && !woToUpdateList.isEmpty()) update woToUpdateList;
707 }
708
709 public static void closeCDDMilestoneOnWo(Map<Id, Sold_Service_Modification__c> ssmInputMap) {
710 Map<Id, WorkOrder> woMapToUpdate = new Map<Id, WorkOrder>([
711 SELECT Id
712 FROM WorkOrder
713 WHERE Sold_Service_Modification__c IN :ssmInputMap.keySet()
714 AND RecordTypeId = :ApplicationConstant.WORK_ORDER_RECORD_TYPE_ID_DELIVERY
715 AND Type__c = :ApplicationConstant.WORK_ORDER_TYPE_DELIVERY_COORDINATOR
716 ]);
717
718 List<String> milestonesToCloseList = new List<String>();
719 milestonesToCloseList.add(CPQ_MIL01_UtilsCls.MIL_NAME_DELIVERY_ON_TIME);
720
721 CPQ_MIL01_UtilsCls.completeWorkOrderMilestone(woMapToUpdate, milestonesToCloseList, System.now());
722 }
723
724 public static void populateDateForDismantleOnReprovideSSM(Map<Id, Sold_Service_Modification__c> ssmInputMap) {
725 Map<Id,Sold_Service_Modification__c> listOfCeaseSSM = new Map<Id,Sold_Service_Modification__c>([SELECT Id , RFS_Date__c, Days_of_Parallel_Running__c ,(SELECT Id, Date_for_Dismantle__c, TECH_Related_SSM__c FROM Sold_Service_Modifications__r WHERE Action__c = 'Cease' LIMIT 1) FROM Sold_Service_Modification__c WHERE Id IN: ssmInputMap.keyset() AND RFS_Date__c <> NULL AND Stage__c = '30. Modification Complete' AND Action__c = 'Reprovide']);
726 List<Sold_Service_Modification__c> listOfCeaseSSMReadyForUpdate = new List<Sold_Service_Modification__c>();
727 for(Sold_Service_Modification__c tempSSMReprovide : ssmInputMap.values()){
728 if(!listOfCeaseSSM.get(tempSSMReprovide.Id).Sold_Service_Modifications__r.isEmpty()){
729 Sold_Service_Modification__c tempCeaseSSM = listOfCeaseSSM.get(tempSSMReprovide.Id).Sold_Service_Modifications__r[0];
730 DateTime datetimeBuffer = tempSSMReprovide.RFS_Date__c;
731 try {
732 tempCeaseSSM.Date_for_Dismantle__c = datetimeBuffer.addDays((Integer)tempSSMReprovide.Days_of_Parallel_Running__c);
733 } catch(NullPointerException npe) {
734 tempCeaseSSM.Date_for_Dismantle__c = datetimeBuffer;
735 }
736 listOfCeaseSSMReadyForUpdate.add(tempCeaseSSM);
737 }
738 }
739 if(!listOfCeaseSSMReadyForUpdate.isEmpty()) {
740 try{
741 update listOfCeaseSSMReadyForUpdate;
742 } catch( Exception e ){
743 System.debug('@@@CPQ_SSM01_Manager Method : populateDateForDismantleOnReprovide : Catch Exception: '+e.getMessage());
744 }
745 }
746 }
747 /***************************************************************************************
748 Developer Michał Pastuszka (Enxoo) michal.pastuszka@enxoo.com
749 Date 2017-08-09
750 Function Method used for building JSON file with current changes performed on SS record.
751 ****************************************************************************************/
752 public static Sold_Service_Modification__c buildSsmJSON(Sold_Service__c newSS, Sold_Service__c oldSS, Sold_Service_Modification__c result) {
753 Sold_Service__c ssResult = new Sold_Service__c();
754
755 String changedFields = '';
756 String modDetails = '';
757 Schema.DescribeSObjectResult obj = Schema.getGlobalDescribe().get('Sold_Service__c').getDescribe();
758 Map<String, Schema.SObjectField> schemaFieldMap = obj.fields.getMap();
759 if(newSS.Item_Action__c == CPQ_PRD04_SoldServiceMappingHlpr.ACTION_ADD) {
760 ssResult = newSS.clone(false, true, false, false);
761 } else {
762 for(String fieldName : schemaFieldMap.keySet()){
763 if(newSS.get(fieldName) != null && !ApplicationConstant.SOLDSERVICE_FIELDS_EXCLUDE.contains(fieldName) && newSS.get(fieldName) != oldSS.get(fieldName)) {
764 ssResult.put(obj.Fields.getMap().get(fieldName).getDescribe().getName(), newSS.get(fieldName));
765 changedFields = changedFields + obj.Fields.getMap().get(fieldName).getDescribe().getLabel() + '\r\n';
766 modDetails = modDetails + obj.Fields.getMap().get(fieldName).getDescribe().getLabel() + ': ' + oldSS.get(fieldName) + ' => ' + newSS.get(fieldName) + '\r\n';
767 }
768 }
769 }
770
771 result.Details__c = modDetails;
772 result.TECH_Mod_Attributes_List__c = changedFields;
773 result.TECH_Definition_JSON__c = JSON.Serialize(ssResult);
774 return result;
775 }
776
777 public static void updateSsmDetailFieldList(Map<Id, Sold_Service_Modification__c> newSSM, Map<Id, Sold_Service_Modification__c> oldSSM, Set<Id> idsList) {
778 String oldServicesQuery = 'SELECT ' + CPQ_Utils01_SObjectHelperCls.getFieldListForSOQL('Sold_Service__c', null, null) + ' FROM Sold_Service__c WHERE Id IN: idsList';
779 Map<Id, Sold_Service__c> oldSsMap = new Map<Id, Sold_Service__c>((List<Sold_Service__c>)Database.query(oldServicesQuery));
780 for(Id ssmId : newSSM.keyset()) {
781 if(newSSM.get(ssmId).Stage__c != ApplicationConstant.SSM_STAGE_LIVE) {
782 updateSsmDetailField(newSSM.get(ssmId), oldSSM.get(ssmId), oldSsMap);
783 }
784 }
785 }
786
787 private static String prepareDetailString(sObject object2check, String fieldName){
788 if(object2check.get(fieldName) instanceof Decimal){
789 Decimal tempDecimal = (Decimal)object2check.get(fieldName);
790 return String.valueOf(tempDecimal.setScale(2));
791 } else {
792 return String.valueOf(object2check.get(fieldName));
793 }
794 }
795
796 /***************************************************************************************
797 Developer Michał Pastuszka (Enxoo) michal.pastuszka@enxoo.com
798 Date 2017-08-09
799 Function Method used for updating Detail field, everytime user changes some field on SSM record.
800
801 Edit 2019-08-13
802 Developer Alan Moczulski (Enxoo) alan.moczulski@enxoo.com
803 Function All values from moddetails are stored in map and BP are converting from id's to names
804 ****************************************************************************************/
805 public static void updateSsmDetailField(Sold_Service_Modification__c newSSM, Sold_Service_Modification__c oldSSM, Map<Id, Sold_Service__c> oldSSMap) {
806
807 Map<String,List<Id>> referenceFields = new Map<String,List<Id>>();
808
809 //ALMOC MAP<FIELDNAME,MAP<OLDVALUE,NEWVALUE>
810 Map<String,Map<String,String>> mapOfFields= new Map<String,Map<String,String>>();
811
812 Set<String> changedFields = new Set<String>();
813 for(String fieldName : ssmschemaFieldMap.keySet()) {
814 if(!ApplicationConstant.SOLDSERVICE_FIELDS_EXCLUDE.contains(fieldName)) {
815 if(newSSM.get(fieldName) != oldSSM.get(fieldName)) {
816 changedFields.add(fieldName);
817 }
818 }
819 }
820//obj.smap = JSON.serialize(obj)
821 Sold_Service_Modification__c ssmSerialize;
822 if(newSSM.TECH_Changed_Values_JSON__c != null) {
823 ssmSerialize = (Sold_Service_Modification__c)JSON.deserialize(newSSM.TECH_Changed_Values_JSON__c, Sold_Service_Modification__c.class);
824 }
825
826 String modDetails = '';
827 if(newSSM.TECH_Definition_JSON__c != null) {
828 Sold_Service__c tempSS = (Sold_Service__c)JSON.deserialize(newSSM.TECH_Definition_JSON__c, Sold_Service__c.class);
829 for(String fieldName : schemaFieldMap.keySet()) {
830 if(schemaFieldMap.get(fieldName).getDescribe().isUpdateable()) {
831 if(!ApplicationConstant.SOLDSERVICE_FIELDS_EXCLUDE.contains(fieldName)){
832 String key = newSSM.Sold_Service_Previous_Instance__c != null ? newSSM.Sold_Service_Previous_Instance__c : newSSM.Sold_Service__c;
833 if(ssmschemaFieldMap.keySet().contains(fieldName) && tempSS.get(fieldName) != null && oldSSMap.get(key).get(fieldName) != null && tempSS.get(fieldName) != oldSSMap.get(key).get(fieldName)) {
834 if(ssmSerialize != null && ssmSerialize.get(fieldName) != null) {
835 String oldValue = prepareDetailString((sObject)oldSSMap.get(key), fieldName);
836 String newValue = prepareDetailString((sObject)tempSS, fieldName);
837 if(!ApplicationConstant.FIELDS_TO_NOT_COPY_IN_DETAILS_ONLY.contains(fieldName) && newValue == String.valueOf(newSSM.get(fieldName))){
838 modDetails = modDetails + obj.Fields.getMap().get(fieldName).getDescribe().getLabel() + ': ' + oldValue + ' => ' + newValue + '\r\n';
839
840 String valueOfField = String.valueof(ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel());
841 mapOfFields = putValuesToMap(mapOfFields,valueOfField,oldValue,newValue);
842 }
843 }
844 }
845 if(ssmSerialize != null && ssmschemaFieldMap.keySet().contains(fieldName) && ssmSerialize.get(fieldName) != null && tempSS.get(fieldName) != ssmSerialize.get(fieldName) && !changedFields.contains(fieldName)) {
846 String oldValue = prepareDetailString((sObject)tempSS, fieldName);
847 String newValue = prepareDetailString((sObject)ssmSerialize, fieldName);
848 if(!ApplicationConstant.FIELDS_TO_NOT_COPY_IN_DETAILS_ONLY.contains(fieldName)){
849 modDetails = modDetails + obj.Fields.getMap().get(fieldName).getDescribe().getLabel() + ': ' + oldValue + ' => ' + newValue + '\r\n';
850
851 String valueOfField = String.valueof(ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel());
852 mapOfFields = putValuesToMap(mapOfFields,valueOfField,oldValue,newValue);
853 }
854 }
855 }
856 }
857 }
858 }
859
860 /**
861 ** Update Details field based on manually changed fields on SSM record
862 **/
863
864 for(String fieldName : ssmschemaFieldMap.keySet()) {
865 if(ssmschemaFieldMap.get(fieldName).getDescribe().isUpdateable()) {
866 if(!ApplicationConstant.SOLDSERVICE_FIELDS_EXCLUDE.contains(fieldName)) {
867
868 if(newSSM.get(fieldName) != oldSSM.get(fieldName) ) {
869 /**
870 ** Update TECH_Changed_Values_JSON__c field with current changes, skip all fields listed in SOLDSERVICEMOD_FIELDS_EXCLUDE
871 **/
872 if(!ApplicationConstant.SOLDSERVICEMOD_FIELDS_EXCLUDE.contains(fieldName)) {
873 if(ssmSerialize != null) {
874 ssmSerialize.put(ssmobj.Fields.getMap().get(fieldName).getDescribe().getName(), newSSM.get(fieldName));
875 if(!ApplicationConstant.FIELDS_TO_NOT_COPY_IN_DETAILS_ONLY.contains(fieldName)){
876 String oldValue = prepareDetailString((sObject)oldSSM, fieldName);
877 String newValue = prepareDetailString((sObject)newSSM, fieldName);
878
879 modDetails = modDetails + ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel() + ': ' + oldSSM.get(fieldName) + ' => ' + newSSM.get(fieldName) + '\r\n';
880
881 String valueOfField = String.valueof(ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel());
882 mapOfFields = putValuesToMap(mapOfFields,valueOfField,oldValue , newValue);
883 }
884 } else {
885 ssmSerialize = new Sold_Service_Modification__c();
886 ssmSerialize.put(ssmobj.Fields.getMap().get(fieldName).getDescribe().getName(), newSSM.get(fieldName));
887 if(!ApplicationConstant.FIELDS_TO_NOT_COPY_IN_DETAILS_ONLY.contains(fieldName)){
888 String oldValue = prepareDetailString((sObject)oldSSM, fieldName);
889 String newValue = prepareDetailString((sObject)newSSM, fieldName);
890
891 modDetails = modDetails + ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel() + ': ' + oldSSM.get(fieldName) + ' => ' + newSSM.get(fieldName) + '\r\n';
892
893 String valueOfField = String.valueof(ssmobj.Fields.getMap().get(fieldName).getDescribe().getLabel());
894 mapOfFields = putValuesToMap(mapOfFields,valueOfField,oldValue , newValue);
895 }
896 }
897 }
898 }
899 }
900 }
901 }
902 if(newSSM.Action__c == 'Technical Change')System.debug('TC!!!!');
903 if(!String.isEmpty(modDetails)){
904 modDetails = returnDetailsFromMap(mapOfFields);
905 newSSM.Details__c = modDetails;
906 }
907 if(ssmSerialize != null) {
908 newSSM.TECH_Changed_Values_JSON__c = JSON.Serialize(ssmSerialize);
909 }
910 }
911 public static Map<String,Map<String,String>> putValuesToMap(Map<String,Map<String,String>> fields, String fieldToMap, String oldValues,String newValues){
912
913 String key = fieldToMap;
914 String detailss = '';
915
916 Map<String,String> oldValueNewValue = new Map<String,String>();
917
918 if(key != null && !key.containsIgnoreCase('Billing Profile') && !fields.containsKey(key)){
919 oldValueNewValue.put(oldValues,newValues);
920 fields.put(key, oldValueNewValue);
921 }else if(key.containsIgnoreCase('Billing Profile') && !fields.containsKey(key)){
922
923 Id newId =(Id) oldValues;
924 Id oldId =(Id) newValues;
925
926 String oldValToMap = '';
927 String newValToMap = '';
928
929 if(newId != null){
930 Map<Id,Billing_Profile__c> bpNew = new Map<Id, Billing_Profile__c>([SELECT Name,Id FROM Billing_Profile__c WHERE Id = :newId]);
931 if(bpNew.containsKey(newId) != null){
932 newValToMap = (String)bpNew.get(newId).Name;
933 }
934 }else{
935 newValToMap = 'null';
936 }
937
938 if(oldId != null){
939 Map<Id,Billing_Profile__c> bpOld = new Map<Id, Billing_Profile__c>([SELECT Name,Id FROM Billing_Profile__c WHERE Id = :oldId]);
940 if(bpOld.containsKey(oldId) != null){
941 oldValToMap = (String)bpOld.get(oldId).Name;
942 }
943 }else{
944 oldValToMap = 'null';
945 }
946
947 oldValueNewValue.put(newValToMap,oldValToMap);
948 fields.put(key, oldValueNewValue);
949 }
950 return fields;
951 }
952 public static String returnDetailsFromMap(Map<String,Map<String,String>> fields){
953 String modDetailsAfterMapping = '';
954
955 for(String outerKey : fields.keySet()){
956 for(String innerKey : fields.get(outerKey).keySet()){
957 modDetailsAfterMapping += outerKey + ':' + innerKey + '=>' + fields.get(outerKey).get(innerKey) + '\r\n';
958 }
959 }
960 return modDetailsAfterMapping;
961 }
962 public static void lockSsmFields(Sold_Service_Modification__c newSsm, Sold_Service_Modification__c oldSsm) {
963 Schema.DescribeSObjectResult ssmobj = Schema.getGlobalDescribe().get('Sold_Service_Modification__c').getDescribe();
964 Map<String, Schema.SObjectField> ssmschemaFieldMap = ssmobj.fields.getMap();
965 for(String fieldName : ssmschemaFieldMap.keySet()) {
966 if((!ApplicationConstant.SOLDSERVICEMOD_UNLOCK_FIELDS.contains(fieldName) &&
967 ((newSsm.TECH_Financial_Update__c && !ApplicationConstant.SOLDSERVICEMOD_UNLOCK_FINANCIALS_FIELDS.contains(fieldName)) || !newSsm.TECH_Financial_Update__c))
968 && newSsm.get(fieldName) != null && newSsm.get(fieldName) != oldSsm.get(fieldName)) {
969 try{
970 newSsm.addError('This field is locked and cannot be changed: ' + fieldName);
971 } catch (Exception ex){
972 System.debug('This field was locked and cannot be changed, but transaction is not corrupted');
973 }
974 }
975 }
976 }
977
978 public static void attachSStoOM(Map<Id, Sold_Service_Modification__c> rfsSSM) {
979 Map<Id, Id> ssm2ss = new Map<Id, Id>();
980 for(Id key : rfsSSM.keySet()){
981 if(rfsSSM.get(key).Sold_Service__c != null){
982 ssm2ss.put(key, rfsSSM.get(key).Sold_Service__c);
983 }
984 }
985 List<OM_External_Order__c> orderList = new List<OM_External_Order__c>();
986 for (OM_External_Order__c omex : [SELECT Sold_Service__c, Sold_Service_Modification__c FROM OM_External_Order__c WHERE Sold_Service_Modification__c IN: ssm2ss.keyset() ]) {
987 omex.Sold_Service__c = ssm2ss.get(omex.Sold_Service_Modification__c);
988 orderList.add(omex);
989 }
990 if (!orderList.isEmpty()){
991 update orderList;
992 }
993 }
994
995 /***************************************************************************************
996 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
997 Date 2017-09-03
998 Function Method used for updating Stage of SSM based on Configuration
999 (Delivery Administration -> Configure Status Automation)
1000 ****************************************************************************************/
1001 public static void runStageAutomation(Set<Id> inputSsmIdSet) {
1002 CPQ_Utils04_RequestStateCls.setOn('STAGE_AUTOMATION_STOP');
1003 List<Sold_Service_Modification__c> ssmToUpdateList = new List<Sold_Service_Modification__c>();
1004 List<Delivery_Steps__c> dsConfigList = getStatusAutomationConfiguration();
1005 Map<Id, Sold_Service_Modification__c> parentSsmMap = getSsmInfo(inputSsmIdSet);
1006 Map<Id, List<String>> ssmToNboWoStatusMap = new Map<Id, List<String>>();
1007 Map<Id, List<String>> ssmToTpsWoStatusMap = new Map<Id, List<String>>();
1008 Map<Id, Map<String, String>> ssmToWoGroupMinStatusMap = getConnectedWoMinGroupStatuses(parentSsmMap, ssmToNboWoStatusMap, ssmToTpsWoStatusMap);
1009 for (Id key : parentSsmMap.keySet()) {
1010 Sold_Service_Modification__c ssmRecord = parentSsmMap.get(key);
1011
1012 for (Delivery_Steps__c ds : dsConfigList) {
1013 if(ds.Action__c != null && ds.Action__c != ''){
1014 Set<String> actionSet = convertMPLtoApexSet(ds.Action__c);
1015 if (ds.Action__c != null && ssmRecord.Action__c != null && actionSet.contains(ssmRecord.Action__c)
1016 && ssmToWoGroupMinStatusMap.get(key) != null
1017 && areRequiredWoInFinalStage(ssmToWoGroupMinStatusMap.get(key), ds.Work_Order_Type__c, ds.Required_Work_Order_Type__c)
1018 && areNboTpsInRequiredStage(ssmToTpsWoStatusMap.get(key), ds.Consider_Connected_TPS_Status__c, ds.Minimum_TPS_Status__c)
1019 && areNboTpsInRequiredStage(ssmToNboWoStatusMap.get(key), ds.Consider_Connected_NBO_Status__c, ds.Minimum_NBO_Status__c)) {
1020 if (ssmRecord.Stage__c != ds.TECH_SSM_Stage__c || !CPQ_Utils04_RequestStateCls.isOn('MODIFICATION')) {
1021 ssmRecord.Stage__c = ds.TECH_SSM_Stage__c;
1022 ssmToUpdateList.add(new Sold_Service_Modification__c(Id = ssmRecord.ID, Stage__c = ds.TECH_SSM_Stage__c, CRM_Parent_Sold_Service_Modification__c = ssmRecord.CRM_Parent_Sold_Service_Modification__c));
1023 }
1024 break;
1025 }
1026 }
1027 }
1028 }
1029
1030 if (!ssmToUpdateList.isEmpty()){
1031 /**
1032 ** MIPAS [TSIC-1481] SS is not changing to Live Service when SSM Tech Change changes to 30.
1033 ** If 500 fails, check those flags
1034 **/
1035 if(!CPQ_Utils04_RequestStateCls.isOn('WORK_ORDER_CUSTOM_ASSIGNMENT_RULE')) {
1036 CPQ_Utils04_RequestStateCls.setOff('SOLD_SERVICE_SYNCED');
1037 CPQ_Utils04_RequestStateCls.setOff('MODIFICATION');
1038 } else {
1039 CPQ_Utils04_RequestStateCls.setOn('ORCHESTRATOR');
1040 }
1041
1042 update ssmToUpdateList;
1043 CPQ_Utils04_RequestStateCls.setOn('SOLD_SERVICE_SYNCED');
1044 CPQ_Utils04_RequestStateCls.setOn('MODIFICATION');
1045 Set<Id> ssmIDs = new Set<Id>();
1046 for(Sold_Service_Modification__c ssm : ssmToUpdateList){
1047 ssmIDs.add(ssm.Id);
1048 if(ssm.CRM_Parent_Sold_Service_Modification__c != null){
1049 ssmIDs.add(ssm.CRM_Parent_Sold_Service_Modification__c);
1050 }
1051 }
1052
1053 CPQ_Utils04_RequestStateCls.setOn('ORCHESTRATOR');
1054 CPQ_SSM10_ModificationHlprCls.updateSSMRecords(ssmIDs);
1055 }
1056
1057 }
1058
1059 /***************************************************************************************
1060 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1061 Date 2017-09-03
1062 Function Method used to check if connected to SSM work orders of type NBO fulfill
1063 the requirements from Stage Automation Configuration
1064 ****************************************************************************************/
1065 public static Boolean areNboTpsInRequiredStage(List<String> inputNboTpsWoStatusList, Boolean inputIsNboTpsRequired, String inputAllowedNboTpsStatuses) {
1066 Boolean result = false;
1067 if (inputAllowedNboTpsStatuses == null) {
1068 result = true;
1069 } else if (inputIsNboTpsRequired != true && (inputNboTpsWoStatusList == null || inputNboTpsWoStatusList.isEmpty()) ) {
1070 result = true;
1071 } else if (inputNboTpsWoStatusList != null && !inputNboTpsWoStatusList.isEmpty() && inputAllowedNboTpsStatuses != null) {
1072 result = true;
1073 Set<String> allowedNboStatusSet = convertMPLtoApexSet(inputAllowedNboTpsStatuses);
1074 if (!allowedNboStatusSet.containsAll(inputNboTpsWoStatusList)) {
1075 result = false;
1076 }
1077 }
1078 return result;
1079 }
1080
1081 /***************************************************************************************
1082 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1083 Date 2017-09-03
1084 Function Method used to convert multi picklist to Set of strings
1085 ****************************************************************************************/
1086 public static Set<String> convertMPLtoApexSet(String multiPickList) {
1087 Set<String> mplValuesSet = new Set<String>(multiPickList.split(';'));
1088 return mplValuesSet;
1089 }
1090
1091 /***************************************************************************************
1092 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1093 Date 2017-09-03
1094 Function Method used to check if different type of work orders
1095 (specified in Stage Automation Configuration) are in their final stage
1096 ****************************************************************************************/
1097 public static Boolean areRequiredWoInFinalStage(Map<String, String> inputWoStatusMap, String woThatNeedToBeCompleted, String inputRequiredWo) {
1098 Boolean result = true;
1099 if (woThatNeedToBeCompleted != null) {
1100 Set<String> typesOfWoToCompleteSet = convertMPLtoApexSet(woThatNeedToBeCompleted);
1101
1102 for (String woTypeName : typesOfWoToCompleteSet) {
1103 if (inputWoStatusMap.get(woTypeName) != null && !ApplicationConstant.HELPER_STATUS_COMPLETED.equalsIgnoreCase(inputWoStatusMap.get(woTypeName))) {
1104 result = false;
1105 break;
1106 } else if (inputWoStatusMap.get(woTypeName) == null && inputRequiredWo != null && inputRequiredWo.contains(woTypeName)) {
1107 result = false;
1108 break;
1109 }
1110 }
1111 }
1112 return result;
1113 }
1114
1115 /***************************************************************************************
1116 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1117 Date 2017-09-03
1118 Function Method used to find if different types of Work orders connected to given SSM
1119 are in their final stage and mark them either as 'Completed' or 'Incomplete'
1120 ****************************************************************************************/
1121 public static Map<Id, Map<String, String>> getConnectedWoMinGroupStatuses(Map<Id, Sold_Service_Modification__c> inputSsmMap, Map<Id, List<String>> inputSsmToNboWoMap, Map<Id, List<String>> inputSsmToTpsoWoMap) {
1122 Map<Id, Map<String, String>> result = new Map<Id, Map<String, String>>();
1123 for (Id key : inputSsmMap.keySet()) {
1124 for (WorkOrder wo : inputSsmMap.get(key).Work_Orders__r) {
1125 if (CPQ_Utils.recordTypeId('WorkOrder.Network_Buildout_Request') == wo.RecordTypeId) {
1126 if (inputSsmToNboWoMap.get(key) != null) {
1127 inputSsmToNboWoMap.get(key).add(wo.Status);
1128 } else {
1129 inputSsmToNboWoMap.put(key, new List<String>{wo.Status});
1130 }
1131 } else if (CPQ_Utils.recordTypeId('WorkOrder.Third_Party_Service') == wo.RecordTypeId) {
1132 if (inputSsmToTpsoWoMap.get(key) != null) {
1133 inputSsmToTpsoWoMap.get(key).add(wo.Status);
1134 } else {
1135 inputSsmToTpsoWoMap.put(key, new List<String>{wo.Status});
1136 }
1137 }
1138
1139 if (result.get(key) != null) {
1140 if (result.get(key).get(wo.Type__c) != null) {
1141 if (!CPQ_WOR50_DefaultTH.woGroupStatusClosed.contains(wo.StatusCategory)
1142 && ApplicationConstant.HELPER_STATUS_COMPLETED.equalsIgnoreCase(result.get(key).get(wo.Type__c))) {
1143 result.get(key).put(wo.Type__c, ApplicationConstant.HELPER_STATUS_INCOMPLETE);
1144 }
1145 } else {
1146 result.get(key).put(wo.Type__c, checkStatusCategoryStage(wo.StatusCategory));
1147 }
1148 } else {
1149 result.put(key, new Map<String, String>{wo.Type__c => checkStatusCategoryStage(wo.StatusCategory)});
1150 }
1151 }
1152 }
1153 return result;
1154 }
1155
1156 /***************************************************************************************
1157 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1158 Date 2017-09-03
1159 Function This Method is used to tell if specified StatusCategory is one of the
1160 final statuses or not.
1161 ****************************************************************************************/
1162 public static String checkStatusCategoryStage(String inputStatusCategoryName) {
1163 if (CPQ_WOR50_DefaultTH.woGroupStatusClosed.contains(inputStatusCategoryName)) {
1164 return ApplicationConstant.HELPER_STATUS_COMPLETED;
1165 } else {
1166 return ApplicationConstant.HELPER_STATUS_INCOMPLETE;
1167 }
1168 }
1169
1170 /***************************************************************************************
1171 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1172 Date 2017-09-03
1173 Function This Method is used to gather information about SSM, connected to this SSM
1174 Work Orders and Third party Services
1175 ****************************************************************************************/
1176 public static Map<Id, Sold_Service_Modification__c> getSsmInfo(Set<Id> inputSsmIdSet) {
1177 Map<Id, Sold_Service_Modification__c> ssmMap = new Map<Id, Sold_Service_Modification__c>([
1178 SELECT Action__c, Stage__c, Item_Type__c, CRM_Parent_Sold_Service_Modification__c, (SELECT Status, StatusCategory, Type__c, RecordTypeId, RecordType.Name FROM Work_Orders__r WHERE Type__c != null)
1179 FROM Sold_Service_Modification__c
1180 WHERE Id IN :inputSsmIdSet
1181 AND (Stage__c != :ApplicationConstant.SSM_STAGE_CANCELLED AND Stage__c != :ApplicationConstant.SSM_STAGE_REJECTED AND Stage__c != :ApplicationConstant.SSM_STAGE_LIVE) FOR UPDATE]);
1182
1183 return ssmMap;
1184 }
1185
1186 /***************************************************************************************
1187 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1188 Date 2017-09-03
1189 Function This Method is used to get information about Stage Automation Configuration
1190 (Accessible from GUI - Delivery Administration).
1191 ****************************************************************************************/
1192 public static List<Delivery_Steps__c> getStatusAutomationConfiguration() {
1193 final Id DS_STATUS_AUTOMATION_RT_ID = CPQ_Utils.recordTypeId('Delivery_Steps__c.Status_Automation');
1194
1195 List<Delivery_Steps__c> dsList = [
1196 SELECT Action__c, Consider_Connected_NBO_Status__c, Consider_Connected_TPS_Status__c, Minimum_NBO_Status__c, Minimum_TPS_Status__c,
1197 Required_Work_Order_Type__c, Work_Order_Type__c, TECH_SSM_Stage__c
1198 FROM Delivery_Steps__c
1199 WHERE RecordTypeId = :DS_STATUS_AUTOMATION_RT_ID
1200 ORDER BY TECH_SSM_Stage__c DESC];
1201
1202 return dsList;
1203 }
1204
1205 /***************************************************************************************
1206 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1207 Date 2017-10-09
1208 Function This Method is used to update information about connected Port on SSM.
1209 The input is map of SSMs where at least one Port lookup changed.
1210 SOQL: 1
1211 DML: 0
1212 ****************************************************************************************/
1213 public static void updateChangedPortInfoOnSSM(List<Sold_Service_Modification__c> inputSsmPortChangedList) {
1214 Set<Id> connectedPortIdSet = new Set<Id>();
1215
1216 for (Sold_Service_Modification__c ssm : inputSsmPortChangedList) {
1217 if (ssm.A_Port__c != null) connectedPortIdSet.add(ssm.A_Port__c);
1218 if (ssm.B_Port__c != null) connectedPortIdSet.add(ssm.B_Port__c);
1219 }
1220
1221 Map<Id, Port__c> connectedPortsList = new Map<Id, Port__c>([
1222 SELECT Location__c, Homing_Gateway__c, Site__c, Interface__c, Connector__c, Demarc_Type__c, Demarc_Site__c,
1223 Demarc_Comments__c, Floor__c, Room__c, Rack__c, Port_Type__c
1224 FROM Port__c
1225 WHERE Id in :connectedPortIdSet
1226 ]);
1227
1228 for (Sold_Service_Modification__c ssm : inputSsmPortChangedList) {
1229 if (ssm.A_Port__c != null) {
1230 Port__c aPort = connectedPortsList.get(ssm.A_Port__c);
1231
1232 for(String portField : CPQ_LOC01_MANAGER.PORT_A_TO_SS_FIELD_MAP.keySet()) {
1233 ssm.put(CPQ_LOC01_MANAGER.PORT_A_TO_SS_FIELD_MAP.get(portField), aPort.get(portField));
1234 }
1235 } else {
1236 for(String portField : CPQ_LOC01_MANAGER.PORT_A_TO_SS_FIELD_MAP.keySet()) {
1237 ssm.put(CPQ_LOC01_MANAGER.PORT_A_TO_SS_FIELD_MAP.get(portField), null);
1238 }
1239 }
1240 if (ssm.B_Port__c != null) {
1241 Port__c bPort = connectedPortsList.get(ssm.B_Port__c);
1242
1243 for(String portField : CPQ_LOC01_MANAGER.PORT_B_TO_SS_FIELD_MAP.keySet()) {
1244 ssm.put(CPQ_LOC01_MANAGER.PORT_B_TO_SS_FIELD_MAP.get(portField), bPort.get(portField));
1245 }
1246 } else {
1247 for(String portField : CPQ_LOC01_MANAGER.PORT_B_TO_SS_FIELD_MAP.keySet()) {
1248 ssm.put(CPQ_LOC01_MANAGER.PORT_B_TO_SS_FIELD_MAP.get(portField), null);
1249 }
1250 }
1251 }
1252 }
1253
1254 /***************************************************************************************
1255 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1256 Date 2017-10-18
1257 Function This Async Method is used to update Stage of Port Change Requests that are connected
1258 to given Sold Service Modification (wchich changed stage to 30. Complete). This is used if
1259 the context is not a batch.
1260 SOQL: 0
1261 DML: 0
1262 ****************************************************************************************/
1263 @future
1264 public static void updateChangedPortInfoOnSSMAsync(Map<Id, String> ssmToStageInputMap) {
1265 updateChangedPortInfoOnSSM(ssmToStageInputMap);
1266 }
1267
1268 /***************************************************************************************
1269 Developer Grzegorz Długosz (Enxoo) grzegorz.dlugosz@enxoo.com
1270 Date 2017-10-18
1271 Function This Method is used to update Stage of Port Change Requests that are connected
1272 to given Sold Service Modification (wchich changed stage to 30. Complete).
1273 This is used if context is a batch.
1274 SOQL: 1
1275 DML: 1
1276 ****************************************************************************************/
1277 public static void updateChangedPortInfoOnSSM(Map<Id, String> ssmToStageInputMap) {
1278 List<Port_Change_Request__c> pcrToUpdateList = new List<Port_Change_Request__c>();
1279 List<Port_Change_Request__c> pcrQuery = [
1280 SELECT Stage__c, Sold_Service_Modification__c
1281 FROM Port_Change_Request__c
1282 WHERE Sold_Service_Modification__c IN :ssmToStageInputMap.keySet()
1283 AND Stage__c != :ApplicationConstant.SSM_STAGE_LIVE
1284 FOR UPDATE
1285 ];
1286
1287 for (Port_Change_Request__c pcr : pcrQuery) {
1288 if(pcr.Stage__c != ssmToStageInputMap.get(pcr.Sold_Service_Modification__c)) {
1289 pcr.Stage__c = ssmToStageInputMap.get(pcr.Sold_Service_Modification__c);
1290 pcrToUpdateList.add(pcr);
1291 }
1292 }
1293
1294 if (!pcrToUpdateList.isEmpty()) update pcrToUpdateList;
1295 }
1296
1297 /**
1298 * @author Grzegorz Długosz - grzegorz.dlugosz@enxoo.com
1299 * @description This method is used to fill information about parent (SS) of Sold Service
1300 * that this SSM is connected to. (Parent_of_Sold_Service__c field on SSM)
1301 * @param ssmInputList - List of SSMs that might need
1302 * reference to parent of Sold Service filled.
1303 */
1304 public static void fillParentSSFieldOnSSM(List<Sold_Service_Modification__c> ssmInputList) {
1305 Set<Id> soldServiceSet = new Set<Id>();
1306
1307 for (Sold_Service_Modification__c ssm : ssmInputList) {
1308 soldServiceSet.add(ssm.Sold_Service__c);
1309 }
1310
1311 Map<Id, Sold_Service__c> parentSSMap = new Map<Id, Sold_Service__c>([
1312 SELECT CRM_Parent_Sold_Service__c
1313 FROM Sold_Service__c
1314 WHERE CRM_Parent_Sold_Service__c != null
1315 AND Id IN :soldServiceSet
1316 ]);
1317
1318 for (Sold_Service_Modification__c ssm : ssmInputList) {
1319 if (parentSSMap.get(ssm.Sold_Service__c) != null) {
1320 ssm.Parent_of_Sold_Service__c = parentSSMap.get(ssm.Sold_Service__c).CRM_Parent_Sold_Service__c;
1321 }
1322 }
1323 }
1324
1325 /***************************************************************************************
1326 Developer David Lindstrom (Enxoo) david.lindstroem@enxoo.com
1327 Date 2018-01-12
1328 Function This Method is used to rollup the OLI_Capex__c from Opportunity Line Item to
1329 SSM and SS when SSM Stage is set to '30. Modification Complete'
1330 SOQL: 1
1331 DML: 1
1332 ****************************************************************************************/
1333 public static void rollupOliCapexOnSSMandSS(Map<Id, Sold_Service_Modification__c> ssmInputMap) {
1334 Set<Id> oppLineItemIds = new Set<Id>();
1335 for (Sold_Service_Modification__c ssm : ssmInputMap.values()) {
1336 oppLineItemIds.add(ssm.OLI_Link_ID__c);
1337 }
1338
1339 Map<Id, OpportunityLineItem> oliMap = new Map<Id, OpportunityLineItem>([
1340 SELECT OLI_Capex__c
1341 FROM OpportunityLineItem
1342 WHERE Id IN :oppLineItemIds
1343 ]);
1344
1345 List<Sold_Service__c> ssToUpdate = new List<Sold_Service__c>();
1346 for(Sold_Service_Modification__c ssm : ssmInputMap.values()) {
1347 if(oliMap.containsKey(ssm.OLI_Link_ID__c)) {
1348 Double capexValue = oliMap.get(ssm.OLI_Link_ID__c).OLI_Capex__c;
1349 ssm.Service_Capex__c = capexValue;
1350
1351 if(ssm.Sold_Service__c != null) {
1352 Sold_Service__c ss = new Sold_Service__c(Id = ssm.Sold_Service__c);
1353 ss.Service_Capex__c = capexValue;
1354 ssToUpdate.add(ss);
1355 }
1356 }
1357 }
1358
1359 CPQ_Utils04_RequestStateCls.SetOn('DISABLE_RECURSIVE_SS_UPDATE');
1360 update ssToUpdate;
1361 CPQ_Utils04_RequestStateCls.SetOff('DISABLE_RECURSIVE_SS_UPDATE');
1362 }
1363
1364 /***************************************************************************************
1365 Developer David Lindstrom (Enxoo) david.lindstroem@enxoo.com
1366 Date 2019-01-04
1367 Function This Async Method is used to cancel/reject the other related Cease & Reprovide SSM
1368 when one of them are cancelled/rejected. This is used if
1369 the context is not a batch.
1370 SOQL: 1
1371 DML: 1
1372 ****************************************************************************************/
1373 @future
1374 public static void cancelRelatedCeaseAndReprovideSsmAsync(Set<Id> ssmCeaseAndReproviceIds) {
1375 Map<Id, Sold_Service_Modification__c> ssmMap =
1376 new Map<Id, Sold_Service_Modification__c>(
1377 [SELECT Id, Opp_Link__c, Action__c, Stage__c, Next_Sold_Service_Instance__c, Sold_Service__c
1378 FROM Sold_Service_Modification__c
1379 WHERE Id IN: ssmCeaseAndReproviceIds]);
1380 cancelRelatedCeaseAndReprovideSsm(ssmMap);
1381 }
1382
1383 /***************************************************************************************
1384 Developer David Lindstrom (Enxoo) david.lindstroem@enxoo.com
1385 Date 2018-12-18
1386 Function This Method is used to cancel/reject the other related Cease & Reprovide SSM
1387 when one of them are cancelled/rejected.
1388 Note: If one of the Cease & Reprovide SSMs is cancelled/rejected and the
1389 other one has already been Completed, we leave it as is and don't force it
1390 to be cancelled/rejected also.
1391 SOQL: 2
1392 DML: 2
1393 ****************************************************************************************/
1394 public static void cancelRelatedCeaseAndReprovideSsm(Map<Id, Sold_Service_Modification__c> ssmCeaseAndReproviceMap){
1395 Map<Id, Sold_Service_Modification__c> mapOppIdToSsm = new Map<Id, Sold_Service_Modification__c>();
1396 for(Sold_Service_Modification__c cancelledSsm : ssmCeaseAndReproviceMap.values()){
1397 mapOppIdToSsm.put(cancelledSsm.Opp_Link__c, cancelledSsm);
1398 }
1399
1400 Set<Id> oppIds = mapOppIdToSsm.keySet();
1401 Set<Id> cancelledOrRejectedSsm = ssmCeaseAndReproviceMap.keySet();
1402 List<Sold_Service_Modification__c> relatedCeaseAndReproviceSsm =
1403 [SELECT Id, Stage__c, Opp_Link__c, Sold_Service__c, Next_Sold_Service_Instance__c, TECH_Allow_Stage_Change__c
1404 FROM Sold_Service_Modification__c
1405 WHERE Opp_Link__c IN: oppIds
1406 AND Id NOT IN: cancelledOrRejectedSsm
1407 AND Stage__c != :ApplicationConstant.SSM_STAGE_LIVE
1408 FOR UPDATE];
1409
1410 List<Sold_Service_Modification__c> ssmToUpdate = new List<Sold_Service_Modification__c>();
1411 for(Sold_Service_Modification__c relatedSsm : relatedCeaseAndReproviceSsm){
1412 if(mapOppIdToSsm.containsKey(relatedSsm.Opp_Link__c)){
1413 Sold_Service_Modification__c cancelledSsm = mapOppIdToSsm.get(relatedSsm.Opp_Link__c);
1414
1415 if(cancelledSsm.Action__c == 'Cease' && cancelledSsm.Next_Sold_Service_Instance__c == relatedSsm.Sold_Service__c){
1416 relatedSsm.Stage__c = cancelledSsm.Stage__c;
1417 relatedSsm.TECH_Allow_Stage_Change__c = !relatedSsm.TECH_Allow_Stage_Change__c;
1418 ssmToUpdate.add(relatedSsm);
1419 }
1420 else if(cancelledSsm.Action__c == 'Reprovide' && cancelledSsm.Sold_Service__c == relatedSsm.Next_Sold_Service_Instance__c){
1421 relatedSsm.Stage__c = cancelledSsm.Stage__c;
1422 relatedSsm.TECH_Allow_Stage_Change__c = !relatedSsm.TECH_Allow_Stage_Change__c;
1423 ssmToUpdate.add(relatedSsm);
1424 }
1425 }
1426 }
1427
1428 if(!CPQ_Utils04_RequestStateCls.isOn('UPDATING_RELATED_C&R_SSM')){
1429 CPQ_Utils04_RequestStateCls.setOn('UPDATING_RELATED_C&R_SSM');
1430 try {
1431 update ssmToUpdate;
1432 }
1433 catch (Exception e) {
1434 System.debug('@@ CPQ_SSM01_Manager.cancelRelatedCeaseAndReprovideSsm exception message: ' + e.getMessage());
1435 }
1436
1437 cancelRelatedWorkOrders(ssmToUpdate);
1438 }
1439 }
1440
1441 public static void cancelRelatedWorkOrders(List<Sold_Service_Modification__c> cancelledSsmList){
1442 Set<Id> ssmIds = (new Map<Id, Sold_Service_Modification__c>(cancelledSsmList)).keySet();
1443
1444 List<WorkOrder> fetchedWorkOrders =
1445 [SELECT Id, Sold_Service_Modification__c, StatusCategory, Type__c, RecordTypeId, Record_Type_Name__c FROM WorkOrder
1446 WHERE Sold_Service_Modification__c IN: ssmIds FOR UPDATE];
1447
1448 Set<String> closedStatuses = new Set<String>{'Completed', 'Closed'};
1449 Set<String> inProgressStatusCategory = new Set<String>{'InProgress'};
1450
1451 List<WorkOrder> woToUpdate = new List<WorkOrder>();
1452 List<WorkOrder> woToInsert = new List<WorkOrder>();
1453 for(WorkOrder wo : fetchedWorkOrders){
1454 if(closedStatuses.contains(wo.StatusCategory)){
1455 WorkOrder newWo = new WorkOrder();
1456 newWo.Status = 'New';
1457 newWo.Subject = 'Cancelled: Revert Any Changes';
1458 newWo.Sold_Service_Modification__c = wo.Sold_Service_Modification__c;
1459 newWo.Type__c = wo.Type__c;
1460 if(wo.Record_Type_Name__c == 'Automated Work Order'){
1461 newWo.RecordTypeId = wo.RecordTypeId;
1462 }
1463 woToInsert.add(newWo);
1464 }
1465 else if(inProgressStatusCategory.contains(wo.StatusCategory)) {
1466 wo.Status = ApplicationConstant.WORK_ORDER_STATUS_CANCELLED;
1467 woToUpdate.add(wo);
1468 }
1469 else {
1470 // Do nothing
1471 }
1472 }
1473
1474 CPQ_Utils04_RequestStateCls.setOn('WORK_ORDER_CUSTOM_ASSIGNMENT_RULE');
1475 try {
1476 insert woToInsert;
1477 }
1478 catch(Exception e) {
1479 System.debug('@@ CPQ_SSM01_Manager.cancelRelatedCeaseAndReprovideSsm insert WorkOrder exception message: ' + e.getMessage());
1480 System.debug('@@ CPQ_SSM01_Manager.cancelRelatedCeaseAndReprovideSsm failed to insert WorkOrders: ' + woToInsert);
1481 }
1482 CPQ_Utils04_RequestStateCls.setOff('WORK_ORDER_CUSTOM_ASSIGNMENT_RULE');
1483
1484 CPQ_Utils04_RequestStateCls.setOn('WORK_ORDER_CUSTOM_ASSIGNMENT_RULE');
1485 try {
1486 update woToUpdate;
1487 }
1488 catch(Exception e) {
1489 System.debug('@@ CPQ_SSM01_Manager.cancelRelatedCeaseAndReprovideSsm update WorkOrder exception message: ' + e.getMessage());
1490 System.debug('@@ CPQ_SSM01_Manager.cancelRelatedCeaseAndReprovideSsm failed to update WorkOrders: ' + woToUpdate);
1491 }
1492 CPQ_Utils04_RequestStateCls.setOff('WORK_ORDER_CUSTOM_ASSIGNMENT_RULE');
1493 }
1494
1495 public static void checkWayOfDelivery(List<Sold_Service_Modification__c> ssmList){
1496 Set<Id> ssIdSet = gatherSSfromSSM(ssmList);
1497 Map<Id, Id> provisionedSS = findSSprovisioned(ssIdSet);
1498 if(provisionedSS.isEmpty() && !CPQ_Utils04_RequestStateCls.isOn('ISBATCH_SSM') ){
1499 checkAllAsManual(ssmList);
1500 return;
1501 }
1502 Set<String> tosSet = prepareToSSet(ssmList, provisionedSS.keySet());
1503 Map<String, String> nsoDSMap = getNSODS(tosSet);
1504 if(nsoDSMap.isEmpty()){
1505 checkAllAsManual(ssmList);
1506 } else {
1507 Map<Id, Service_Group__c> groups2update = new Map<Id, Service_Group__c>();
1508 for(Sold_Service_Modification__c ssm: ssmList){
1509 if(ssm.Type_of_Service__c == null){
1510 ssm.Manual_Work_Delivery__c = true;
1511 continue;
1512 }
1513 String key = ssm.Type_of_Service__c;
1514 if(ssm.CPQ_Component__c != null){
1515 key += '_' + ssm.CPQ_Component__c;
1516 } else if(ssm.CPQ_Product__c != null){
1517 key += '_' + ssm.CPQ_Product__c;
1518 }
1519 if(!nsoDSMap.containsKey(key) && !nsoDSMap.containsKey(ssm.Type_of_Service__c)){
1520 ssm.Manual_Work_Delivery__c = true;
1521 } else if( provisionedSS.containsKey(ssm.Sold_Service__c) && nsoDSMap.get(key).containsIgnoreCase(ssm.Action__c)){
1522 ssm.Manual_Work_Delivery__c = false;
1523 } else if( CPQ_Utils04_RequestStateCls.isOn('ISBATCH_SSM') && !provisionedSS.containsKey(ssm.Sold_Service__c) && nsoDSMap.get(key).containsIgnoreCase(ssm.Action__c) ){
1524 ssm.Manual_Work_Delivery__c = false;
1525 } else {
1526 ssm.Manual_Work_Delivery__c = true;
1527 }
1528 if(ssm.Manual_Work_Delivery__c && provisionedSS.containsKey(ssm.Sold_Service__c)){
1529 Id serviceGroupId = provisionedSS.get(ssm.Sold_Service__c);
1530 groups2update.put(serviceGroupId, new Service_Group__c(Id = serviceGroupId, NSO_Available__c = false));
1531 }
1532 }
1533 if(!groups2update.isEmpty()){
1534 database.update(groups2update.values(), false);
1535 }
1536 }
1537 }
1538
1539 private static Set<String> prepareToSSet(List<Sold_Service_Modification__c> ssmForToS, Set<Id> provisionedByGroup){
1540 Set<String> resultSet = new Set<String>();
1541 for(Sold_Service_Modification__c ssm : ssmForToS){
1542 if(ssm.Type_of_Service__c != null){
1543 if(provisionedByGroup.contains(ssm.Sold_Service__c)){
1544 resultSet.add(ssm.Type_of_Service__c);
1545 } else if( CPQ_Utils04_RequestStateCls.isOn('ISBATCH_SSM') ){
1546 resultSet.add(ssm.Type_of_Service__c);
1547 }
1548 }
1549 }
1550 return resultSet;
1551 }
1552
1553 private static Map<String, String> getNSODS(Set<String> tosSet){
1554 Map<String, String> resultMap = new Map<String, String>();
1555 for(Delivery_Steps__c ds: [SELECT Attribute_Type_of_Service__r.Name__c, Attribute_Type_of_Service__r.Exclusive_for_Product__c, Attribute_Type_of_Service__r.Exclusive_for_Component__c, Delivery_Step__r.Action__c FROM Delivery_Steps__c
1556 WHERE RecordTypeId =: CPQ_WOR20_CreatorBaseCls.DELIVERY_STEP_ATR_JUNCTION_RT AND Delivery_Step__r.Active__c = true
1557 AND Attribute_Type_of_Service__r.Name__c IN: tosSet]){
1558 String key = ds.Attribute_Type_of_Service__r.Name__c;
1559 if(ds.Attribute_Type_of_Service__r.Exclusive_for_Component__c != null){
1560 key += '_' + ds.Attribute_Type_of_Service__r.Exclusive_for_Component__c;
1561 } else if(ds.Attribute_Type_of_Service__r.Exclusive_for_Product__c != null){
1562 key += '_' + ds.Attribute_Type_of_Service__r.Exclusive_for_Product__c;
1563 }
1564 if(!resultMap.containsKey(key)){
1565 resultMap.put(key, ds.Delivery_Step__r.Action__c);
1566 } else {
1567 resultMap.put(key, resultMap.get(key) + ds.Delivery_Step__r.Action__c);
1568 }
1569 }
1570 return resultMap;
1571 }
1572
1573 private static void checkAllAsManual(List<Sold_Service_Modification__c> ssmList){
1574 for(Sold_Service_Modification__c ssm: ssmList){
1575 ssm.Manual_Work_Delivery__c = true;
1576 }
1577 }
1578 private static Set<Id> gatherSSfromSSM(List<Sold_Service_Modification__c> ssmList){
1579 Set<Id> resultSet = new Set<Id>();
1580 for(Sold_Service_Modification__c ssm : ssmList){
1581 resultSet.add(ssm.Sold_Service__c);
1582 }
1583 return resultSet;
1584 }
1585
1586 private static Map<Id, Id> findSSprovisioned(Set<Id> ssList){
1587 Map<Id, Id> resultMap = new Map<Id, Id>();
1588 for( Sold_Service__c ss : [SELECT Id, Service_Group__c FROM Sold_Service__c WHERE Id IN: ssList AND Service_Group__c != null AND Service_Group__r.NSO_Available__c = true]){
1589 resultMap.put(ss.Id, ss.Service_Group__c);
1590 }
1591 return resultMap;
1592 }
1593
1594 public static void updateConnnectedGroups(Set<Id> ssIdSet){
1595 Map<Id, Id> provisionedSS = findSSprovisioned(ssIdSet);
1596 List<Service_Group__c> groups2update = new List<Service_Group__c>();
1597 for(Id ssId : ssIdSet){
1598 groups2update.add(new Service_Group__c(Id = provisionedSS.get(ssId), NSO_Available__c = false));
1599 }
1600 if(!groups2update.isEmpty()){
1601 database.update(groups2update, false);
1602 }
1603 }
1604
1605 public static void markSSMlistWithInflightChange(List<Sold_Service_Modification__c> ssmList){
1606 List<Sold_Service_Modification__c> validetedSSM = validateSSM(ssmList);
1607 changeWOstatus(gatherConnectedWo(validetedSSM));
1608
1609 for(Sold_Service_Modification__c ssm : validetedSSM){
1610 markSSM(ssm);
1611
1612 }
1613 update validetedSSM;
1614 }
1615
1616 public static List<Sold_Service_Modification__c> validateSSM(List<Sold_Service_Modification__c> ssmList){
1617 List<Sold_Service_Modification__c> validatedSsmList = new List<Sold_Service_Modification__c>();
1618 for(Sold_Service_Modification__c ssm : ssmList){
1619 if(ssm.Action__c =='Add' && (!ssm.Stage__c.contains(ApplicationConstant.SSM_STAGE_CANCELLED) || !ssm.Stage__c.contains(ApplicationConstant.SSM_STAGE_PENDING_CUST_ACCEPTANCE)
1620 || !ssm.Stage__c.contains(ApplicationConstant.SSM_STAGE_REJECTED) || !ssm.Stage__c.contains(ApplicationConstant.SSM_STAGE_LIVE))){
1621 validatedSsmList.add(ssm);
1622 }
1623 }
1624 return validatedSsmList;
1625 }
1626
1627 public static List<WorkOrder> gatherConnectedWo(List<Sold_Service_Modification__c> validatedSsmList){
1628 List<WorkOrder> connectedWO = [SELECT Id, Status, WorkOrderNumber FROM WorkOrder WHERE Sold_Service_Modification__c IN : validatedSsmList AND RecordType.DeveloperName != 'Automated_Work_Order'];
1629 return connectedWO;
1630 }
1631
1632 public static void changeWOstatus(List<WorkOrder> woList){
1633 List<WorkOrder> changedWo = new List<WorkOrder>();
1634 for (WorkOrder wo : woList){
1635 if(wo.Status == 'New' || wo.Status == 'In Progress'){
1636 wo.Previous_Status__c = wo.Status;
1637 wo.Status = 'On Hold';
1638 changedWo.add(wo);
1639 }
1640 }
1641 update changedWo;
1642 }
1643
1644 public static void markSSM(Sold_Service_Modification__c ssm){
1645 ssm.In_flight_Change_Requested__c = true;
1646 ssm.Stage__c = ApplicationConstant.SSM_STAGE_ON_HOLD;
1647 ssm.TECH_Allow_Stage_Change__c = !ssm.TECH_Allow_Stage_Change__c;
1648
1649 ssm.TECH_SSM_Snapshot__c = JSON.serialize(ssm);
1650 }
1651
1652 public static void markSSMlistWithInflightChange(Set<Id> ssmIdSet){
1653 Set<Id> validetedSsmIds = validateSSM(ssmIdSet);
1654 changeWOstatus(gatherConnectedWo(validetedSsmIds));
1655
1656 for(Id ssmId : validetedSsmIds){
1657 markSSM(ssmId);
1658
1659 }
1660 }
1661
1662 public static Set<Id> validateSSM(Set<Id> ssmIdSet){
1663 Set<String> stageList = new Set<String>{ApplicationConstant.SSM_STAGE_CANCELLED, ApplicationConstant.SSM_STAGE_PENDING_CUST_ACCEPTANCE,
1664 ApplicationConstant.SSM_STAGE_REJECTED, ApplicationConstant.SSM_STAGE_LIVE};
1665
1666 List<Sold_Service_Modification__c> validatedSsmList = [SELECT Id FROM Sold_Service_Modification__c WHERE Id IN :ssmIdSet AND Action__c = 'Add' AND Stage__c NOT IN :stageList];
1667 Set<Id> validatedSsmIdSet = (new Map<Id,Sold_Service_Modification__c>(validatedSsmList)).keySet();
1668 return validatedSsmIdSet;
1669 }
1670
1671 public static List<WorkOrder> gatherConnectedWo(Set<Id> validatedSsmIdSet){
1672 List<WorkOrder> connectedWO = [SELECT Id, Status, WorkOrderNumber FROM WorkOrder WHERE Sold_Service_Modification__c IN : validatedSsmIdSet AND RecordType.DeveloperName != 'Automated_Work_Order'];
1673 return connectedWO;
1674 }
1675
1676 public static void markSSM(Id ssmId){
1677 Sold_Service_Modification__c ssm = new Sold_Service_Modification__c(Id = ssmId);
1678 ssm.In_flight_Change_Requested__c = true;
1679 ssm.Stage__c = ApplicationConstant.SSM_STAGE_ON_HOLD;
1680 ssm.TECH_Allow_Stage_Change__c = !ssm.TECH_Allow_Stage_Change__c;
1681
1682 ssm.TECH_SSM_Snapshot__c = JSON.serialize(ssm);
1683 }
1684
1685}