Skip to content

Commit

Permalink
Added buttons for new enhanced UI community contribution, various min…
Browse files Browse the repository at this point in the history
…or fixes and enhancements

-
#2
3
-
#2
2
-
#2
1
-
#1
6
-
#5
-
#15
  • Loading branch information
afawcettffdc committed Apr 9, 2014
1 parent 7ed63d0 commit 0c8168c
Show file tree
Hide file tree
Showing 25 changed files with 2,175 additions and 42 deletions.
5 changes: 3 additions & 2 deletions rolluptool/src/classes/LREngine.cls
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ public class LREngine {

// Zero rollups for unprocessed master records (those with no longer any child relationships)
for(Id masterRecId : masterIds)
for (String detailFld : detail2MasterFldMap.keySet())
masterRecordsMap.get(masterRecId).put(detail2MasterFldMap.get(detailFld), 0);
for (RollupSummaryField rsf : ctx.fieldsToRoll)
masterRecordsMap.get(masterRecId).put(rsf.master.getName(),
rsf.isMasterTypeNumber ? 0 : null);

return masterRecordsMap.values();
}
Expand Down
57 changes: 52 additions & 5 deletions rolluptool/src/classes/RollupService.cls
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ global with sharing class RollupService
LookupRollupSummary__c lookup = lookups[0];
if(lookup.CalculateJobId__c!=null)
throw RollupServiceException.jobAlreadyRunning(lookup.Name);

// Already active?
if(!lookup.Active__c)
throw new RollupServiceException('The rollup must be Active before you can run a Calculate job.');

// Start the job and record the Job Id
Integer scopeSize = (Integer) DeclarativeLookupRollupSummaries__c.getInstance().CalculateJobScopeSize__c;
Expand Down Expand Up @@ -207,7 +211,7 @@ global with sharing class RollupService

// Rollup child records and update master records
if(lookupsToProcess.size()>0)
update updateMasterRollupsTrigger(lookups, masterRecordIds);
updateRecords(updateMasterRollupsTrigger(lookups, masterRecordIds), false, true);
return;
}

Expand All @@ -217,7 +221,7 @@ global with sharing class RollupService
for(LookupRollupSummary__c lookup : lookups)
if(childRecord.get(lookup.RelationShipField__c)!=null)
masterRecordIds.add((Id)childRecord.get(lookup.RelationShipField__c));
update updateMasterRollupsTrigger(lookups, masterRecordIds);
updateRecords(updateMasterRollupsTrigger(lookups, masterRecordIds), false, true);
}

/**
Expand Down Expand Up @@ -301,7 +305,7 @@ global with sharing class RollupService
// Update master records
List<LookupRollupSummaryLog__c> rollupSummaryLogs = new List<LookupRollupSummaryLog__c>();
List<SObject> masterRecordList = masterRecords.values();
List<Database.Saveresult> saveResults = Database.update(masterRecordList, false);
List<Database.Saveresult> saveResults = updateRecords(masterRecordList, false, false);

// Log errors to the summary log
Integer masterRecordIdx = 0;
Expand Down Expand Up @@ -373,7 +377,7 @@ global with sharing class RollupService

// Update master records
List<SObject> masterRecordList = masterRecords.values();
List<Database.Saveresult> saveResults = Database.update(masterRecordList, false);
List<Database.Saveresult> saveResults = updateRecords(masterRecordList, false, false);

// Log errors to the summary log
Integer masterRecordIdx = 0;
Expand Down Expand Up @@ -549,5 +553,48 @@ global with sharing class RollupService
RollupSummaries.OPERATION_PICKLIST_TO_ENUMS.get(lookup.AggregateOperation__c)));
}
return engineCtxByParentRelationship;
}
}

/**
* Wrapper around DML allowing with or without sharing to be applied and all or nothing exception handling
**/
private static List<Database.Saveresult> updateRecords(List<SObject> masterRecords, Boolean withSharing, Boolean allOrNothing)
{
return withSharing ?
new UpdateWithSharing(masterRecords).updateRecords(allOrNothing) :
new UpdateWithoutSharing(masterRecords).updateRecords(allOrNothing);
}

