Untitled
unknown
apex
a year ago
4.8 kB
11
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