function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
joseph keuler 1joseph keuler 1 

How to use before update and after insert trigger

So I have a trigger that I want to run everytime a record is updated and created. However, when I use after insert and before update I get a record is locked error when creating the record.

How can I run this trigger on both record edit and creation (it only works before update)?   Better yet, is it possible to update any record "after update" or "after insert"?
 
trigger CalcBenefit on EA_App__c (before update, after insert) {
//works for update only.  insert throws error because I'm trying to change value
for (EA_App__C ea : Trigger.new){

    EA_App__C oldEA = Trigger.oldMap.get(ea.Id);

    if (ea.X3_Month_Income__c > CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c))){
        ea.App_Status__c = 'DENIED';            
        ea.Benefit_Amount__c = 0;                 

    }else if (ea.X3_Month_Income__c <= CalculateBenefit.getMin(integer.valueOf(ea.Family_Size__c)) && ea.App_Status__c != 'PAID'){
        //how to compare to old? 
        //&& (ea.X3_Month_Income__c != oldEA.X3_Month_Income__c || ea.Family_Size__c != oldEA.Family_Size__c)
        ea.Benefit_Amount__c = 0;                 
        ea.App_Status__c = 'SENT FOR APPROVAL';                

    }else{
        ea.App_Status__c = 'PAID';
        ea.Benefit_Amount__c = CalculateBenefit.calc(ea.X3_Month_Income__c, integer.valueOf(ea.Family_Size__c), ea.Fuel_Cost__c, '2015');
    }

}

 
Best Answer chosen by joseph keuler 1
Michael WelburnMichael Welburn
Have you taken a look at what the use cases are for before vs after triggers? This is a helpful link - http://www.sfdc99.com/2014/01/25/use-vs-triggers/

Typically you would use a before trigger to update a field on the object being saved (perhaps a calculation too complex for configuration) whereas an after trigger would fire something related off, perhaps an update to another object. In your case, after update and before insert, because you want to set fields on the object being modified, will end up firing the same trigger twice.

I believe the reason you are having locking problems is because while you are using after insert and modifying the fields on your object, you aren't even saving them with a subsequent update call (so they just remain modified but unsaved after after insert runs). You will likely want to convert your existing logic to before insert, before update.

All Answers

Michael WelburnMichael Welburn
Have you taken a look at what the use cases are for before vs after triggers? This is a helpful link - http://www.sfdc99.com/2014/01/25/use-vs-triggers/

Typically you would use a before trigger to update a field on the object being saved (perhaps a calculation too complex for configuration) whereas an after trigger would fire something related off, perhaps an update to another object. In your case, after update and before insert, because you want to set fields on the object being modified, will end up firing the same trigger twice.

I believe the reason you are having locking problems is because while you are using after insert and modifying the fields on your object, you aren't even saving them with a subsequent update call (so they just remain modified but unsaved after after insert runs). You will likely want to convert your existing logic to before insert, before update.
This was selected as the best answer
Abhishek BansalAbhishek Bansal
Hi Joseph,

i have modified your trigger code as per your requiremnet.
Please use the below updated code in your trigger :
trigger CalcBenefit on EA_App__c (before insert, before update) {
	for (EA_App__C ea : Trigger.new){
		if((trigger.isInsert && ea.X3_Month_Income__c > CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c))) || (trigger.isUpdate && Trigger.oldMap.get(ea.Id).X3_Month_Income__c != ea.X3_Month_Income__c && ea.X3_Month_Income__c > CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c)))){
			ea.App_Status__c = 'DENIED';            
			ea.Benefit_Amount__c = 0;
		}
		else if((trigger.isInsert && ea.X3_Month_Income__c <= CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c)) && ea.App_Status__c != 'PAID') || (trigger.isUpdate && (Trigger.oldMap.get(ea.Id).X3_Month_Income__c != ea.X3_Month_Income__c || Trigger.oldMap.get(ea.Id).App_Status__c != ea.App_Status__c ) && ea.App_Status__c != 'PAID' && ea.X3_Month_Income__c <= CalculateBenefit.getMax(integer.valueOf(ea.Family_Size__c)))) {
			ea.Benefit_Amount__c = 0;                 
			ea.App_Status__c = 'SENT FOR APPROVAL';  
		}
		else{
			ea.App_Status__c = 'PAID';
			ea.Benefit_Amount__c = CalculateBenefit.calc(ea.X3_Month_Income__c, integer.valueOf(ea.Family_Size__c), ea.Fuel_Cost__c, '2015');
		}
	}
}

Please let me know if you have any issue or if you want any information regarding this code.

Thanks,
Abhishek