private virtual class Updater
{
protected List<SObject> masterRecords;

public Updater(List<SObject> masterRecords)
{
this.masterRecords = masterRecords;
}

public virtual List<Database.Saveresult> updateRecords(boolean allOrNothing)
{
return Database.update(masterRecords, allOrNothing);
}
}

private with sharing class UpdateWithSharing extends Updater
{
public UpdateWithSharing(List<SObject> masterRecords)
{ super(masterRecords); }

public override List<Database.Saveresult> updateRecords(boolean allOrNothing)
{ return super.updateRecords(allOrNothing); }
}

private without sharing class UpdateWithoutSharing extends Updater
{
public UpdateWithoutSharing(List<SObject> masterRecords)
{ super(masterRecords); }

public override List<Database.Saveresult> updateRecords(boolean allOrNothing)
{ return super.updateRecords(allOrNothing); }
}
}
247 changes: 247 additions & 0 deletions rolluptool/src/classes/RollupServiceTest3.cls
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,72 @@ private with sharing class RollupServiceTest3
System.assertEquals(1, logs.size());
System.assertEquals('The answer is not 42! : FIELD_CUSTOM_VALIDATION_EXCEPTION (dlrs__Total__c)', logs[0].ErrorMessage__c);
}

private testmethod static void testCalculateJobNotActive()
{
// Test supported?
if(!TestContext.isSupported())
return;

// Insert parents
Schema.SObjectType parentType = Schema.getGlobalDescribe().get('dlrs__LookupParent__c');
SObject parentA = parentType.newSObject();
parentA.put('Name', 'ParentA');
SObject parentB = parentType.newSObject();
parentB.put('Name', 'ParentB');
SObject parentC = parentType.newSObject();
parentC.put('Name', 'ParentC');
List<SObject> parents = new List<SObject> { parentA, parentB, parentC };
insert parents;

// Insert children
Schema.SObjectType childType = Schema.getGlobalDescribe().get('dlrs__LookupChild__c');
List<SObject> children = new List<SObject>();
for(SObject parent : parents)
{
String name = (String) parent.get('Name');
SObject child1 = childType.newSObject();
child1.put('dlrs__LookupParent__c', parent.Id);
child1.put('dlrs__Amount__c', 20);
children.add(child1);
SObject child2 = childType.newSObject();
child2.put('dlrs__LookupParent__c', parent.Id);
child2.put('dlrs__Amount__c', 20);
children.add(child2);
if(name.equals('ParentA') || name.equals('ParentB'))
{
SObject child3 = childType.newSObject();
child3.put('dlrs__LookupParent__c', parent.Id);
child3.put('dlrs__Amount__c', 2);
children.add(child3);
}
}
insert children;

// Create rollup AFTER the data exists
LookupRollupSummary__c rollupSummary = new LookupRollupSummary__c();
rollupSummary.Name = 'Test Rollup';
rollupSummary.ParentObject__c = 'dlrs__LookupParent__c';
rollupSummary.ChildObject__c = 'dlrs__LookupChild__c';
rollupSummary.RelationShipField__c = 'dlrs__LookupParent__c';
rollupSummary.FieldToAggregate__c = 'dlrs__Amount__c';
rollupSummary.AggregateOperation__c = RollupSummaries.AggregateOperation.Sum.name();
rollupSummary.AggregateResultField__c = 'dlrs__Total__c';
rollupSummary.Active__c = false;
rollupSummary.CalculationMode__c = 'Scheduled';
insert rollupSummary;

// Run rollup calculate job
Test.startTest();
try {
// Assert not possible to start another
RollupService.runJobToCalculate(rollupSummary.Id);
System.assert(false, 'Expected an exception');
} catch (Exception e) {
System.assert(e.getMessage().equals('The rollup must be Active before you can run a Calculate job.'));
}
Test.stopTest();
}

