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 - + Deploy to Salesforce - + Deploy to Salesforce Sandbox 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 - + Deploy to Salesforce - + Deploy to Salesforce Sandbox 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