You need to sign in to do that
Don't have an account?
Trigger Bizzare bihavior with and without Data Loader
Hello Fellas,
I was advised to post here. Maybe you will be able to help.
I cannot get this trigger to work upon Data Loader Account upsert.
It works when I do the changes within the application (UI), but it does not when I change the account owner of using the Data Loader. When I use the Data Loader to upsert account ownership, it changes ownership of ALL opportunities in ALL accounts no matter whether account owner for a particular opportunity has changed or not.
Objective: After A Data Loader account upsert - Check IF an owner of an opportunity is NOT the owner of the account and a sharing person of the account,
THEN change owner of that opportunity to the NEW owner of the account to which that opportunity pertains.
For this purpose there is a custom field in account called SLS2__c, which is updated each time accounts are upserted. This field contains the 15 character SF UserID of the person who shares the account.
trigger updateOppOwner on Account (after insert, after update) {
if (Trigger.isAfter) {
Set<Id> acctIds = new Set<Id>();
for (Account acct : Trigger.new) {
acctIds.add(acct.Id);
}
List<Opportunity> optyList = [SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds];
if ( !optyList.isEmpty() ) {
for (Account acct : Trigger.new) {
for(Opportunity opty : optyList ) {
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
opty.OwnerId = acct.OwnerID;
} else {
opty.OwnerId = opty.OwnerId ;
}
}
update optyList;
}
}
}
}
Again, the trigger works when account ownership is changed manually, but when I use the Data Loader, it changes ownership of ALL opportunities in ALL accounts no matter whether account owner for a particular opportunity has changed or not.
Do you have any suggestions?
One thing that is troubling to me is that you are updating the optylist inside the for loops.
You should update the list outside of the for loops.
Joe,
Arizona is right you should be updating the list outside the for loop.
Another thing,I can see you can check that if event is insert or update.What I mean to say is :
if(Trigger.isInsert){
// do your coding here
}
else if (Trigger.Isupdate){
for (Account newAcc: Trigger.new){
Account oldAcc = trigger.oldmap.get(newAcc.id);
if(oldAcc.OwnerId != newAcc.ownerId){ // this would check whether Account owner has been updated or not.
// do your coding here
}
}
}
Thank you for the response.
<<Another thing,I can see you can check that if event is insert or update.>>
I am not sure exactly what you mean. I am not very familiar with programming.
Currently, with Data Loader Upsert, the trigger updates all opportunities, even those that are not updated or inserted.
But the thing is that all existing accounts should be updated on a daily basis with account information such as statistics, no matter whether they change owners or not. So basically all accounts are updated. New accounts are inserted. Therefore we will have to use upsert.
Is there a solution with this Data Loader issue in your opinion?
Joe,
I was saying that in your Trigger you can check whether it is an update event or insert event and based on that you can manipulate your code as per your requirement.
Please go through the below link to know more about Trigger context variables i.e. isInsert or isUpdate
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables.htm
Thanks.
I will substitute isAfter with isUpdate and will test it.
But I cannot code it any further. I lack the knowledge to do so.
This is another explanation that I received from the community board:
<<The error is in the following line.
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
Say I have Account A, with OppA, Opp B and Account C with OppD, OppE
First it checks whether the oppty owner id of OppA!=Acccount A OwnerId
Then it checks whether oppty owner id of OppA!=Account B OwnerId
and hence it updates all the oppty ids with the new account id.
There should be an additional check whether the Account is the related account of the opportunity being compared. >>
Does anyone have any idea how to fix that?
Change your code from
List<Opportunity> optyList = [SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds];
if ( !optyList.isEmpty() ) {
for (Account acct : Trigger.new) {
for(Opportunity opty : optyList ) {
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
opty.OwnerId = acct.OwnerID;
} else {
opty.OwnerId = opty.OwnerId ;
}
}
update optyList;
}
}
}
}
to
Map<Id,Opportunity> optyMap = new Map<Id,Opportunit>([SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds]);
if ( !optyMap.isEmpty() ) {
for (Account acct : Trigger.new) {
if(optyMap.containsKey(acct.id)){ //this would check all the opportunity is with the related account
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
// Do your coding here
}
}
}
}
Thank you again Vinit.
I pasted your trigger:
============
trigger updateOppOwner on Account (after insert, after update) {
if (Trigger.isAfter) {
Set<Id> acctIds = new Set<Id>();
for (Account acct : Trigger.new) {
acctIds.add(acct.Id);
}
Map<Id,Opportunity> optyMap = new Map<Id,Opportunity>([SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds]);
if ( !optyMap.isEmpty() ) {
for (Account acct : Trigger.new) {
if(optyMap.containsKey(acct.id)){
//this would check all the opportunity is with the related account
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
opty.OwnerId = acct.OwnerID;
} else {
opty.OwnerId = opty.OwnerId ;
}
}
update optyList;
}
}
}
}
===============
It returned an error:
Line 14: opty.OwnerId = acct.OwnerID;
My bad,I forgot to add one line ,Please use below one :-
Map<Id,Opportunity> optyMap = new Map<Id,Opportunit>([SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds]);
if ( !optyMap.isEmpty() ) {
for (Account acct : Trigger.new) {
if(optyMap.containsKey(acct.id)){//this would check all the opportunity is with the related account
for(Opportunity opty : optyMap.values())
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
// Do your coding here
}
}
}
}
}
Thanks again.
I just tested it with the DL. It did not update any opportunity at all.
This is the trigger:
====
trigger updateOppOwner on Account (after insert, after update) {
if (Trigger.isAfter) {
Set<Id> acctIds = new Set<Id>();
for (Account acct : Trigger.new) {
acctIds.add(acct.Id);
}
Map<Id,Opportunity> optyMap = new Map<Id,Opportunit>([SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds]);
if ( !optyMap.isEmpty() ) {
for (Account acct : Trigger.new) {
if(optyMap.containsKey(acct.id)){//this would check all the opportunity is with the related account
for(Opportunity opty : optyMap.values())
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
opty.OwnerId = acct.OwnerID;
} else {
opty.OwnerId = opty.OwnerId ;
}
}
}
}
}
}
====
I just removed : <<update optyList;>> from the end because it was returning an error.
You are not updating any opportunity on ur code.so how u expect the opportunity to be updated.
After the for loop,please put below code : -
update optyMap.values();
I forgot to addd,this should work
Unfortunately, still cannot get this to work.
I included the update optyMap.values();
so the trigger looks like this:
<<<
trigger updateOppOwner on Account (after insert, after update) {
if (Trigger.isAfter) {
Set<Id> acctIds = new Set<Id>();
for (Account acct : Trigger.new) {
acctIds.add(acct.Id);
}
Map<Id,Opportunity> optyMap = new Map<Id,Opportunity>([SELECT OwnerId FROM Opportunity WHERE AccountId in :acctIds]);
if ( !optyMap.isEmpty() ) {
for (Account acct : Trigger.new) {
if(optyMap.containsKey(acct.id)){//this would check all the opportunity is with the related account
for(Opportunity opty : optyMap.values())
if(opty.OwnerId != acct.OwnerId && opty.OwnerId != acct.SLS2__c){
opty.OwnerId = acct.OwnerID;
} else {
opty.OwnerId = opty.OwnerId ;
}
}
update optyMap.values();
}
}
}
}
>>>
I tested upserting with Data Loader - It updated Account owner as it should, but did NOT update Opportunity owner when account owner had changed.
I also tried by removing the following:
} else {
opty.OwnerId = opty.OwnerId ;
It did not work either.