Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recurring Donations Batch Filtering #6971

Merged
merged 44 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
11a3f87
Initial commit of RD Batch filtering
lparrott Jun 3, 2022
0cfbdf2
RD Batch filter fixes, new unit test
lparrott Jun 6, 2022
3e31108
Merge dc728c566e27bed506d62327fe8cecc178f9e21e into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 8, 2022
7e40fc3
WIP Changing RD Batch Filter logic
lparrott Jun 8, 2022
215bbdf
Merge d830277b682f2df505ba8c7b91712a6665c11861 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 9, 2022
9a5da93
Merge branch 'feature/240__rdBatchFiltering' of https:/Sa…
lparrott Jun 10, 2022
c7337df
RD LDV Batch, updating custom setting labels and default values
lparrott Jun 15, 2022
d285764
Disabling Closed RD filter for Bulk Data process, adding unit test to…
lparrott Jun 16, 2022
8fbb819
RD Batch filtering - adding unit tests to check settings conditions
lparrott Jun 16, 2022
0d0c774
Merge 8ffab97bc05b338c5bb052bf87520ebf8244fe3a into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 17, 2022
1efddb8
Merge 611c24908801e16d299e9ecefa8fed44ec332718 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 17, 2022
722df21
Merge 66c20d6f760d2288f687ffd888e435236603e7b5 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 18, 2022
9e5880c
RD Batch filter review feedback
lparrott Jun 21, 2022
4cbad9d
Merge branch 'feature/240__rdBatchFiltering' of https:/Sa…
lparrott Jun 21, 2022
69c7b86
Merge 67885bcb28f78b2e1f1ad786526429ab1bb3d4e4 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 21, 2022
04627dc
RD Batch filter, fixing potential null pointer exceptions with new se…
lparrott Jun 22, 2022
e616829
Merge 521c3d222b6ec5dfea7c04d40ba5780757b45347 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 22, 2022
c4c4478
Merge fb220dfc250920165d1cca3e4482ba2c43be72f0 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 22, 2022
c66dc6a
Merge 76e3fd984354693fc6228acd76b835e850bd6cb1 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 23, 2022
9f099c3
Merge fc3c2315d30146597fa5a4e946c623e8dd5727b7 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 23, 2022
baa51ae
Merge c24fed424ca3be2b1041a8adc50f34bc695ec740 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 23, 2022
79c8fb4
Merge ff7d8fd64047bacdf0d6a64040ea1327bb8b2b30 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 25, 2022
03f59c2
Merge 36926019734b923c77fc25443f598db0cf2a41b2 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 27, 2022
546fcc3
Merge 38b63d9d22b27e3c6bc6f90e4d1f53945d116f1f into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 27, 2022
f271ece
Merge 45c732c46ec5c1bd9285a9d8b032be6c7623224d into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 29, 2022
1caa5e2
Merge 7d49cfda681425cc4d5cbafd39fa31c071a4f0b1 into feature/240__rdBa…
salesforce-org-metaci[bot] Jun 29, 2022
b660cc5
temporarily remove disabling filter from NPSP settings run for testin…
daniel-fuller Jun 30, 2022
af1b1b5
Merge b373fe998eec85c2dc8eddf954edcfd90efe0976 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 1, 2022
d071cf7
Merge cfa690b8884c3151fe98c78408f034232d020615 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 1, 2022
397f6b4
change the closedStatusValues variable scope so that the variable is …
daniel-fuller Jul 5, 2022
4dcf7df
update query to prevent passing null in the limit or where clause
daniel-fuller Jul 5, 2022
9b610b3
Merge 799cb42d49ec1dbdf133de08d5b0ac3ad40491ab into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 5, 2022
edef1ff
Merge 5e9ac2336e4975bf5a5e335648aab594b2ff1f53 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 6, 2022
00b97fd
Merge c9da83356c97eccf0efc682723a02ee274593c52 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 6, 2022
e8e15a3
Merge e71e287a43d98d68de0885f9f7ee6e92224d2afc into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 6, 2022
c96c00f
Merge 255d606f4e1a4cd162962e56d6c2036118d83c11 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 8, 2022
4934821
Merge f2b87bb2188c00f4a086f6a4c8a4b78e53679af2 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 8, 2022
219b202
Merge 1b5a60a745e52718dc103ad8dfcb1aa3d33864a6 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 11, 2022
d75bcd2
Remove comment from Unit test
lparrott Jul 11, 2022
1865936
Merge ef9d2cacca98ab24c94c992582294225e5c9d407 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 11, 2022
8ebe3b0
Merge 252209ec28a165f569c63227288b5d42328ac736 into feature/240__rdBa…
salesforce-org-metaci[bot] Jul 12, 2022
0a6647f
Revert "temporarily remove disabling filter from NPSP settings run fo…
daniel-fuller Jul 12, 2022
11ff225
Merge branch 'feature/240__rdBatchFiltering' of https:/Sa…
lparrott Jul 12, 2022
2ead37a
Making Unit test assertion statement more accurate
lparrott Jul 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions force-app/main/default/classes/CRLP_Batch_Base.cls
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ public abstract class CRLP_Batch_Base {
private set;
}

