Adds rule-based filtering for cloned records
Implements a mechanism to exclude child records from being cloned based on configurable formulas. Introduces a Custom Metadata object to define exclusion rules, allowing administrators to specify formulas for different SObjects. Updates the cloning service to evaluate these formulas and filter out records that meet the exclusion criteria.
This commit is contained in:
1 parent
81b24f298b
commit
f34a61e653
67 files changed
+112
-11
No files matched your search
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
xœ•ÎM
|
||||
1@a×=E. $ý› ˆwiÒTG:ðø‚k7îßO·u]xJ§ÑÍ@U'A�FVÓ,F)rõFÄRdÏRÝ«t{�PRN*…ªÏI*Kh„1ÔÙ7d6%öJ®ã¾uØ[}þ]␍F/úXž7¸\�¦˜|8g8cDtúöq¿J÷ŽFDé
|
||||
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
xœ•ÎÁ
|
||||
!€áÎ>ż@ ŽŽ
|
||||
Ñ»ŒãXKl®=~йK÷ÿƒ_¶u]&xOs¨btI3Jò•Äybn¡&ÌͲ”–Ù:6/úœÐHë5”Ø]ÊDEmeÌèÑ1§–¼¯I«ácÞ·{ooØ·cˆÂ,�åyƒË\
|
||||
ÑStálƒµF¾cSÿ æWi>¯ÑCÓ
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
xœ•ÎA
|
||||
1@Q×=E. ¤m&mA¼Kš¦:È8R+x|Áµ÷ÿÁ×}ÛÖ Á/‡9Ì ‹Ï‚¹ùŠÑ—ÆJ�¬´Ð‰c‰•b"²{Ȱû„Ê5ÕØXsW$žf.Ü’ZÓÜ¥5qòš×}À³·7<÷×Pƒ9Doëý§3øDKàÄK�#¢ÓïØ´?ˆûUº©ID
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
xś•ÎA
|
||||
Â0@Q×9Ĺ\@H2“¦ń.“ÉŚ©•4Ź/¸văţ?ř˛ë2 †t]Ě(Ô2U¬1Ńdł™I#VMy´2×,d-¸w}`m%cDÎč˝z±9N¨)zndą”ăľuŘ˝aߎ.
|
||||
Łł<–ç␍.W™R$*>ĂŮ“÷NľcC˙ îWé>~
|
||||
DŰ
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
xœ•ÎA
|
||||
Â0@Q×9Å\@H&3ɤwI§S-ÒVÒ<¾àÚ�ûÿàë¾®K|éÍb¦¬X“Äb¹VC?&Ï%Î�¢”0fBq¯Úlë 9 ià4'"1bŸ-)F?&RŽšeWÏþØóô†c?›ôVõ¹lw¸␍21’`a¸zòÞéw¬ÛÄý*ÝlÜAÝ
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
xœ•ÎM
|
||||
1@a×=E. ¤iâ]Ú4ÕAÆ‘N<¾àÚ�û÷Á“m]— ÎÆÓªÀ=&ÌVPkL܈(‡Œ wßšRwÜ,b2¯2ô9»‹…‹PMÔ’cñY{.9‡V) ±·,Õ”cÞ·{ooØ·cˆÂEËó—+Ø¢£ˆäáŒÑÈwlêÄü*ÍUCK
|
||||
+1
@@ -0,0 +1 @@
|
||||
x°+)JMU06d01000PхMллcх*][И╥╗Ё╜NИмcmУWsYУv/
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1 +1 @@
|
||||
aedb3c7323a730a30e0cf8263e520ad4fe2a9912
|
||||
3f635a585a79811712905e7ed8bacd891fb2dbd1
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"fileVersion": 0,
|
||||
"serverMaxRevisionCounter": 104,
|
||||
"serverMaxRevisionCounter": 125,
|
||||
"sourceMembers": {
|
||||
"ReportFolder__prm_channel_reports_folder": {
|
||||
"memberType": "ReportFolder",
|
||||
@@ -196,20 +196,20 @@
|
||||
},
|
||||
"Profile__Admin": {
|
||||
"memberType": "Profile",
|
||||
"serverRevisionCounter": 97,
|
||||
"serverRevisionCounter": 124,
|
||||
"lastRetrievedFromServer": null,
|
||||
"isNameObsolete": false
|
||||
},
|
||||
"ApexClass__OpportunityCloneService": {
|
||||
"memberType": "ApexClass",
|
||||
"serverRevisionCounter": 45,
|
||||
"lastRetrievedFromServer": 45,
|
||||
"serverRevisionCounter": 115,
|
||||
"lastRetrievedFromServer": 115,
|
||||
"isNameObsolete": false
|
||||
},
|
||||
"ApexClass__OpportunityCloneServiceTest": {
|
||||
"memberType": "ApexClass",
|
||||
"serverRevisionCounter": 46,
|
||||
"lastRetrievedFromServer": 46,
|
||||
"serverRevisionCounter": 125,
|
||||
"lastRetrievedFromServer": 125,
|
||||
"isNameObsolete": false
|
||||
},
|
||||
"ApexClass__TestCloneUtility": {
|
||||
@@ -385,6 +385,24 @@
|
||||
"serverRevisionCounter": 103,
|
||||
"lastRetrievedFromServer": 103,
|
||||
"isNameObsolete": false
|
||||
},
|
||||
"CustomMetadata__SmartCloneRecordExclusionRule.LineItemPriceBelowFiftyDollars": {
|
||||
"memberType": "CustomMetadata",
|
||||
"serverRevisionCounter": 112,
|
||||
"lastRetrievedFromServer": null,
|
||||
"isNameObsolete": true
|
||||
},
|
||||
"CustomMetadata__SmartCloneRecordExclusionRule.QuantityLessThanTwo": {
|
||||
"memberType": "CustomMetadata",
|
||||
"serverRevisionCounter": 116,
|
||||
"lastRetrievedFromServer": 116,
|
||||
"isNameObsolete": false
|
||||
},
|
||||
"StaticResource__SmartClone_TestData": {
|
||||
"memberType": "StaticResource",
|
||||
"serverRevisionCounter": 117,
|
||||
"lastRetrievedFromServer": 117,
|
||||
"isNameObsolete": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ public with sharing class OpportunityCloneService {
|
||||
* @description Map of Child relationship objects to the opportunity.
|
||||
*/
|
||||
public static Map<String,Schema.DescribeSObjectResult> opportunityChildrenMap;
|
||||
public static Map<String,SmartCloneRecordExclusionRule__mdt> exclusionRuleMap;
|
||||
public static Map<String,List<FormulaEval.FormulaInstance>> formulaInstanceBySObjectMap;
|
||||
/**
|
||||
* @description static constructor that will populate the opportunityChildrenMap
|
||||
*/
|
||||
@@ -43,6 +45,24 @@ public with sharing class OpportunityCloneService {
|
||||
}
|
||||
}
|
||||
}
|
||||
exclusionRuleMap = new Map<String,SmartCloneRecordExclusionRule__mdt>();
|
||||
formulaInstanceBySObjectMap = new Map<String,List<FormulaEval.FormulaInstance>>();
|
||||
Map<String,Schema.SObjectType> sObjectTypeMap = Schema.getGlobalDescribe();
|
||||
for(SmartCloneRecordExclusionRule__mdt rule:SmartCloneRecordExclusionRule__mdt.getAll().values()){
|
||||
if(rule.IsActive__c && String.isNotBlank(rule.ExclusionFormula__c)){
|
||||
exclusionRuleMap.put(rule.DeveloperName,rule);
|
||||
String sObjectName = rule.RelatedObject__c;
|
||||
FormulaEval.FormulaInstance fInstance = Formula.builder().withType(sObjectTypeMap.get(sObjectName.toLowerCase()))
|
||||
.withReturnType(FormulaEval.FormulaReturnType.Boolean)
|
||||
.withFormula(rule.ExclusionFormula__c).build();
|
||||
List<FormulaEval.FormulaInstance> fInstanceList = formulaInstanceBySObjectMap.get(sObjectName);
|
||||
if(fInstanceList == null){
|
||||
fInstanceList = new List<FormulaEval.FormulaInstance>();
|
||||
}
|
||||
fInstanceList.add(fInstance);
|
||||
formulaInstanceBySObjectMap.put(sObjectName,fInstanceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description Lightning Exposed method that will provide a map of Child relationships
|
||||
@@ -185,17 +205,31 @@ public with sharing class OpportunityCloneService {
|
||||
}
|
||||
|
||||
private static List<SObject> CloneAndReassociateRecords(List<SObject> recList, String parentFieldName, Id newParentId) {
|
||||
System.debug(LoggingLevel.INFO,'\n\nOpportunityCloneService.CloneAndReassociateRecords Executing.\n\n ');
|
||||
List<SObject> newList = new List<sObject>();
|
||||
for(SObject rec:recList){
|
||||
SObject newRec = rec.clone(false,true,false,false);
|
||||
newRec.put(parentFieldName, newParentId);
|
||||
/**
|
||||
if(newRec.getSObjectType().getDescribe().getName().toUpperCase() == 'OPPORTUNITYLINEITEM') {
|
||||
String sObjectName = newRec.getSObjectType().getDescribe().getName();
|
||||
if(sObjectName.toUpperCase() == 'OPPORTUNITYLINEITEM') {
|
||||
newRec.put('UnitPrice',null);
|
||||
}
|
||||
*/
|
||||
//TODO: This is where we can evaluate the record to determine if it meets the formula criteria being included
|
||||
// as a child record.
|
||||
Boolean fResult = false;
|
||||
if(formulaInstanceBySObjectMap.containsKey(sObjectName)){
|
||||
List<FormulaEval.FormulaInstance> fInstanceList = formulaInstanceBySObjectMap.get(sObjectName);
|
||||
for(FormulaEval.FormulaInstance fInstance:fInstanceList){
|
||||
fResult = (Boolean)fInstance.evaluate(newRec);
|
||||
if(fResult) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!fResult) {
|
||||
newList.add(newRec);
|
||||
}
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ private class OpportunityCloneServiceTest {
|
||||
}
|
||||
}
|
||||
insert oliTestLines;
|
||||
testFutureMethod();
|
||||
}
|
||||
|
||||
@isTest
|
||||
@@ -106,10 +107,11 @@ private class OpportunityCloneServiceTest {
|
||||
}
|
||||
@isTest
|
||||
static void CloneOpportunityWithChildren(){
|
||||
Test.startTest();
|
||||
Opportunity testOpp = [SELECT Id, Name FROM Opportunity LIMIT 1];
|
||||
Map<String,String> testReplacements = new Map<String,String>();
|
||||
testReplacements.put('Name',TestCloneUtility.GenerateRandomString(10));
|
||||
Test.startTest();
|
||||
|
||||
|
||||
Id testResult = OpportunityCloneService.CloneOpportunityWithChildren(testOpp.Id, testReplacements,
|
||||
new List<String>{'OpportunityLineItems'});
|
||||
@@ -117,4 +119,9 @@ private class OpportunityCloneServiceTest {
|
||||
|
||||
Test.stopTest();
|
||||
}
|
||||
@future
|
||||
public static void testFutureMethod(){
|
||||
//insert some Exlusion rules
|
||||
Test.loadData(SmartCloneRecordExclusionRule__mdt.SObjectType, 'SmartClone_TestData');
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomMetadata xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<label>QuantityLessThanTwo</label>
|
||||
<protected>false</protected>
|
||||
<values>
|
||||
<field>ExclusionFormula__c</field>
|
||||
<value xsi:type="xsd:string">Quantity < 2</value>
|
||||
</values>
|
||||
<values>
|
||||
<field>IsActive__c</field>
|
||||
<value xsi:type="xsd:boolean">false</value>
|
||||
</values>
|
||||
<values>
|
||||
<field>RelatedObject__c</field>
|
||||
<value xsi:type="xsd:string">OpportunityLineItem</value>
|
||||
</values>
|
||||
</CustomMetadata>
|
||||
@@ -0,0 +1,2 @@
|
||||
DeveloperName,MasterLabel,IsActive__c,RelatedObject__c,ExclusionFormula__c
|
||||
QuantityLessThanThree,QuantityLessThanThree,TRUE,OpportunityLineItem,Quantity < 3
|
||||
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<cacheControl>Public</cacheControl>
|
||||
<contentType>text/csv</contentType>
|
||||
<description>Test Data for SmartClone Code Coverage.</description>
|
||||
</StaticResource>
|
||||
Reference in new issue
Block a user