Advertisement
Guest User

Untitled

a guest
Nov 14th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 100.78 KB | None | 0 0
  1. /*
  2. Description : Manager class for Sold_Service_Modification__c object
  3. Created by : Tomasz Bogdański (tomasz.bogdanski@enxoo.com)
  4. Date created : 2016-03-14
  5. ************************************************************************/
  6. public 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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement