Skip to content

Commit

Permalink
v1.6.35 - Rollup Order By Bugfix (#632)
Browse files Browse the repository at this point in the history
* Fixes an issue reported by Katherine West where rollup ordering wasn't being properly applied

* Fixes #629 by properly handling text template HTML tags (when present) for the Full Recalc CMDT-driven Invocable rollup action
  • Loading branch information
jamessimone authored Oct 2, 2024
1 parent 877a3b6 commit 1acc7d5
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 24 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ As well, don't miss [the Wiki](../../wiki), which includes even more info for co

## Deployment & Setup

<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfJfAAK">
<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfKiAAK">
<img alt="Deploy to Salesforce"
src="./media/deploy-package-to-prod.png">
</a>

<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfJfAAK">
<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfKiAAK">
<img alt="Deploy to Salesforce Sandbox"
src="./media/deploy-package-to-sandbox.png">
</a>
Expand Down
9 changes: 8 additions & 1 deletion extra-tests/classes/RollupDateLiteralTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,15 @@ private class RollupDateLiteralTests {
@IsTest
static void shouldWorkForLastMonth() {
runTestForLiteral('LAST_MONTH');
User australiaUser = [SELECT Id FROM User WHERE LastName = 'Australia User'];
System.runAs(australiaUser) {
runTestForLiteral('LAST_MONTH');
}
}

@IsTest
static void shouldWorkForThisMonth() {
runTestForLiteral('THIS_MONTH');
// TODO extend this more generally throughout this test class
User australiaUser = [SELECT Id FROM User WHERE LastName = 'Australia User'];
System.runAs(australiaUser) {
runTestForLiteral('THIS_MONTH');
Expand All @@ -239,6 +242,10 @@ private class RollupDateLiteralTests {
@IsTest
static void shouldWorkForNextMonth() {
runTestForLiteral('NEXT_MONTH');
User australiaUser = [SELECT Id FROM User WHERE LastName = 'Australia User'];
System.runAs(australiaUser) {
runTestForLiteral('NEXT_MONTH');
}
}

@IsTest
Expand Down
75 changes: 75 additions & 0 deletions extra-tests/classes/RollupFlowFullRecalcDispatcherTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,81 @@ private class RollupFlowFullRecalcDispatcherTests {
System.assertEquals(5, user.Latitude);
}

@IsTest
static void supportsTextTemplateInputVariables() {
Rollup.onlyUseMockMetadata = true;
Rollup.rollupMetadata = new List<Rollup__mdt>{
new Rollup__mdt(
DeveloperName = 'cmdt1',
CalcItem__c = 'ContactPointAddress',
RollupFieldOnCalcItem__c = 'PreferenceRank',
LookupFieldOnCalcItem__c = 'ParentId',
LookupObject__c = 'Account',
LookupFieldOnLookupObject__c = 'Id',
RollupFieldOnLookupObject__c = 'AnnualRevenue',
RollupOperation__c = 'SUM',
CalcItemWhereClause__c = 'PreferenceRank = 1'
),
new Rollup__mdt(
DeveloperName = 'cmdt2',
CalcItem__c = 'ContactPointAddress',
RollupFieldOnCalcItem__c = 'PreferenceRank',
LookupFieldOnCalcItem__c = 'ParentId',
LookupObject__c = 'Account',
LookupFieldOnLookupObject__c = 'Id',
RollupFieldOnLookupObject__c = 'NumberOfEmployees',
RollupOperation__c = 'COUNT'
)
};
List<RollupFlowFullRecalcDispatcher.FlowInput> flowInputs = getFlowInputs(Rollup.rollupMetadata);
String exampleTextTemplate = '<p><span style="background-color: rgb(255, 255, 255); font-size: 11.36px; font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0);">{0}</span></p>';
flowInputs[0].rollupDeveloperNames = String.format(exampleTextTemplate, new List<String>{ flowInputs[0].rollupDeveloperNames });

Test.startTest();
RollupFlowFullRecalcDispatcher.performFullRecalcRollups(flowInputs);
Test.stopTest();

Account acc = [SELECT AnnualRevenue, NumberOfEmployees FROM Account];
System.assertEquals(6, acc.AnnualRevenue);
System.assertEquals(6, acc.NumberOfEmployees);
}

@IsTest
static void integrationSupportsTextTemplateVariables() {
Rollup.onlyUseMockMetadata = true;
Rollup.rollupMetadata = new List<Rollup__mdt>{
new Rollup__mdt(
DeveloperName = 'cmdt1',
CalcItem__c = 'ContactPointAddress',
RollupFieldOnCalcItem__c = 'PreferenceRank',
LookupFieldOnCalcItem__c = 'ParentId',
LookupObject__c = 'Account',
LookupFieldOnLookupObject__c = 'Id',
RollupFieldOnLookupObject__c = 'AnnualRevenue',
RollupOperation__c = 'SUM',
CalcItemWhereClause__c = 'PreferenceRank = 1'
),
new Rollup__mdt(
DeveloperName = 'cmdt2',
CalcItem__c = 'ContactPointAddress',
RollupFieldOnCalcItem__c = 'PreferenceRank',
LookupFieldOnCalcItem__c = 'ParentId',
LookupObject__c = 'Account',
LookupFieldOnLookupObject__c = 'Id',
RollupFieldOnLookupObject__c = 'NumberOfEmployees',
RollupOperation__c = 'COUNT'
)
};

Test.startTest();
new Flow.Interview.Rollup_Integration_Comma_Separated_Full_Recalc(new Map<String, Object>{ 'rollupNames' => 'cmdt1, cmdt2' }).start();
Test.stopTest();

Account acc = [SELECT AnnualRevenue, NumberOfEmployees FROM Account];
System.assertEquals(6, acc.AnnualRevenue);
System.assertEquals(6, acc.NumberOfEmployees);
}

private static List<RollupFlowFullRecalcDispatcher.FlowInput> getFlowInputs(List<Rollup__mdt> metas) {
List<RollupFlowFullRecalcDispatcher.FlowInput> flowInputs = new List<RollupFlowFullRecalcDispatcher.FlowInput>();
RollupFlowFullRecalcDispatcher.FlowInput input = new RollupFlowFullRecalcDispatcher.FlowInput();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?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>Integration NumberValue FIRST</label>
<protected>false</protected>
<values>
<field>FieldName__c</field>
<value xsi:type="xsd:string">NumberField__c</value>
</values>
<values>
<field>NullSortOrder__c</field>
<value xsi:type="xsd:string">NULLS FIRST</value>
</values>
<values>
<field>Ranking__c</field>
<value xsi:type="xsd:double">1.0</value>
</values>
<values>
<field>Rollup__c</field>
<value xsi:type="xsd:string">RollupIntegrationChildRollupText</value>
</values>
<values>
<field>SortOrder__c</field>
<value xsi:type="xsd:string">Ascending</value>
</values>
</CustomMetadata>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<actionCalls>
<name>Recalc_Rollups</name>
<label>Recalc Rollups</label>
<locationX>176</locationX>
<locationY>134</locationY>
<actionName>RollupFlowFullRecalcDispatcher</actionName>
<actionType>apex</actionType>
<flowTransactionModel>CurrentTransaction</flowTransactionModel>
<inputParameters>
<name>rollupDeveloperNames</name>
<value>
<elementReference>Rollups_Comma_Separated</elementReference>
</value>
</inputParameters>
<nameSegment>RollupFlowFullRecalcDispatcher</nameSegment>
<storeOutputAutomatically>true</storeOutputAutomatically>
<versionSegment>1</versionSegment>
</actionCalls>
<apiVersion>61.0</apiVersion>
<environments>Default</environments>
<interviewLabel>Rollup Integration: Comma-Separated Full Recalc {!$Flow.CurrentDateTime}</interviewLabel>
<label>Rollup Integration: Comma-Separated Full Recalc</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>AutoLaunchedFlow</processType>
<start>
<locationX>50</locationX>
<locationY>0</locationY>
<connector>
<targetReference>Recalc_Rollups</targetReference>
</connector>
</start>
<status>Draft</status>
<textTemplates>
<name>Rollups_Comma_Separated</name>
<isViewedAsPlainText>false</isViewedAsPlainText>
<text>&lt;p&gt;{!rollupNames}&lt;/p&gt;</text>
</textTemplates>
<variables>
<name>rollupNames</name>
<dataType>String</dataType>
<isCollection>false</isCollection>
<isInput>true</isInput>
<isOutput>false</isOutput>
</variables>
</Flow>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "apex-rollup",
"version": "1.6.34",
"version": "1.6.35",
"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",
Expand Down
2 changes: 1 addition & 1 deletion plugins/RollupCallback/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public class SubflowRollupDispatcher implements RollupSObjectUpdater.IDispatcher
decorator.FieldNames = new List<String>(record.getPopulatedFieldsAsMap().keySet());
wrappedRecords.add(decorator);
}
Flow.Interview rollupSubflow = Flow.Interview.RollupSubflow(
Flow.Interview rollupSubflow = new Flow.Interview.RollupSubflow(
new Map<String, Object>{
'records' => wrappedRecords
}
Expand Down
4 changes: 2 additions & 2 deletions rollup-namespaced/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ For more info, see the base `README`.

## Deployment & Setup

<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfJkAAK">
<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfKnAAK">
<img alt="Deploy to Salesforce"
src="./media/deploy-package-to-prod.png">
</a>

<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfJkAAK">
<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfKnAAK">
<img alt="Deploy to Salesforce Sandbox"
src="./media/deploy-package-to-sandbox.png">
</a>
7 changes: 4 additions & 3 deletions rollup-namespaced/sfdx-project.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"default": true,
"package": "apex-rollup-namespaced",
"path": "rollup-namespaced/source/rollup",
"versionName": "Fixes parentRecordIdForEmptyChildrenCollections flow case",
"versionNumber": "1.1.27.0",
"versionName": "Fixes Rollup Order By sorting to always be deterministic, allows text templates in Full Recalc CMDT-driven Invocable invocable",
"versionNumber": "1.1.28.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": {
Expand All @@ -30,6 +30,7 @@
"[email protected]": "04t6g000008ObbqAAC",
"[email protected]": "04t6g000008Obc0AAC",
"[email protected]": "04t6g000008ObeVAAS",
"[email protected]": "04t6g000008OfJkAAK"
"[email protected]": "04t6g000008OfJkAAK",
"[email protected]": "04t6g000008OfKnAAK"
}
}
3 changes: 2 additions & 1 deletion rollup/core/classes/RollupCalculator.cls
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,9 @@ public without sharing abstract class RollupCalculator {
protected List<WinnowResult> winnowItems(List<SObject> items, Map<Id, SObject> oldCalcItems) {
List<RollupOrderBy__mdt> orderBys = this.metadata?.LimitAmount__c != null && this.metadata.RollupOrderBys__r.isEmpty()
? new List<RollupOrderBy__mdt>{ new RollupOrderBy__mdt(FieldName__c = 'Id', Ranking__c = 0) }
: this.metadata.RollupOrderBys__r;
: new List<RollupOrderBy__mdt>(this.metadata.RollupOrderBys__r);
if (orderBys.isEmpty() == false) {
orderBys.sort(new RollupRepository.OrderBySorter());
items.sort(new RollupCalcItemSorter(orderBys));
}
List<WinnowResult> winnowedItems = new List<WinnowResult>();
Expand Down
18 changes: 15 additions & 3 deletions rollup/core/classes/RollupDateLiteral.cls
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,11 @@ public without sharing abstract class RollupDateLiteral {
private class LastMonthLiteral extends RollupDateLiteral {
public LastMonthLiteral() {
this.ref = getRelativeDatetime(System.today().addMonths(-1).toStartOfMonth(), START_TIME);
this.bound = offsetToFirstDay(getRelativeDatetime(this.ref.addMonths(1).dateGmt(), END_TIME));
Date relativeDate = this.ref.addMonths(1).date();
if (relativeDate.day() == 1) {
relativeDate = relativeDate.addDays(-1);
}
this.bound = offsetToFirstDay(getRelativeDatetime(relativeDate, END_TIME));
}
}

Expand All @@ -364,7 +368,11 @@ public without sharing abstract class RollupDateLiteral {
private class ThisMonthLiteral extends RollupDateLiteral {
public ThisMonthLiteral() {
this.ref = getRelativeDatetime(System.today().toStartOfMonth(), START_TIME);
this.bound = offsetToFirstDay(getRelativeDatetime(this.ref.addMonths(1).dateGmt(), END_TIME));
Date relativeDate = this.ref.addMonths(1).date();
if (relativeDate.day() == 1) {
relativeDate = relativeDate.addDays(-1);
}
this.bound = offsetToFirstDay(getRelativeDatetime(relativeDate, END_TIME));
}
}

Expand All @@ -374,7 +382,11 @@ public without sharing abstract class RollupDateLiteral {
private class NextMonthLiteral extends RollupDateLiteral {
public NextMonthLiteral() {
this.ref = getRelativeDatetime(System.today().toStartOfMonth().addMonths(1), START_TIME);
this.bound = offsetToFirstDay(getRelativeDatetime(this.ref.addMonths(1).dateGmt(), END_TIME));
Date relativeDate = this.ref.addMonths(1).date();
if (relativeDate.day() == 1) {
relativeDate = relativeDate.addDays(-1);
}
this.bound = offsetToFirstDay(getRelativeDatetime(relativeDate, END_TIME));
}
}

Expand Down
2 changes: 1 addition & 1 deletion rollup/core/classes/RollupFlowFullRecalcDispatcher.cls
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ global without sharing class RollupFlowFullRecalcDispatcher {
if (String.isBlank(input.rollupDeveloperNames)) {
throw new IllegalArgumentException('Comma-separated list of Rollup__mdt DeveloperName(s) was not provided');
}
List<String> splitListOfApiNames = input.rollupDeveloperNames.split(',');
List<String> splitListOfApiNames = input.rollupDeveloperNames.stripHtmlTags().split(',');
for (String apiName : splitListOfApiNames) {
rollupDeveloperNames.add(apiName.trim());
}
Expand Down
2 changes: 1 addition & 1 deletion rollup/core/classes/RollupLogger.cls
Original file line number Diff line number Diff line change
@@ -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.34';
private static final String CURRENT_VERSION_NUMBER = 'v1.6.35';
private static final System.LoggingLevel FALLBACK_LOGGING_LEVEL = System.LoggingLevel.DEBUG;
private static final RollupPlugin PLUGIN = new RollupPlugin();

Expand Down
3 changes: 1 addition & 2 deletions rollup/core/classes/RollupRepository.cls
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public without sharing class RollupRepository implements RollupLogger.ToStringOb
SharingMode__c,
ShouldRunWithoutCustomSettingEnabled__c,
SplitConcatDelimiterOnCalcItem__c,
(SELECT Id, FieldName__c, NullSortOrder__c, Ranking__c, SortOrder__c FROM RollupOrderBys__r),
(SELECT Id, DeveloperName, FieldName__c, NullSortOrder__c, Ranking__c, SortOrder__c FROM RollupOrderBys__r),
RollupGrouping__r.Id,
RollupGrouping__r.RollupOperation__c
FROM Rollup__mdt
Expand All @@ -149,7 +149,6 @@ public without sharing class RollupRepository implements RollupLogger.ToStringOb
meta.GroupByRowStartDelimiter__c = meta.GroupByRowStartDelimiter__c?.unescapeJava();
meta.SharingMode__c = meta.SharingMode__c ?? RollupMetaPicklists.SharingMode.SystemLevel;
meta.UltimateParentLookup__c = meta.UltimateParentLookup__r.QualifiedApiName;
meta.RollupOrderBys__r.sort(new OrderBySorter());
}

return matchingMetadata;
Expand Down
10 changes: 4 additions & 6 deletions sfdx-project.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"package": "apex-rollup",
"path": "rollup",
"scopeProfiles": true,
"versionName": "Fixes parentRecordIdForEmptyChildrenCollections flow case",
"versionNumber": "1.6.34.0",
"versionName": "Fixes Rollup Order By sorting to always be deterministic, allows text templates in Full Recalc CMDT-driven Invocable invocable",
"versionNumber": "1.6.35.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": {
Expand Down Expand Up @@ -101,12 +101,10 @@
"Apex Rollup - Rollup [email protected]": "04t6g000008Sis0AAC",
"Nebula Logger - [email protected]": "04t5Y0000015oRNQAY",
"apex-rollup": "0Ho6g000000TNcOCAW",
"[email protected]": "04t6g000008ObN8AAK",
"[email protected]": "04t6g000008ObNNAA0",
"[email protected]": "04t6g000008ObVhAAK",
"[email protected]": "04t6g000008ObblAAC",
"[email protected]": "04t6g000008ObbvAAC",
"[email protected]": "04t6g000008ObeQAAS",
"[email protected]": "04t6g000008OfJfAAK"
"[email protected]": "04t6g000008OfJfAAK",
"[email protected]": "04t6g000008OfKiAAK"
}
}

0 comments on commit 1acc7d5

Please sign in to comment.