private testmethod static void testDeveloperAPI()
{
Expand Down Expand Up @@ -204,4 +270,185 @@ private with sharing class RollupServiceTest3
System.assertEquals(42, (Decimal) assertParents.get(parentB.id).get('dlrs__Total__c'));
System.assertEquals(40, (Decimal) assertParents.get(parentC.id).get('dlrs__Total__c'));
}


/**
* https://github.com/afawcett/declarative-lookup-rollup-summaries/issues/23
*/
private testmethod static void testDateRollupDeleteChild()
{
// Test supported?
if(!TestContext.isSupported())
return;

// Configure rollup
LookupRollupSummary__c rollupSummary = new LookupRollupSummary__c();
rollupSummary.Name = 'Total Opportunities greater than 200 into Annual Revenue on Account';
rollupSummary.ParentObject__c = 'Account';
rollupSummary.ChildObject__c = 'Opportunity';
rollupSummary.RelationShipField__c = 'AccountId';
rollupSummary.RelationShipCriteria__c = null;
rollupSummary.FieldToAggregate__c = 'CloseDate';
rollupSummary.AggregateOperation__c = 'Max';
rollupSummary.AggregateResultField__c = 'SLAExpirationDate__c';
rollupSummary.Active__c = true;
rollupSummary.CalculationMode__c = 'Realtime';
insert new List<LookupRollupSummary__c> { rollupSummary };

// Test data
Account account = new Account();
account.Name = 'Test Account';
account.AnnualRevenue = 0;
insert account;
Opportunity opp = new Opportunity();
opp.Name = 'Test Opportunity';
opp.StageName = 'Open';
opp.CloseDate = System.today();
opp.AccountId = account.Id;
opp.Amount = 100;
insert opp;

// Assert rollup
Id accountId = account.Id;
System.assertEquals(System.today(), Database.query('select SLAExpirationDate__c from Account where Id = :accountId')[0].get(ACCOUNT_SLA_EXPIRATION_DATE));

// Delete Opportunity
delete opp;

// Assert rollup
System.assertEquals(null, Database.query('select SLAExpirationDate__c from Account where Id = :accountId')[0].get(ACCOUNT_SLA_EXPIRATION_DATE));
}

/**
* https://github.com/afawcett/declarative-lookup-rollup-summaries/issues/23
*/
private testmethod static void testDateRollupInsertConditionalChild()
{
// Test supported?
if(!TestContext.isSupported())
return;

// Configure rollup
LookupRollupSummary__c rollupSummary = new LookupRollupSummary__c();
rollupSummary.Name = 'Total Opportunities greater than 200 into Annual Revenue on Account';
rollupSummary.ParentObject__c = 'Account';
rollupSummary.ChildObject__c = 'Opportunity';
rollupSummary.RelationShipField__c = 'AccountId';
rollupSummary.RelationShipCriteria__c = 'CloseDate < TODAY';
rollupSummary.FieldToAggregate__c = 'CloseDate';
rollupSummary.AggregateOperation__c = 'Max';
rollupSummary.AggregateResultField__c = 'SLAExpirationDate__c';
rollupSummary.Active__c = true;
rollupSummary.CalculationMode__c = 'Realtime';
insert new List<LookupRollupSummary__c> { rollupSummary };

// Test data
Account account = new Account();
account.Name = 'Test Account';
account.AnnualRevenue = 0;
insert account;
Opportunity opp = new Opportunity();
opp.Name = 'Test Opportunity';
opp.StageName = 'Open';
opp.CloseDate = System.today();
opp.AccountId = account.Id;
opp.Amount = 100;
insert opp;

// Assert rollup
Id accountId = account.Id;
System.assertEquals(null, Database.query('select SLAExpirationDate__c from Account where Id = :accountId')[0].get(ACCOUNT_SLA_EXPIRATION_DATE));

// Delete Opportunity
delete opp;

// Assert rollup
System.assertEquals(null, Database.query('select SLAExpirationDate__c from Account where Id = :accountId')[0].get(ACCOUNT_SLA_EXPIRATION_DATE));
}

