You need to sign in to do that
Don't have an account?
Trigger to update Parent role ID in Opportunity
HI there,
working on a trigger too get the parent role of the opportunity Owner user, as I beleive I can;t do it using a formula in SF. If possible please let me know. But my issue is that the trigger bellow will not let me update the field "Manager_role__C" as the error says that "Can't execute the After Update" as record is read only . Tried to change the trigger to "before update" and got another error as it says " execution of BeforeUpdate caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old: Trigger.AboveRole: line 20, column 1"
Pretty sure it is a simple thing in my code but driving me crazy as usual.. Not sure also if this is becasue I have other triggers in the Oppt object , all 'After update" but they will change values in other objects than the Oppt itself. Here is the code:
trigger AboveRole on Opportunity (before insert, before update) { Set<Id> recordIds = new Set<Id>(); Set<Id> acctIds = new Set<Id>(); Set<Id> userIds = new Set<Id>(); Set<Id> roleIds = new Set<Id>(); for(opportunity S:Trigger.new) if(S.type == 'Renewal'){ recordIds.add(S.id); acctIds.add(S.accountid); userIds.add(S.ownerid); List<User> RoleUSer = [Select userroleID from USER where id in :userids]; roleIds.add(RoleUser[0].userroleID); List<Userrole> roleparent =[Select parentroleid from userrole where id in:roleIds]; IF (roleparent.size() > 0){ S.manager_role__C = roleparent[0].parentroleid; update s; } } }
Hello,
With a before trigger, you do not need to call an update for Trigger.new since the dataset hasn't been written yet. So to take your code for example:
IF (roleparent.size() > 0){
S.manager_role__C = roleparent[0].parentroleid;
}
This is all you would need since S is an opportunity record from Trigger.new and the manager_role__c field has been updated with the roleParent[0].parentroleid before the insert or update.
If for whatever reason, you DID want the trigger to occur on an after update, you could always do the following:
List<Opportunity> oppsToUpdate = [Select Id From Opportunity where Id in: Trigger.new];
And then update the oppsToUpdate list.
Also as an FYI, please be careful about your triggers not being bulkified. I notice you have an update s; inside a for loop. While this wont be a problem if you remove the update s, in the future you would want to add the changed records (in this case Opportunity S) to a list and then at the end update the list.
Hope this helps!
All Answers
Hello,
With a before trigger, you do not need to call an update for Trigger.new since the dataset hasn't been written yet. So to take your code for example:
IF (roleparent.size() > 0){
S.manager_role__C = roleparent[0].parentroleid;
}
This is all you would need since S is an opportunity record from Trigger.new and the manager_role__c field has been updated with the roleParent[0].parentroleid before the insert or update.
If for whatever reason, you DID want the trigger to occur on an after update, you could always do the following:
List<Opportunity> oppsToUpdate = [Select Id From Opportunity where Id in: Trigger.new];
And then update the oppsToUpdate list.
Also as an FYI, please be careful about your triggers not being bulkified. I notice you have an update s; inside a for loop. While this wont be a problem if you remove the update s, in the future you would want to add the changed records (in this case Opportunity S) to a list and then at the end update the list.
Hope this helps!
Thanks a lot and really, thatks for the heads up on the bukifying ! that solved my problem.