diff --git a/README.md b/README.md
index 598d819c..fb0ae9bb 100644
--- a/README.md
+++ b/README.md
@@ -24,12 +24,12 @@ As well, don't miss [the Wiki](../../wiki), which includes even more info for co
## Deployment & Setup
-
+
-
+
diff --git a/extra-tests/classes/RollupCalcItemReplacerTests.cls b/extra-tests/classes/RollupCalcItemReplacerTests.cls
index 5a8a1def..bc285860 100644
--- a/extra-tests/classes/RollupCalcItemReplacerTests.cls
+++ b/extra-tests/classes/RollupCalcItemReplacerTests.cls
@@ -162,4 +162,19 @@ private class RollupCalcItemReplacerTests {
System.assertNotEquals(null, updatedContact);
}
+
+ @IsTest
+ static void worksWithParantheticalNotClauses() {
+ Account acc = [SELECT Id FROM Account];
+
+ RollupCalcItemReplacer replacer = new RollupCalcItemReplacer(
+ new RollupControl__mdt(IsRollupLoggingEnabled__c = true, ReplaceCalcItemsAsyncWhenOverCount__c = 2)
+ );
+ acc = (Account) replacer.replace(
+ new List{ acc, acc },
+ new List{ new Rollup__mdt(CalcItemWhereClause__c = 'NOT(AnnualRevenue != 0 AND Name != null)', CalcItem__c = 'Account') }
+ )[0];
+
+ System.assertEquals(ACC_ANNUAL_REVENUE, acc.AnnualRevenue);
+ }
}
diff --git a/extra-tests/classes/RollupFlowBulkProcessorTests.cls b/extra-tests/classes/RollupFlowBulkProcessorTests.cls
index 7c2e59e3..f624ccb0 100644
--- a/extra-tests/classes/RollupFlowBulkProcessorTests.cls
+++ b/extra-tests/classes/RollupFlowBulkProcessorTests.cls
@@ -14,16 +14,34 @@ private class RollupFlowBulkProcessorTests {
System.assertEquals('No records', outputs[0].message);
}
- private class CachedRollup extends Rollup {
- public List getCurrentlyCachedRollups() {
- return this.getCachedRollups();
- }
+ @IsTest
+ static void skipsAddingRollupForNoOps() {
+ RollupFlowBulkProcessor.FlowInput input = new RollupFlowBulkProcessor.FlowInput();
+ // this contact should be filtered out due to not having an AccountId filled out
+ input.recordsToRollup = new List{ new Contact() };
+ input.rollupContext = 'INSERT';
+
+ Rollup.rollupMetadata = new List{
+ new Rollup__mdt(
+ RollupOperation__c = 'CONCAT',
+ CalcItem__c = 'Contact',
+ LookupObject__c = 'Account',
+ RollupFieldOnCalcItem__c = 'FirstName',
+ LookupFieldOnCalcItem__c = 'AccountId',
+ LookupFieldOnLookupObject__c = 'Id',
+ RollupFieldOnLookupObject__c = 'Name'
+ )
+ };
+
+ RollupFlowBulkProcessor.addRollup(new List{ input });
+
+ System.assertEquals(true, Rollup.CACHED_ROLLUPS.isEmpty());
}
@IsTest
static void shouldAddToRollupsIfCMDTPresent() {
RollupFlowBulkProcessor.FlowInput input = new RollupFlowBulkProcessor.FlowInput();
- input.recordsToRollup = new List{ new Contact() };
+ input.recordsToRollup = new List{ new Contact(AccountId = RollupTestUtils.createId(Account.SObjectType)) };
input.rollupContext = 'INSERT';
Rollup.rollupMetadata = new List{
@@ -44,7 +62,7 @@ private class RollupFlowBulkProcessorTests {
for (Rollup.FlowOutput output : outputs) {
System.assertEquals(true, outputs[0].isSuccess, 'Should not error when adding deferred flow rollup');
}
- System.assertNotEquals(true, new CachedRollup().getCurrentlyCachedRollups().isEmpty(), 'Deferred rollup should be kept in buffer');
+ System.assertNotEquals(true, Rollup.CACHED_ROLLUPS.isEmpty(), 'Deferred rollup should be kept in buffer');
}
@IsTest
@@ -82,7 +100,7 @@ private class RollupFlowBulkProcessorTests {
RollupFlowBulkProcessor.addRollup(new List{ input });
Test.stopTest();
- System.assertEquals(1, new CachedRollup().getCurrentlyCachedRollups().size());
+ System.assertEquals(1, Rollup.CACHED_ROLLUPS.size());
}
@IsTest
@@ -196,7 +214,7 @@ private class RollupFlowBulkProcessorTests {
acc = [SELECT AnnualRevenue FROM Account WHERE Id = :acc.Id];
System.assertEquals(5, acc.AnnualRevenue);
- System.assertEquals(0, new CachedRollup().getCurrentlyCachedRollups().size(), 'Flow rollup buffer should have been flushed!');
+ System.assertEquals(0, Rollup.CACHED_ROLLUPS.size(), 'Flow rollup buffer should have been flushed!');
}
@IsTest
diff --git a/extra-tests/classes/RollupFlowFullRecalcTests.cls b/extra-tests/classes/RollupFlowFullRecalcTests.cls
index bf1f3682..2e9e80fd 100644
--- a/extra-tests/classes/RollupFlowFullRecalcTests.cls
+++ b/extra-tests/classes/RollupFlowFullRecalcTests.cls
@@ -376,7 +376,7 @@ private class RollupFlowFullRecalcTests {
@IsTest
static void shouldRefreshMultipleBatchFullRecalcs() {
- Rollup.defaultControl = new RollupControl__mdt(MaxLookupRowsBeforeBatching__c = 1, IsRollupLoggingEnabled__c = true, MaxRollupRetries__c = 3);
+ Rollup.defaultControl = new RollupControl__mdt(MaxLookupRowsBeforeBatching__c = 0, IsRollupLoggingEnabled__c = true, MaxRollupRetries__c = 3);
Account acc = [SELECT Id FROM Account];
Individual secondParent = new Individual(LastName = 'Second');
insert secondParent;
@@ -525,4 +525,63 @@ private class RollupFlowFullRecalcTests {
System.assertEquals(1500, updatedAcc.AnnualRevenue, 'SUM REFRESH hierarchy from flow should fully recalc');
System.assertEquals('One, Two', updatedAcc.Name, 'CONCAT_DISTINCT REFRESH hierarchy from flow should full recalc');
}
+
+ @IsTest
+ static void shouldCorrectlyFindAdjacentChildrenForRollupsToMultipleParents() {
+ List accounts = new List{
+ new Account(Name = 'Parent 1'),
+ new Account(Name = 'Parent 2'),
+ new Account(Name = 'Parent 3'),
+ new Account(Name = 'Parent 4')
+ };
+ insert accounts;
+ Individual bParentOne = new Individual(LastName = 'B1', ConsumerCreditScore = 3, ConvictionsCount = 2);
+ Individual bParentTwo = new Individual(LastName = 'B2', ConsumerCreditScore = 7, ConvictionsCount = 2);
+ insert new List{ bParentOne, bParentTwo };
+ List childrenToInsert = new List{
+ new ContactPointAddress(PreferenceRank = 1, ParentId = accounts[0].Id, Name = bParentOne.Id),
+ new ContactPointAddress(PreferenceRank = 2, ParentId = accounts[1].Id, Name = bParentOne.Id),
+ new ContactPointAddress(PreferenceRank = 3, ParentId = accounts[2].Id, Name = bParentTwo.Id),
+ new ContactPointAddress(PreferenceRank = 4, ParentId = accounts[3].Id, Name = bParentTwo.Id)
+ };
+ insert childrenToInsert;
+
+ List cpas = new List{ childrenToInsert[0], childrenToInsert[2] };
+
+ Rollup.FlowInput firstInput = RollupTestUtils.prepareFlowTest(cpas, 'REFRESH', 'SUM')[0];
+ firstInput.deferProcessing = true;
+ Rollup.FlowInput secondInput = firstInput.clone();
+ secondInput.lookupFieldOnCalcItem = 'Name';
+ secondInput.rollupSObjectName = 'Individual';
+ secondInput.rollupFieldOnOpObject = 'ConsumerCreditScore';
+ Rollup.FlowInput thirdInput = secondInput.clone();
+ thirdInput.calcItemWhereClause = 'PreferenceRank > 0';
+ thirdInput.rollupFieldOnOpObject = 'ConvictionsCount';
+ thirdInput.rollupOperation = 'COUNT';
+ Rollup.FlowInput fourthInput = secondInput.clone();
+ fourthInput.rollupSObjectName = 'Task';
+ fourthInput.rollupFieldOnOpObject = 'CallDurationInSeconds';
+ fourthInput.calcItemWhereClause = '(NOT Name LIKE \'' + bParentOne.Id.toString().substring(0, 3) + '%\')';
+
+ Test.startTest();
+ Rollup.performRollup(new List{ firstInput, secondInput, thirdInput, fourthInput });
+ Rollup.processStoredFlowRollups();
+ Test.stopTest();
+
+ Map accountToExpectedAmount = new Map{
+ accounts[0].Id => childrenToInsert[0].PreferenceRank,
+ accounts[1].Id => childrenToInsert[1].PreferenceRank,
+ accounts[2].Id => childrenToInsert[2].PreferenceRank,
+ accounts[3].Id => childrenToInsert[3].PreferenceRank
+ };
+ for (Account updatedAcc : [SELECT Id, Name, AnnualRevenue FROM Account WHERE Id = :accounts]) {
+ System.assertEquals(accountToExpectedAmount.get(updatedAcc.Id), updatedAcc.AnnualRevenue, updatedAcc);
+ }
+ bParentOne = [SELECT Id, ConsumerCreditScore, ConvictionsCount FROM Individual WHERE Id = :bParentOne.Id];
+ System.assertEquals(3, bParentOne.ConsumerCreditScore);
+ System.assertEquals(2, bParentOne.ConvictionsCount);
+ bParentTwo = [SELECT Id, ConsumerCreditScore, ConvictionsCount FROM Individual WHERE Id = :bParentTwo.Id];
+ System.assertEquals(7, bParentTwo.ConsumerCreditScore);
+ System.assertEquals(2, bParentTwo.ConvictionsCount);
+ }
}
diff --git a/extra-tests/classes/RollupFlowTests.cls b/extra-tests/classes/RollupFlowTests.cls
index 7809cbb9..179de402 100644
--- a/extra-tests/classes/RollupFlowTests.cls
+++ b/extra-tests/classes/RollupFlowTests.cls
@@ -1064,4 +1064,64 @@ private class RollupFlowTests {
Account updatedAcc = [SELECT Id, AnnualRevenue FROM Account WHERE Id = :acc.Id];
System.assertEquals(null, updatedAcc.AnnualRevenue);
}
+
+ @IsTest
+ static void shouldCorrectlyDecrementOnRollupsToMultipleParentsDelete() {
+ List accounts = new List{
+ new Account(Name = 'Parent 1', AnnualRevenue = 1),
+ new Account(Name = 'Parent 2', AnnualRevenue = 2),
+ new Account(Name = 'Parent 3', AnnualRevenue = 3),
+ new Account(Name = 'Parent 4', AnnualRevenue = 4)
+ };
+ insert accounts;
+ Individual bParentOne = new Individual(LastName = 'B1', ConsumerCreditScore = 3, ConvictionsCount = 2);
+ Individual bParentTwo = new Individual(LastName = 'B2', ConsumerCreditScore = 7, ConvictionsCount = 2);
+ insert new List{ bParentOne, bParentTwo };
+ List childrenToInsert = new List{
+ new ContactPointAddress(PreferenceRank = accounts[0].AnnualRevenue.intValue(), ParentId = accounts[0].Id, Name = bParentOne.Id),
+ new ContactPointAddress(PreferenceRank = accounts[1].AnnualRevenue.intValue(), ParentId = accounts[1].Id, Name = bParentOne.Id),
+ new ContactPointAddress(PreferenceRank = accounts[2].AnnualRevenue.intValue(), ParentId = accounts[2].Id, Name = bParentTwo.Id),
+ new ContactPointAddress(PreferenceRank = accounts[3].AnnualRevenue.intValue(), ParentId = accounts[3].Id, Name = bParentTwo.Id)
+ };
+ insert childrenToInsert;
+
+ List cpas = new List{ childrenToInsert[0], childrenToInsert[2] };
+
+ Rollup.FlowInput firstInput = RollupTestUtils.prepareFlowTest(cpas, 'DELETE', 'SUM')[0];
+ firstInput.deferProcessing = true;
+ Rollup.FlowInput secondInput = firstInput.clone();
+ secondInput.lookupFieldOnCalcItem = 'Name';
+ secondInput.rollupSObjectName = 'Individual';
+ secondInput.rollupFieldOnOpObject = 'ConsumerCreditScore';
+ Rollup.FlowInput thirdInput = secondInput.clone();
+ thirdInput.calcItemWhereClause = 'PreferenceRank > 0';
+ thirdInput.rollupFieldOnOpObject = 'ConvictionsCount';
+ thirdInput.rollupOperation = 'COUNT';
+ Rollup.FlowInput fourthInput = secondInput.clone();
+ fourthInput.rollupSObjectName = 'Task';
+ fourthInput.rollupFieldOnOpObject = 'CallDurationInSeconds';
+ fourthInput.calcItemWhereClause = '(NOT Name LIKE \'' + bParentOne.Id.toString().substring(0, 3) + '%\')';
+
+ Test.startTest();
+ Rollup.performRollup(new List{ firstInput, secondInput, thirdInput, fourthInput });
+ System.assertEquals(3, Rollup.CACHED_ROLLUPS.size());
+ Rollup.processStoredFlowRollups();
+ Test.stopTest();
+
+ Map accountToExpectedAmount = new Map{
+ accounts[0].Id => null,
+ accounts[1].Id => accounts[1].AnnualRevenue,
+ accounts[2].Id => null,
+ accounts[3].Id => accounts[3].AnnualRevenue
+ };
+ for (Account updatedAcc : [SELECT Id, Name, AnnualRevenue FROM Account WHERE Id = :accounts]) {
+ System.assertEquals(accountToExpectedAmount.get(updatedAcc.Id), updatedAcc.AnnualRevenue, updatedAcc);
+ }
+ bParentOne = [SELECT Id, ConsumerCreditScore, ConvictionsCount FROM Individual WHERE Id = :bParentOne.Id];
+ System.assertEquals(2, bParentOne.ConsumerCreditScore);
+ System.assertEquals(1, bParentOne.ConvictionsCount);
+ bParentTwo = [SELECT Id, ConsumerCreditScore, ConvictionsCount FROM Individual WHERE Id = :bParentTwo.Id];
+ System.assertEquals(4, bParentTwo.ConsumerCreditScore);
+ System.assertEquals(1, bParentTwo.ConvictionsCount);
+ }
}
diff --git a/extra-tests/classes/RollupFullRecalcTests.cls b/extra-tests/classes/RollupFullRecalcTests.cls
index 67e7f3d4..5f9f3b1b 100644
--- a/extra-tests/classes/RollupFullRecalcTests.cls
+++ b/extra-tests/classes/RollupFullRecalcTests.cls
@@ -1624,7 +1624,7 @@ private class RollupFullRecalcTests {
RollupFullBatchRecalculator fullRecalc = new RollupFullBatchRecalculator(
'SELECT Id, PreferenceRank, ParentId FROM ContactPointAddress',
- Rollup.InvocationPoint.FROM_APEX,
+ Rollup.InvocationPoint.FROM_FULL_RECALC_LWC,
new List{
new Rollup__mdt(
CalcItem__c = 'ContactPointAddress',
@@ -1664,7 +1664,7 @@ private class RollupFullRecalcTests {
RollupFullBatchRecalculator fullRecalc = new RollupFullBatchRecalculator(
'SELECT Id, PreferenceRank, ParentId FROM ContactPointAddress',
- Rollup.InvocationPoint.FROM_APEX,
+ Rollup.InvocationPoint.FROM_FULL_RECALC_LWC,
new List{
new Rollup__mdt(
CalcItem__c = 'ContactPointAddress',
diff --git a/package.json b/package.json
index 79c69171..d089689a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "apex-rollup",
- "version": "1.6.17",
+ "version": "1.6.18",
"description": "Fast, configurable, elastically scaling custom rollup solution. Apex Invocable action, one-liner Apex trigger/CMDT-driven logic, and scheduled Apex-ready.",
"repository": {
"type": "git",
diff --git a/rollup-namespaced/README.md b/rollup-namespaced/README.md
index d5a6a0c9..9405640e 100644
--- a/rollup-namespaced/README.md
+++ b/rollup-namespaced/README.md
@@ -18,12 +18,12 @@ For more info, see the base `README`.
## Deployment & Setup
-
+
-
+
diff --git a/rollup-namespaced/sfdx-project.json b/rollup-namespaced/sfdx-project.json
index 59960988..2f5f7c1a 100644
--- a/rollup-namespaced/sfdx-project.json
+++ b/rollup-namespaced/sfdx-project.json
@@ -25,6 +25,6 @@
"apex-rollup-namespaced@1.1.13": "04t6g000008OaYwAAK",
"apex-rollup-namespaced@1.1.14": "04t6g000008OaZBAA0",
"apex-rollup-namespaced@1.1.16": "04t6g000008OaZaAAK",
- "apex-rollup-namespaced@1.1.17": "04t6g000008OafKAAS"
+ "apex-rollup-namespaced@1.1.17": "04t6g000008Oak6AAC"
}
}
\ No newline at end of file
diff --git a/rollup/core/classes/Rollup.cls b/rollup/core/classes/Rollup.cls
index 7335d667..817d9d9d 100644
--- a/rollup/core/classes/Rollup.cls
+++ b/rollup/core/classes/Rollup.cls
@@ -64,7 +64,7 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
}
@TestVisible
- private static final List CACHED_FULL_RECALCS {
+ private static List CACHED_FULL_RECALCS {
get {
if (CACHED_FULL_RECALCS == null) {
CACHED_FULL_RECALCS = new List();
@@ -74,6 +74,16 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
set;
}
+ private static Set CACHED_COUNT_QUERIES {
+ get {
+ if (CACHED_COUNT_QUERIES == null) {
+ CACHED_COUNT_QUERIES = new Set();
+ }
+ return CACHED_COUNT_QUERIES;
+ }
+ set;
+ }
+
@TestVisible
private static List CACHED_ROLLUPS {
get {
@@ -308,9 +318,10 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
FROM_APEX,
FROM_INVOCABLE,
FROM_SCHEDULED,
+ FROM_FULL_RECALC_APEX,
FROM_FULL_RECALC_LWC,
- FROM_SINGULAR_PARENT_RECALC_LWC,
- FROM_FULL_RECALC_FLOW
+ FROM_FULL_RECALC_FLOW,
+ FROM_SINGULAR_PARENT_RECALC_LWC
}
protected Rollup() {
@@ -725,6 +736,7 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
// internal variables!
public Id rollupControlId;
+ public String developerName;
}
global class FlowOutput {
@@ -869,11 +881,14 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
if (metas.isEmpty() == false) {
Rollup rollupConductor = getRollup(metas, wrapper.sObjectType, children, oldFlowRecords, null, fromInvocable);
- String logMessage = 'adding invocable rollup to list:';
- if (wrapper.flowInput.deferProcessing) {
- logMessage = 'deferring processing for rollup:';
+ String logMessage;
+ if (rollupConductor.isNoOp) {
+ logMessage = 'skipping no-op conductor';
+ } else if (wrapper.flowInput.deferProcessing) {
+ logMessage = 'deferring processing for rollup';
CACHED_ROLLUPS.add(rollupConductor);
} else {
+ logMessage = 'adding invocable rollup to list';
populateRollupByType(localRollups, wrapper.sObjectType, rollupConductor);
}
if (wrapper.flowInput.shouldRunSync) {
@@ -881,7 +896,7 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
roll.rollupControl.ShouldRunAs__c = RollupMetaPicklists.ShouldRunAs.Synchronous;
}
}
- RollupLogger.Instance.log(logMessage, rollupConductor, System.LoggingLevel.INFO);
+ RollupLogger.Instance.log(logMessage + ':', rollupConductor, System.LoggingLevel.INFO);
}
}
@@ -1809,6 +1824,8 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
flatten(CACHED_ROLLUPS);
List rollupsToProcess = new List(CACHED_ROLLUPS);
CACHED_ROLLUPS = null;
+ CACHED_FULL_RECALCS = null;
+ CACHED_COUNT_QUERIES = null;
batch(rollupsToProcess, InvocationPoint.FROM_INVOCABLE);
}
@@ -1942,6 +1959,7 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
ChangedFieldsOnCalcItem__c = flowInput.calcItemChangedFields,
ConcatDelimiter__c = flowInput.concatDelimiter,
CurrencyFieldMapping__c = flowInput.currencyFieldMapping,
+ DeveloperName = flowInput.DeveloperName,
FullRecalculationDefaultNumberValue__c = flowInput.fullRecalculationDefaultNumberValue,
FullRecalculationDefaultStringValue__c = flowInput.fullRecalculationDefaultStringValue,
GrandparentRelationshipFieldPath__c = flowInput.grandparentRelationshipFieldPath,
@@ -2278,11 +2296,19 @@ global without sharing virtual class Rollup implements RollupLogger.ToStringObje
private static void appendQueryCount(RollupMetadata metaWrapper, Rollup__mdt meta, String whereClause, Schema.SObjectType childType) {
if (metaWrapper.recordCount != RollupRepository.SENTINEL_COUNT_VALUE) {
- Integer currentCount = new RollupRepository(RollupMetaPicklists.getAccessLevel(meta))
- .setQuery(RollupQueryBuilder.Current.getQuery(childType, new List(), meta.LookupFieldOnLookupObject__c, '!=', whereClause))
- .setArg(new Set())
- .setArg('recordIds', metaWrapper.recordIds)
- .getCount();
+ String query = RollupQueryBuilder.Current.getQuery(childType, new List(), meta.LookupFieldOnLookupObject__c, '!=', whereClause);
+ String hashedQuery = query + meta.LookupObject__c + metaWrapper.recordIds;
+ Integer currentCount;
+ if (CACHED_COUNT_QUERIES.contains(hashedQuery)) {
+ currentCount = 0;
+ } else {
+ currentCount = new RollupRepository(RollupMetaPicklists.getAccessLevel(meta))
+ .setQuery(query)
+ .setArg(new Set())
+ .setArg('recordIds', metaWrapper.recordIds)
+ .getCount();
+ CACHED_COUNT_QUERIES.add(hashedQuery);
+ }
metaWrapper.recordCount = currentCount == RollupRepository.SENTINEL_COUNT_VALUE ? currentCount : metaWrapper.recordCount + currentCount;
}
}
diff --git a/rollup/core/classes/RollupAsyncProcessor.cls b/rollup/core/classes/RollupAsyncProcessor.cls
index c8ae22a7..75b0089a 100644
--- a/rollup/core/classes/RollupAsyncProcessor.cls
+++ b/rollup/core/classes/RollupAsyncProcessor.cls
@@ -668,7 +668,7 @@ global virtual without sharing class RollupAsyncProcessor extends Rollup impleme
this.logger.log(this.getTypeName() + ': Populating unexpected full recalc for ' + outstandingItemCount + ' items', System.LoggingLevel.INFO);
RollupFullRecalcProcessor fullBatchProcessor = new RollupFullBatchRecalculator(
query.substringBeforeLast('\nLIMIT'),
- this.invokePoint,
+ InvocationPoint.FROM_FULL_RECALC_APEX,
new List{ rollup.metadata },
rollup.calcItemType,
recordIds,
@@ -839,7 +839,13 @@ global virtual without sharing class RollupAsyncProcessor extends Rollup impleme
}
private Boolean isValidAdditionalCalcItemRetrieval(RollupAsyncProcessor roll) {
- if (roll.fullRecalcProcessor != null) {
+ Set alwaysFalseForRetrieval = new Set{
+ InvocationPoint.FROM_FULL_RECALC_APEX,
+ InvocationPoint.FROM_FULL_RECALC_LWC,
+ InvocationPoint.FROM_FULL_RECALC_FLOW,
+ InvocationPoint.FROM_SINGULAR_PARENT_RECALC_LWC
+ };
+ if (roll.fullRecalcProcessor != null && alwaysFalseForRetrieval.contains(roll.invokePoint)) {
return false;
} else {
return roll.isFullRecalc || roll.metadata.IsFullRecordSet__c == true;
diff --git a/rollup/core/classes/RollupCalcItemReplacer.cls b/rollup/core/classes/RollupCalcItemReplacer.cls
index e79ae7d6..516ffac7 100644
--- a/rollup/core/classes/RollupCalcItemReplacer.cls
+++ b/rollup/core/classes/RollupCalcItemReplacer.cls
@@ -126,8 +126,11 @@ public without sharing class RollupCalcItemReplacer {
this.fillField(this.parentQueryFields, '' + calcItem.getSObjectType(), fieldName);
}
} else {
- // it'd be great to use calcItem.isSet(fieldName) here, but that returns false for null values
+ if (fieldName.startsWithIgnoreCase('not(')) {
+ fieldName = fieldName.substring(4, fieldName.length());
+ }
try {
+ // it'd be great to use calcItem.isSet(fieldName) here, but that returns false for null values
calcItem.get(fieldName);
} catch (Exception ex) {
this.fillField(this.baseQueryFields, '' + calcItem.getSObjectType(), fieldName);
diff --git a/rollup/core/classes/RollupFlowBulkProcessor.cls b/rollup/core/classes/RollupFlowBulkProcessor.cls
index df86eef6..d8d65a18 100644
--- a/rollup/core/classes/RollupFlowBulkProcessor.cls
+++ b/rollup/core/classes/RollupFlowBulkProcessor.cls
@@ -160,6 +160,7 @@ global without sharing class RollupFlowBulkProcessor {
input.recordsToRollup = flowInput.recordsToRollup;
input.rollupContext = flowInput.rollupContext;
input.shouldRunSync = flowInput.shouldRunSync != null ? flowInput.shouldRunSync : false;
+ input.developerName = meta.DeveloperName;
}
}
}
diff --git a/rollup/core/classes/RollupFullRecalcProcessor.cls b/rollup/core/classes/RollupFullRecalcProcessor.cls
index 85d2bc07..567b8a0f 100644
--- a/rollup/core/classes/RollupFullRecalcProcessor.cls
+++ b/rollup/core/classes/RollupFullRecalcProcessor.cls
@@ -156,6 +156,7 @@ global abstract without sharing class RollupFullRecalcProcessor extends RollupAs
this.addToMap(props, 'Rollup Metadata', this.rollupMetas);
this.addToMap(props, 'Query String', this.queryString);
this.addToMap(props, 'Caboose Count', this.cabooses.size());
+ this.addToMap(props, 'Inner rollups', this.rollupMetas?.size());
return props;
}
diff --git a/rollup/core/classes/RollupLogger.cls b/rollup/core/classes/RollupLogger.cls
index f6cfb6f2..c14388c3 100644
--- a/rollup/core/classes/RollupLogger.cls
+++ b/rollup/core/classes/RollupLogger.cls
@@ -1,7 +1,7 @@
global without sharing virtual class RollupLogger implements ILogger {
@TestVisible
// this gets updated via the pipeline as the version number gets incremented
- private static final String CURRENT_VERSION_NUMBER = 'v1.6.17';
+ private static final String CURRENT_VERSION_NUMBER = 'v1.6.18';
private static final System.LoggingLevel FALLBACK_LOGGING_LEVEL = System.LoggingLevel.DEBUG;
private static final RollupPlugin PLUGIN = new RollupPlugin();
diff --git a/sfdx-project.json b/sfdx-project.json
index 3515a65d..9b2e9907 100644
--- a/sfdx-project.json
+++ b/sfdx-project.json
@@ -5,8 +5,8 @@
"package": "apex-rollup",
"path": "rollup",
"scopeProfiles": true,
- "versionName": "Adds CMDT support for Task/User/Event and other previously unsupported objects",
- "versionNumber": "1.6.17.0",
+ "versionName": "More accurate counts when adding up relevant children/parents prior to going async. More accurate REFRESH calculations for rollups to multiple parents",
+ "versionNumber": "1.6.18.0",
"versionDescription": "Fast, configurable, elastically scaling custom rollup solution. Apex Invocable action, one-liner Apex trigger/CMDT-driven logic, and scheduled Apex-ready.",
"releaseNotesUrl": "https://github.com/jamessimone/apex-rollup/releases/latest",
"unpackagedMetadata": {
@@ -103,6 +103,7 @@
"apex-rollup@1.6.14": "04t6g000008OaYrAAK",
"apex-rollup@1.6.15": "04t6g000008OaZQAA0",
"apex-rollup@1.6.16": "04t6g000008OaZVAA0",
- "apex-rollup@1.6.17": "04t6g000008OafFAAS"
+ "apex-rollup@1.6.17": "04t6g000008OafFAAS",
+ "apex-rollup@1.6.18": "04t6g000008Oak1AAC"
}
}
\ No newline at end of file