You need to sign in to do that
Don't have an account?
Sandy
How to combine two Triggers on same object ?
Hi!
Please can someone assist me with two triggers that I am trying to get working on for the Case object.
first trigget is for automatically assign entitlements to cases from email or web. and second one is complete resolution time when case is closed.
Here are the two triggers as currently written - appreciate that they probably need work! :-)
Thanks in advance.
Trigger 1
trigger DefaultEntitlement on Case (Before Insert, Before Update) {
Set<Id> contactIds = new Set<Id>();
Set<Id> acctIds = new Set<Id>();
for (Case c : Trigger.new) {
contactIds.add(c.ContactId);
acctIds.add(c.AccountId);
}
List <EntitlementContact> entlContacts =
[Select e.EntitlementId,e.ContactId,e.Entitlement.AssetId
From EntitlementContact e
Where e.ContactId in :contactIds
And e.Entitlement.EndDate >= Today
And e.Entitlement.StartDate <= Today];
if(entlContacts.isEmpty()==false){
for(Case c : Trigger.new){
if(c.EntitlementId == null && c.ContactId != null){
for(EntitlementContact ec:entlContacts){
if(ec.ContactId==c.ContactId){
c.EntitlementId = ec.EntitlementId;
if(c.AssetId==null && ec.Entitlement.AssetId!=null)
c.AssetId=ec.Entitlement.AssetId;
break;
}
}
}
}
} else{
List <Entitlement> entls = [Select e.StartDate, e.Id, e.EndDate,
e.AccountId, e.AssetId
From Entitlement e
Where e.AccountId in :acctIds And e.EndDate >= Today
And e.StartDate <= Today];
if(entls.isEmpty()==false){
for(Case c : Trigger.new){
if(c.EntitlementId == null && c.AccountId != null){
for(Entitlement e:entls){
if(e.AccountId==c.AccountId){
c.EntitlementId = e.Id;
if(c.AssetId==null && e.AssetId!=null)
c.AssetId=e.AssetId;
break;
}
}
}
}
}
}
}
Trigger 2
trigger CompleteResolutionTimeMilestone on Case (before update) {
if (UserInfo.getUserType() == 'Standard'){
DateTime completionDate = System.now();
List<Id> updateCases = new List<Id>();
for (Case c : Trigger.new){
if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate
<= completionDate)&&(c.SlaExitDate == null)))
updateCases.add(c.Id);
c.EntitlementId = null;
}
if (updateCases.isEmpty() == false)
milestoneUtils.completeMilestone(updateCases, 'Resolution Time', completionDate);
}
}
Please can someone assist me with two triggers that I am trying to get working on for the Case object.
first trigget is for automatically assign entitlements to cases from email or web. and second one is complete resolution time when case is closed.
Here are the two triggers as currently written - appreciate that they probably need work! :-)
Thanks in advance.
Trigger 1
trigger DefaultEntitlement on Case (Before Insert, Before Update) {
Set<Id> contactIds = new Set<Id>();
Set<Id> acctIds = new Set<Id>();
for (Case c : Trigger.new) {
contactIds.add(c.ContactId);
acctIds.add(c.AccountId);
}
List <EntitlementContact> entlContacts =
[Select e.EntitlementId,e.ContactId,e.Entitlement.AssetId
From EntitlementContact e
Where e.ContactId in :contactIds
And e.Entitlement.EndDate >= Today
And e.Entitlement.StartDate <= Today];
if(entlContacts.isEmpty()==false){
for(Case c : Trigger.new){
if(c.EntitlementId == null && c.ContactId != null){
for(EntitlementContact ec:entlContacts){
if(ec.ContactId==c.ContactId){
c.EntitlementId = ec.EntitlementId;
if(c.AssetId==null && ec.Entitlement.AssetId!=null)
c.AssetId=ec.Entitlement.AssetId;
break;
}
}
}
}
} else{
List <Entitlement> entls = [Select e.StartDate, e.Id, e.EndDate,
e.AccountId, e.AssetId
From Entitlement e
Where e.AccountId in :acctIds And e.EndDate >= Today
And e.StartDate <= Today];
if(entls.isEmpty()==false){
for(Case c : Trigger.new){
if(c.EntitlementId == null && c.AccountId != null){
for(Entitlement e:entls){
if(e.AccountId==c.AccountId){
c.EntitlementId = e.Id;
if(c.AssetId==null && e.AssetId!=null)
c.AssetId=e.AssetId;
break;
}
}
}
}
}
}
}
Trigger 2
trigger CompleteResolutionTimeMilestone on Case (before update) {
if (UserInfo.getUserType() == 'Standard'){
DateTime completionDate = System.now();
List<Id> updateCases = new List<Id>();
for (Case c : Trigger.new){
if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate
<= completionDate)&&(c.SlaExitDate == null)))
updateCases.add(c.Id);
c.EntitlementId = null;
}
if (updateCases.isEmpty() == false)
milestoneUtils.completeMilestone(updateCases, 'Resolution Time', completionDate);
}
}
You might have perfectly rational reasons why you have 2 triggers, but... Your triggers overlap in the "before update" event. You won't know which will fire first, and they might get queued in a way that it's not always the same. If timing is important, you will have to add complexity to control it. Unless this all works perfectly and you're sure you'll never add anything or have to perform maintenance, I'd fix merge the triggers first. Maybe that's where you're headed.
The other thing that seems sub-optimal is the amount of work being done in the trigger. This adds to your grief to merge the triggers.
I would recommend three things:
1. Use a single trigger per object (trigger CaseSave on Case)
2. Only qualify the record type (or similar inclusion/exclusion criteria)
3. Do all the work in a class or classes with helpful names (CaseEntitlement, CaseMilestone)
The trigger would look something like this: Your two classes would look like this:
CaseEntitlement.cls CaseMilestone.cls With this example you gain the benefit of controlling the timing, and filtering the cases if necessary. Each class method would execute on a list of cases similar to your existing trigger code. After your classes run, Salesforce will attempt to commit the data. I didn't really look at the details of your code since you were just asking about how to merge your triggers.
Please let me know if this solves your issue.
Best regards,
Ron
All Answers
You will need to use Trigger Context Variables and write a handler class to merge the triggers.
See examples provided in below articles to get started https://medium.com/elevate-salesforce/apex-trigger-framework-a-generic-way-to-join-tigger-contexts-46c4d9277db0
https://salesforce.stackexchange.com/questions/132421/combine-two-triggers
https://salesforce.stackexchange.com/questions/31535/merging-two-triggers-into-one
Thanks
You might have perfectly rational reasons why you have 2 triggers, but... Your triggers overlap in the "before update" event. You won't know which will fire first, and they might get queued in a way that it's not always the same. If timing is important, you will have to add complexity to control it. Unless this all works perfectly and you're sure you'll never add anything or have to perform maintenance, I'd fix merge the triggers first. Maybe that's where you're headed.
The other thing that seems sub-optimal is the amount of work being done in the trigger. This adds to your grief to merge the triggers.
I would recommend three things:
1. Use a single trigger per object (trigger CaseSave on Case)
2. Only qualify the record type (or similar inclusion/exclusion criteria)
3. Do all the work in a class or classes with helpful names (CaseEntitlement, CaseMilestone)
The trigger would look something like this: Your two classes would look like this:
CaseEntitlement.cls CaseMilestone.cls With this example you gain the benefit of controlling the timing, and filtering the cases if necessary. Each class method would execute on a list of cases similar to your existing trigger code. After your classes run, Salesforce will attempt to commit the data. I didn't really look at the details of your code since you were just asking about how to merge your triggers.
Please let me know if this solves your issue.
Best regards,
Ron