Untitled
unknown
java
a year ago
9.9 kB
11
Indexable
// halo_CustomRollup
public interface halo_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();
}
// halo_SObjectTypeCustomRollups
public abstract with sharing class halo_SObjectTypeCustomRollups {
private final DescendantsSelector selector;
private Map<Id, SObject> updatedRecords = new Map<Id, SObject>();
protected SObjectTypeCustomRollups() {
this.selector = new DescendantsSelector(getRelationshipField(), getSObjectType());
}
public void initialize(SObject sObj, TriggerContext triggerContext) {
for (halo_CustomRollup rollup : this.getRollups()) {
rollup.initialize(sObj, triggerContext);
}
}
public void recalculate(Map<Id, SObject> ancestors) {
List<halo_CustomRollup> rollupsToRecalculate = this.getRollupsToRecalculate();
if (!rollupsToRecalculate.isEmpty()) {
this.selector.addCustomRollups(rollupsToRecalculate);
List<SObject> descendants = this.selector.getDescendants();
for (halo_CustomRollup rollup : rollupsToRecalculate) {
rollup.recalculate(ancestors, descendants);
this.summarizeUpdatedRecords(rollup);
}
}
}
private void summarizeUpdatedRecords(halo_CustomRollup rollup) {
for (Id recordId : rollup.getUpdatedRecordIds()) {
updatedRecords.put(recordId, ancestors.get(recordId));
}
}
public Set<SObject> getUpdatedRecords() {
return updatedRecords.values();
}
public Set<SObjectField> getAncestorFields() {
Set<SObjectField> ancestorFields = new Set<SObjectField>();
for (halo_CustomRollup rollup : this.getRollups()) {
ancestorFields.addAll(rollup.getAncestorQueryFields());
}
return ancestorFields;
}
public Set<Id> getAncestorRecordIds() {
Set<Id> ancestorRecordIds = new Set<Id>();
for (halo_CustomRollup rollup : this.getRollups()) {
ancestorRecordIds.addAll(rollup.getAncestorRecordIds());
}
return ancestorRecordIds;
}
protected abstract List<halo_CustomRollup> getRollups();
protected abstract SObjectType getSObjectType();
protected abstract String getRelationshipField();
private List<halo_CustomRollup> getRollupsToRecalculate() {
List<halo_CustomRollup> customRollups = new List<halo_CustomRollup>();
for (halo_CustomRollup rollup : this.getRollups()) {
if (rollup.shouldRecalculate()) {
customRollups.add(rollup);
}
}
return customRollups;
}
private with sharing class DescendantsSelector() {
private final String relationshipField;
private final SObjectType sObjType;
private Set<SObjectField> fields = new Set<SObjectField>();
private Set<Id> ancestorRecordIds = new Set<Id>();
public DescendantsSelector(String relationshipField, SObjectType sObjType) {
this.relationshipField = relationshipField;
this.sObjType = sObjType;
}
public void addCustomRollups(List<halo_CustomRollup> customRollups) {
for (halo_CustomRollup rollup : customRollups) {
this.fields.addAll(rollup.getDescendantQueryFields());
this.ancestorRecordIds.addAll(rollup.getAncestorRecordIds());
}
}
public List<SObject> getRecords() {
return Database.query(String.format('SELECT {0} FROM {1} WHERE {2}', new List<Object> { this.fields, this.sObjType + '', this.relationshipField + ' IN :this.ancestorRecordIds' })));
}
}
}
// halo_SObjectRollupsCalculator
public abstract with sharing class halo_SObjectRollupsCalculator {
public void recalculate(List<SObject> sObjects, TriggerContext triggerContext) {
this.initializeRollups(sObjects, triggerContext);
Map<Id, SObject> ancestors = this.fetchAncestorRecords();
List<SObject> updatedAncestors = this.processRecalculations(ancestors);
update updatedAncestors;
}
private void initializeRollups(List<SObject> sObjects, TriggerContext triggerContext) {
for (SObject sObj : sObjects) {
SObjectType sObjType = sObj.getSObjectType();
for (halo_SObjectTypeCustomRollups rollup : this.getCustomRollups().get(sObjType)) {
rollup.initialize(sObj, triggerContext);
}
}
}
private Map<Id, SObject> fetchAncestorRecords() {
AncestorSelector selector = new AncestorSelector(this.getAncestorSObjectType());
for (halo_SObjectTypeCustomRollups customRollup : this.getCustomRollups().values()) {
selector.addFields(customRollup.getAncestorFields());
selector.addRecordIds(customRollup.getAncestorRecordIds());
}
return selector.getRecords();
}
private List<SObject> processRecalculations(Map<Id, SObject> ancestors) {
List<SObject> ancestorsToUpdate = new List<SObject>();
for (halo_SObjectTypeCustomRollups customRollup : this.getCustomRollups().values()) {
customRollup.recalculate(ancestors);
ancestorsToUpdate.addAll(customRollup.getUpdatedRecords());
}
return ancestorsToUpdate;
}
protected abstract Map<SObjectType, halo_SObjectTypeCustomRollups> getCustomRollups();
protected abstract SObjectType getAncestorSObjectType();
private with sharing class AncestorSelector() {
private final SObjectType ancestorSObjectType;
private Set<SObjectField> fields = new Set<SObjectField>();
private Set<Id> recordIds = new Set<Id>();
public AncestorSelector(SObjectType ancestorSObjectType) {
this.ancestorSObjectType = ancestorSObjectType;
}
public void addFields(Set<SObjectField> fields) {
this.fields.addAll(fields);
}
public void addRecordIds(Set<Id> recordIds) {
this.recordIds.addAll(recordIds);
}
public Map<Id, SObject> getRecords() {
return Database.query(String.format('SELECT {0} FROM {1} WHERE {2}', new List<Object> { this.fields, this.ancestorSObjectType + '', 'Id IN :this.recordIds' }));
}
}
}
// halo_TourRollupsCalculator
public with sharing class halo_TourRollupsCalculator extends halo_SObjectRollupsCalculator {
private static final Map<SObjectType, halo_SObjectTypeCustomRollups> CUSTOM_ROLLUPS = new Map<SObjectType, halo_SObjectTypeCustomRollups> {
Ticket_Hold__c.SObjectType => new ()
};
protected override Map<SObjectType, halo_SObjectTypeCustomRollups> getCustomRollups() {
return halo_TourRollupsCalculator.CUSTOM_ROLLUPS;
}
protected override SObjectType getAncestorSObjectType() {
return Tour__c.SObjectType;
}
private with sharing class TicketHoldCustomRollups extends halo_SObjectTypeCustomRollups {
private final List<halo_CustomRollup> rollups = new List<halo_CustomRollup> {
new TicketHoldComplimentaryRollup()
};
protected override List<halo_CustomRollup> getRollups() {
return this.rollups;
}
protected override SObjectType getSObjectType() {
return Ticket_Hold__c.SObjectType;
}
protected abstract String getRelationshipField() {
return 'Ticket_Band__r.Show__r.Tour__c';
}
}
private with sharing class TicketHoldComplimentaryRollup implements halo_CustomRollup {
private Set<Id> ancestorRecordIds = new Set<Id>();
private Set<Id> updatedRecordIds = new Set<Id>();
public void initialize(SObject sObj, TriggerContext triggerContext) {
Ticket_Hold__c ticketHold = (Ticket_Hold__c) sObj;
if ((triggerContext.isNew() || triggerContext.isChanged(sObj, Ticket_Hold__c.Complimentary__c)) && ticketHold.Ticket_Band__r.Show__r.Show_Status__c != 'Cancelled' && ticketHold.Ticket_Band__r.Show__r.Onsales_Date__c != null) {
this.ancestorRecordIds.add(ticketHold.Ticket_Band__r.Show__r.Tour__c);
}
}
public void recalculate(Map<Id, SObject> ancestors, Map<Id, List<SObject>> descendants) {
for (Id ancestorRecordId : this.ancestorRecordIds) {
Tour__c tour = (Tour__c) ancestors.get(ancestorRecordId);
Integer complimentarySum = 0;
for (Ticket_Hold__c descendant : (List<Ticket_Hold__c>) descendants.get(tour.Id)) {
if (descendant.Complimentary__c != null) {
complimentarySum += descendant.Complimentary__c;
}
}
if (tour.Comp_Holds__c != complimentarySum) {
tour.Comp_Holds__c = complimentarySum;
updatedRecordIds.add(tour.Id);
}
}
}
public Boolean shouldRecalculate() {
return !this.ancestorRecordIds.isEmpty();
}
public Set<SObjectField> getDescendantQueryFields() {
return new Set<SObjectField> {
Ticket_Hold__c.Complimentary__c
};
}
public Set<SObjectField> getAncestorQueryFields() {
return new Set<SObjectField> {
Ticket_Hold__c.Comp_Holds__c
};
}
public Set<Id> getAncestorRecordIds() {
return this.ancestorRecordIds;
}
public Set<Id> getUpdatedRecordIds() {
return this.updatedRecordIds;
}
}
}Editor is loading...
Leave a Comment