private testmethod static void testRollupWithInAccessibleParent()
{
// Test supported?
if(!TestContext.isSupported())
return;

// Configure rollup
LookupRollupSummary__c rollupSummary = new LookupRollupSummary__c();
rollupSummary.Name = 'Test Rollup';
rollupSummary.ParentObject__c = 'dlrs__LookupParent__c';
rollupSummary.ChildObject__c = 'dlrs__LookupChild__c';
rollupSummary.RelationShipField__c = 'dlrs__LookupParent__c';
rollupSummary.FieldToAggregate__c = 'dlrs__Amount__c';
rollupSummary.AggregateOperation__c = RollupSummaries.AggregateOperation.Sum.name();
rollupSummary.AggregateResultField__c = 'dlrs__Total__c';
rollupSummary.Active__c = true;
rollupSummary.CalculationMode__c = 'Realtime';
insert rollupSummary;

// Insert parents
Schema.SObjectType parentType = Schema.getGlobalDescribe().get('dlrs__LookupParent__c');
SObject parentA = parentType.newSObject();
parentA.put('Name', 'ParentA');
insert parentA;

// Insert children
Schema.SObjectType childType = Schema.getGlobalDescribe().get('dlrs__LookupChild__c');
SObject child1 = childType.newSObject();
child1.put('dlrs__LookupParent__c', parentA.Id);
insert child1;

// Assert rollup
Map<Id, SObject> assertParents = new Map<Id, SObject>(Database.query('select id, dlrs__Total__c from dlrs__LookupParent__c'));
System.assertEquals(null, (Decimal) assertParents.get(parentA.id).get('dlrs__Total__c'));

// Create test user
User testUser = null;
System.runAs ( new User(Id = UserInfo.getUserId()) ) {
testUser = createUser();
}

// Test data insert children as new user (who cannot see the parent)
System.runAs(testUser)
{
// Ensure this user can read it (the Sharing setting for LookupParent__c is Public Read Only)
assertParents = new Map<Id, SObject>(Database.query('select id, dlrs__Total__c from dlrs__LookupParent__c'));
System.assertEquals(null, (Decimal) assertParents.get(parentA.id).get('dlrs__Total__c'));

// Attempt to indirectly via rollup trigger to update parent record
child1.put('dlrs__Amount__c', 42);
update child1;
}

// Assert rollup
assertParents = new Map<Id, SObject>(Database.query('select id, dlrs__Total__c from dlrs__LookupParent__c'));
System.assertEquals(42, (Decimal) assertParents.get(parentA.id).get('dlrs__Total__c'));
}

/**
* Create test user
**/
private static User createUser()
{
// Can only proceed with test if we have a suitable profile
List<Profile> testProfiles = [Select Id From Profile where Name='Standard User' limit 1];
if(testProfiles.size()!=1)
return null;

// Can only proceed with test if we can successfully insert a test user
String testUsername = System.now().format('yyyyMMddhhmmss') + '@testorg.com';
User testUser = new User(Alias = 'test1', Email='[email protected]', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', LocaleSidKey='en_US', ProfileId = testProfiles[0].Id, TimeZoneSidKey='America/Los_Angeles', UserName=testUsername);
try {
insert testUser;

// Assign permission sets
Set<String> psNames = new Set<String> { 'LookupRollupSummariesFull', 'LookupRollupSummariesTest' };
List<PermissionSet> ps = [select Id from PermissionSet where Name in :psNames];
insert new List<PermissionSetAssignment> {
new PermissionSetAssignment(AssigneeId = testUser.Id, PermissionSetId = ps[0].Id),
new PermissionSetAssignment(AssigneeId = testUser.Id, PermissionSetId = ps[1].Id) };
} catch (Exception e) {
return null;
}
return testUser;
}
}
Loading

0 comments on commit 0c8168c

Please sign in to comment.