Untitled
unknown
apex
a year ago
4.8 kB
7
Indexable
public abstract with sharing class halo_SObjectRollupsCalculator { public void recalculate(List<SObject> sObjects, TriggerContext triggerContext) { for (SObject sObj : sObjects) { SObjectType sObjType = sObj.getSObjectType(); for (SObjectTypeCustomRollups rollups : this.getCustomRollups().get(sObjType)) { rollups.initialize(sObj, triggerContext); } } List<SObject> ancestorsToUpdate = new List<SObject>(); for (SObjectTypeCustomRollups customRollups : this.getCustomRollups().values()) { rollups.recalculate(); ancestorsToUpdate.addAll(rollups.getUpdatedRecords()); } update ancestorsToUpdate; } protected abstract Map<SObjectType, SObjectTypeCustomRollups> getCustomRollups(); protected abstract SObjectType getAncestorSObjectType(); public abstract with sharing class SObjectTypeCustomRollups { private Map<Id, SObject> updatedRecords = new Map<Id, SObject>(); public void initialize(SObject sObj, TriggerContext triggerContext) { for (CustomRollup rollup : this.getRollups()) { rollup.initialize(sObj, triggerContext); } } public void recalculate() { List<CustomRollup> rollupsToRecalculate = this.getRollupsToRecalculate(); if (!rollupsToRecalculate.isEmpty()) { RollupSelector selector = new RollupSelector(rollupsToRecalculate, this.getRelationshipField(), this.getSObjectType()); Map<Id, SObject> ancestors = selector.getAncestors(); List<SObject> descendants = selector.getDescendants(); for (CustomRollup rollup : rollupsToRecalculate) { rollup.recalculate(ancestors, descendants); for (Id recordId : rollup.getUpdatedRecordIds()) { this.updatedRecords.put(recordId, ancestors.get(recordId)); } } } } public Set<SObject> getUpdatedRecords() { return this.updatedRecords; } protected abstract List<CustomRollup> getRollups(); protected abstract SObjectType getSObjectType(); protected abstract String getRelationshipField(); private List<CustomRollup> getRollupsToRecalculate() { List<CustomRollup> customRollups = new List<CustomRollup>(); for (CustomRollup rollup : this.getRollups()) { if (rollup.shouldRecalculate()) { customRollups.add(rollup); } } return customRollups; } } public interface CustomRollup { void initialize(SObject sObj, TriggerContext triggerContext); void recalculate(Map<Id, SObject> ancestors, List<SObject> descendants); Boolean shouldRecalculate(); Set<SObjectField> getDescendantQueryFields(); Set<SObjectField> getAncestorQueryFields(); Set<Id> getAncestorRecordIds(); Set<Id> getUpdatedRecordIds(); } private with sharing class RollupSelector() { private List<CustomRollup> customRollups; private String relationshipField; private SObjectType ancestorSObjectType; public RollupSelector(List<CustomRollup> customRollups, String relationshipField, SObjectType ancestorSObjectType) { this.customRollups = customRollups; this.relationshipField = relationshipField; this.ancestorSObjectType = ancestorSObjectType; } public Map<Id, SObject> getAncestors() { Set<SObjectField> fields = new Set<SObjectField>(); Set<Id> recordIds = new Set<Id>(); for (List<CustomRollup> rollups : this.customRollups) { for (CustomRollup rollup : rollups) { fields.addAll(rollup.getAncestorQueryFields()); recordIds.addAll(rollup.getAncestorRecordIds()); } } return Database.query(String.format('SELECT {0} FROM {1} WHERE {2}', new List<Object> { fields, this.ancestorSObjectType + '', 'Id IN :recordIds' })); } public List<SObject> getDescendants() { Set<SObjectField> fields = new Set<SObjectField>(); Set<Id> ancestorRecordIds = new Set<Id>(); for (CustomRollup rollup : this.customRollups) { fields.addAll(rollup.getDescendantQueryFields()); ancestorRecordIds.addAll(rollup.getAncestorRecordIds()); } return Database.query(String.format('SELECT {0} FROM {1} WHERE {2}', new List<Object> { fields, sObjType + '', this.relationshipField + ' IN :ancestorRecordIds' }))); } } }
Editor is loading...
Leave a Comment