/** @description Whether Recurring Donation Batch filtering is enabled */
protected Boolean isRdBatchFilterEnabled {
get {
return isRdBatchFilterEnabled;
}
private set;
}

/** @description When filtering, the number of days since being modified to include */
protected Integer rdBatchFilterDateRange {
get {
return rdBatchFilterDateRange;
}
private set;
}

/** @description The customizable rollup custom settings */
protected Customizable_Rollup_Settings__c customizableRollupSettings;

Expand Down Expand Up @@ -140,6 +156,9 @@ public abstract class CRLP_Batch_Base {
this.statefulCacheOfRollupsToBeProcessed = CRLP_Rollup_SEL.getRollupDefinitionsToUse(this.jobType, this.jobFilter);
this.isScheduledJob = System.isScheduled();
this.customizableRollupSettings = UTIL_CustomSettingsFacade.getCustomizableRollupSettings();
this.isRdBatchFilterEnabled = (this.jobType == CRLP_RollupProcessingOptions.RollupType.RecurringDonations)
&& UTIL_CustomSettingsFacade.getRecurringDonationsSettings().Enable_Opportunity_Batch_Filter__c;
this.rdBatchFilterDateRange = UTIL_CustomSettingsFacade.getRecurringDonationsSettings().Batch_Filter_Date_Range__c.intValue();

this.detailObjectType = CRLP_Rollup_SVC.getDetailObjectType(jobType);
this.keyField = CRLP_Rollup_SVC.getParentFieldNameForQuery(jobType);
Expand Down Expand Up @@ -484,6 +503,9 @@ public abstract class CRLP_Batch_Base {
when ContactHardCredit {
return base.customizableRollupSettings.ContactHardCreditNonSkew_Incremental__c;
}
when RecurringDonations {
return base.isRdBatchFilterEnabled;
}
when else {
return false;
}
Expand All @@ -502,7 +524,11 @@ public abstract class CRLP_Batch_Base {
Integer maxDaysAgo {
get {
if (maxDaysAgo == null) {
maxDaysAgo = getMaxIntegerValueFromRollupsForType(CRLP_Operation.TimeBoundOperationType.Days_Back);
if (base.isRdBatchFilterEnabled) {
maxDaysAgo = base.rdBatchFilterDateRange;
} else {
maxDaysAgo = getMaxIntegerValueFromRollupsForType(CRLP_Operation.TimeBoundOperationType.Days_Back);
}
}
return maxDaysAgo;
}
Expand Down Expand Up @@ -560,7 +586,9 @@ public abstract class CRLP_Batch_Base {
Integer overrideForLastNDaysValue {
get {
if (overrideForLastNDaysValue == null) {
if (base.customizableRollupSettings.Rollups_IncrementalLastNDays_ValOverride__c != null) {
if (base.isRdBatchFilterEnabled) {
overrideForLastNDaysValue = base.rdBatchFilterDateRange;
} else if (base.customizableRollupSettings.Rollups_IncrementalLastNDays_ValOverride__c != null) {
overrideForLastNDaysValue = (Integer) base.customizableRollupSettings.Rollups_IncrementalLastNDays_ValOverride__c;
}
}
Expand Down
41 changes: 41 additions & 0 deletions force-app/main/default/classes/CRLP_Batch_Base_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,44 @@ private class CRLP_Batch_Base_TEST {
'Recurring Donation Nonskew query should not include inner join');
}

/**
* @description Confirms RD NonSkew query with Batch Filter enabled includes an inner join
*/
@isTest
private static void recurringDonationRollupGeneratesIncrementalModeJoinQuery() {
CRLP_RollupProcessingOptions.RollupType jobType =
CRLP_RollupProcessingOptions.RollupType.RecurringDonations;
String userDefinedLastNDaysFieldOverride = 'LastModifiedDate';
Integer userDefinedLastNDaysValueOverride = 20;
Integer oppFilterDateRange = RD2_OpportunityEvaluation_TEST.OPP_FILTER_DATE_RANGE;
configureIncrementalFieldOverrides(
jobType,
userDefinedLastNDaysFieldOverride,
userDefinedLastNDaysValueOverride);

CRLP_RollupProcessingOptions.RollupTypeFilter typeFilter =
CRLP_RollupProcessingOptions.RollupTypeFilter.All;
CRLP_Batch_Base_NonSkew rdBatchJob = new CRLP_RD_BATCH(typeFilter);
rdBatchJob.isScheduledJob = true;

CRLP_Batch_Base.BatchQueryBuilder queryBuilder =
new CRLP_Batch_Base.BatchQueryBuilder(rdBatchJob, null, null, null);

String query = queryBuilder.buildQuery();
String generatedWhereClause = queryBuilder.getMainQueryInnerJoinFilter();

System.assertEquals(2, query.countMatches('SELECT'),
'Recurring Donation Filtered query should include inner join');

System.assert(generatedWhereClause.contains('FROM'));
System.assert(generatedWhereClause.contains('WHERE'), 'The incremental mode ' +
'where clause for the inner join should contain a where filter on the Opportunities.');
System.assert(generatedWhereClause.contains('LAST_N_DAYS:' + oppFilterDateRange),
'Where clause should use Opp Date Range Setting, not Rollup Override value: ' + oppFilterDateRange);
System.assert(!batchStartOuterQueryContainsOrderByAndLimit(queryBuilder.buildQuery()),
'The outer query should not contain "ORDER BY" or "LIMIT".');
}

/**
* @description For Account-Contact-Soft-Credit rollups, validate that the FieldsToCheckForNonZero property
* returns back a single instance of a numeric field based on the mocked rollups configured for this
Expand Down Expand Up @@ -693,6 +731,9 @@ private class CRLP_Batch_Base_TEST {
settings.ContactHardCreditNonSkew_Incremental__c = isIncrementalMode;
CRLP_RollupContact_TEST.mockRollupCMTValues();
}
when RecurringDonations {
RD2_OpportunityEvaluation_TEST.configureRecurringDonationsOppFilter();
}
}
return settings;
}
Expand Down
23 changes: 23 additions & 0 deletions force-app/main/default/classes/RD2_OpportunityEvaluation_BATCH.cls
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,21 @@ public without sharing class RD2_OpportunityEvaluation_BATCH
*/
@TestVisible
private String getRDBatchQuery() {
Boolean rdBatchFilterOn = getOpportunityModifiedFilterEnabled();
String rdFilterWhereClause;
if (rdBatchFilterOn) {
Integer dateRange = getOpportunityModifiedDateRange();
Date earliestModifiedDate = currentDate.addDays(-dateRange);
rdFilterWhereClause = 'Id IN (SELECT npe03__Recurring_Donation__c'
+ 'FROM Opportunity WHERE LastModifiedDate > :earliestModifiedDate)';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @lparrott - any chance we can switch this to use SystemModStamp instead of LastModifiedDate since SystemModStamp is indexed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely, I have a list of questions to ask you and JJ, one revolves around potentially reusing the "Incremental Mode Field Override" setting for this query, which defaults to SystemModStamp. One downside: since there's only one field, it would be used for all incremental batches.

}

return new UTIL_Query()
.withFrom(npe03__Recurring_Donation__c.SObjectType)
.withSelectFields(
new Set<String>{ 'Id' }
)
.withWhere(rdFilterWhereClause)
.build();
}

Expand Down Expand Up @@ -247,6 +257,19 @@ public without sharing class RD2_OpportunityEvaluation_BATCH
return configValue.intValue();
}

private Integer getOpportunityModifiedDateRange() {
Integer dateRange = UTIL_CustomSettingsFacade.getRecurringDonationsSettings().Batch_Filter_Date_Range__c.intValue();
if (dateRange == null) {
dateRange = 30;
}
return dateRange;
}

private Boolean getOpportunityModifiedFilterEnabled() {
Boolean filterEnabled = UTIL_CustomSettingsFacade.getRecurringDonationsSettings().Enable_Opportunity_Batch_Filter__c;
return filterEnabled;
}

/**
* @description Custom batch exception
*/
Expand Down
46 changes: 46 additions & 0 deletions force-app/main/default/classes/RD2_OpportunityEvaluation_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public with sharing class RD2_OpportunityEvaluation_TEST {
private static final Date START_DATE = Date.newInstance(2019, 9, 15);
private static final Integer MONTHS_TO_DEC = START_DATE.monthsBetween(Date.newInstance(2019, 12, 15));
private static final Integer MONTHS_TO_YEAR_END = START_DATE.monthsBetween(Date.newInstance(2020, 1, 1));
public static final Integer OPP_FILTER_DATE_RANGE = 10;

/****
* @description Creates data required for unit tests
Expand Down Expand Up @@ -91,6 +92,35 @@ public with sharing class RD2_OpportunityEvaluation_TEST {
System.assertEquals(null, actuaException, 'An exception is expected because Enhanced RD is not enabled');
}

/**
* @description Verifies Recurring Donations with unmodified Opportunities are not processed
*/
@IsTest
private static void shouldNotProcessRDsWithUnmodifiedOpps() {
RD2_EnablementService_TEST.setRecurringDonations2Enabled();
configureRecurringDonationsOppFilter();
final Date batchRunDate = Date.today().addDays(OPP_FILTER_DATE_RANGE);
RD2_ScheduleService.currentDate = batchRunDate;

npe03__Recurring_Donation__c rd = getRecurringDonationBuilder()
.withStatusClosed()
.build();
insert rd;

Opportunity oldOpp = TEST_OpportunityBuilder.getOpportunityBuilder(rd)
.withClosedWonStage()
.withCloseDate(START_DATE)
.build();
insert oldOpp;

runBatch(new RD2_OpportunityEvaluation_BATCH(batchRunDate));

assertBatchJobIteration(0);

List<Opportunity> opps = oppGateway.getRecords(rd);
System.assertEquals(1, opps.size(), 'No new Opp should be created: ' + opps);
}

/**
* @description Verifies closed Recurring Donations are processed in the Opp evaluation batch
*/
Expand Down Expand Up @@ -1439,4 +1469,20 @@ public with sharing class RD2_OpportunityEvaluation_TEST {

return rdGateway.getRecord(rd.Id);
}

/***
* @description Stubs custom settings configuration to enable Filtered Recurring Donations Batch
* @return none
*/
public static void configureRecurringDonationsOppFilter() {
UTIL_CustomSettingsFacade.getRecurringDonationsSettingsForTest(
new npe03__Recurring_Donations_Settings__c(
IsRecurringDonations2Enabled__c = true,
npe03__Open_Opportunity_Behavior__c = RD2_Constants.CloseActions.Mark_Opportunities_Closed_Lost.name(),
Enable_Opportunity_Batch_Filter__c = true,
Batch_Filter_Date_Range__c = OPP_FILTER_DATE_RANGE
)
);
}

}
5 changes: 5 additions & 0 deletions force-app/main/default/classes/UTIL_CustomSettingsFacade.cls
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ public without sharing class UTIL_CustomSettingsFacade {
settings.UseFiscalYearForRecurringDonationValue__c = false;
settings.EnableChangeLog__c = false;

settings.Enable_Opportunity_Batch_Filter__c = false;
settings.Batch_Filter_Date_Range__c = 30;

List<RecordType> oppRecordTypes = [SELECT Id FROM RecordType WHERE SObjectType = 'Opportunity' AND IsActive = true];
if (oppRecordTypes.size() > 0) {
settings.npe03__Record_Type__c = oppRecordTypes[0].id;
Expand Down Expand Up @@ -915,6 +918,8 @@ public without sharing class UTIL_CustomSettingsFacade {
recurringDonationsSettings.StatusAutomationDaysForClosed__c = settings.StatusAutomationDaysForClosed__c;
recurringDonationsSettings.StatusAutomationLapsedValue__c = settings.StatusAutomationLapsedValue__c;
recurringDonationsSettings.StatusAutomationClosedValue__c = settings.StatusAutomationClosedValue__c;
recurringDonationsSettings.Batch_Filter_Date_Range__c = settings.Batch_Filter_Date_Range__c;
recurringDonationsSettings.Enable_Opportunity_Batch_Filter__c = settings.Enable_Opportunity_Batch_Filter__c;

orgRecurringDonationsSettings = recurringDonationsSettings;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Batch_Filter_Date_Range__c</fullName>
<defaultValue>30</defaultValue>
<description>When "Enable Opportunity Last Modified Batch Filter" is checked, this field determines the amount of days after being modified that an Opportunity should be included in Recurring Donation Batch jobs.</description>
<externalId>false</externalId>
<inlineHelpText>When "Enable Opportunity Last Modified Batch Filter" is checked, this field determines the amount of days after being modified that an Opportunity should be included in Recurring Donation Batch jobs.</inlineHelpText>
<label>Batch Filter Date Range</label>
<precision>18</precision>
<required>false</required>
<scale>0</scale>
<trackTrending>false</trackTrending>
<type>Number</type>
<unique>false</unique>
</CustomField>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Enable_Opportunity_Batch_Filter__c</fullName>
<defaultValue>false</defaultValue>
<description>When checked, Recurring Donation nightly batch jobs limit the number of Donations selected for recalculation by looking for recently updated Opportunities on those Recurring Donations. This helps to improve nightly job performance.</description>
<externalId>false</externalId>
<inlineHelpText>When checked, Recurring Donation nightly batch jobs limit the number of Donations selected for recalculation by looking for recently updated Opportunities on those Recurring Donations. This helps to improve nightly job performance.</inlineHelpText>
<label>Enable Opportunity Modified Batch Filter</label>
<trackTrending>false</trackTrending>
<type>Checkbox</type>
</CustomField>