+ Start a Discussion
pdvaporpdvapor 

Update Lookup in Trigger

Hi All,

I am trying to update a Lookup Field on an Account with a Trigger.  Essentially I have a Custom Object (Box_Assumptions_c) related to an Account (Account1) and I want to update an a Custom Field (X9Box_Assumptions__c) on a different Account (Account2) with a Box Assumption that is related to Account1 by using the Owner's (Portal User) Contact Account (Account1).

 

trigger updatecustomer9box on Account (before insert, before update) {
    
    //Get Account ID of the current record.
    set<id> acctid = new set<id>();
    for (account a : trigger.new)
    acctid.add(a.owner.contact.account.id);
    
    map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>([select id 
                                                                     from box_assumptions__c
                                                                     where account__c in : acctid]);
    for (account a : trigger.new){
        box_assumptions__c thisbox = boxmap.get(a.x9box_assumptions__c);
        a.x9box_assumptions__c = thisbox.id;
    }
}

 I am getting a Null Pointer Exception so any advice would be helpful!

 

-Thanks in advance!

 

Best Answer chosen by Admin (Salesforce Developers) 
WizradWizrad
trigger updatecustomer9box on Account (after insert, after update) {
   if(!MyCoolTriggerUtilClass.isRunning) {
       MyCoolTriggerUtilClass.magicalSalesforceMethod(Trigger.new);
   }
}

public class MyCoolTriggerUtilClass {

    public static void isRunning = false;

    public static void magicalSalesforceMethod(List<Account> triggerNewList) {
        isRunning = true;

        //Get Account ID of the current record.
        set<id> acctid = new set<id>();
        List<Account> toUpdate = [SELECT Id, Owner.Contact.AccountId FROM Account WHERE Id in :triggerNewList];
        for (account a : toUpdate)
            acctid.add(a.owner.contact.accountId);
    


        map<id, id> boxmap = new map<id, id>();
        for(Box_Assumption__c ba : [SELECT Account__c, Id FROM Box_Assumption__c where Account__c in :acctid]) {
          boxmap.put(ba.Account__c, ba.Id);
        }

        for (account a : toUpdate) {
            a.x9box_assumptions__c = boxmap.get(a.owner.contact.accountId);
        }

        upsert toUpdate;

        isRunning = false;
    }
}

 

 

All Answers

Kevin BromerKevin Bromer

In a before insert, the account object you're inserting doesn't yet have an owner associated with it, that is assigned to the record after the before insert trigger. If you change it to after insert, it should work.

 

 

pdvaporpdvapor

So I made some modifications (including the "after update, after insert" change and now it saves, but is not making the association...any other suggestions?

trigger updatecustomer9box on Account (after insert, after update) {
    
    //Get Account ID of the current record.
    set<id> acctid = new set<id>();
    for (account a : trigger.new){
        if (a.RecordType.Name == 'CC Client Customer Account'){
            acctid.add(a.owner.contact.account.id);
        }
    }
    
    if (acctid.size() == 0)
        return;
    
    map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>([select id 
                                                                     from box_assumptions__c
                                                                     where account__c in : acctid]);
    for (account a : trigger.new){
        box_assumptions__c thisbox = boxmap.get(a.x9box_assumptions__c);
        a.x9box_assumptions__c = thisbox.id;
    
    update a;
    }
}

 

Rahul S.ax961Rahul S.ax961

Can you please Elaborate problem you are facing.

pdvaporpdvapor

When I update the record with a new Owner, it does not update the x9box_assumptions__c field.

 

Thank you for your help!

VPrakashVPrakash

Try this 

 

trigger updatecustomer9box on Account (after insert, after update) {       

//Get Account ID of the current record.   

set<id> acctid = new set<id>();   

account[] updateaccts = new account[]{};   

for (account a : trigger.new){       

if (a.RecordType.Name == 'CC Client Customer Account'){           

acctid.add(a.owner.contact.account.id);       

}   

}       

if (acctid.size() == 0)        return;   

for ( box_assumptions__c BA : select id from box_assumptions__c where account__c in : acctid){ 

map<id, box_assumptions__c> boxmap = new map<id,box_assumptions__c>();

boxmap.add(BA.Account__c , BA);   


//map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>([select id                                                                      from box_assumptions__c                                                                     where account__c in : acctid]);   

for (account a : trigger.new){       

a.x9box_assumptions__c  = boxmap.get(a.id);      

updateaccts.add(a);   

}   

if(updateaccts.size()>0){

update updateaccts;   

}

}

pdvaporpdvapor

I am getting: 
Error: Compile Error: unexpected token: 'select' at line 14 column 33

VPrakashVPrakash

try this,

 

trigger updatecustomer9box on Account (after insert, after update) {       

//Get Account ID of the current record.   

set<id> acctid = new set<id>();   

account[] updateaccts = new account[]{};   

for (account a : trigger.new){       

if (a.RecordType.Name == 'CC Client Customer Account'){           

acctid.add(a.owner.contact.account.id);       

}   

}       

if (acctid.size() == 0)        return;   

for ( box_assumptions__c BA : [select id from box_assumptions__c where account__c in : acctid]){ 

map<id, box_assumptions__c> boxmap = new map<id,box_assumptions__c>();

boxmap.add(BA.Account__c , BA);   


//map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>([select id                                                                      from box_assumptions__c                                                                     where account__c in : acctid]);   

for (account a : trigger.new){       

a.x9box_assumptions__c  = boxmap.get(a.id);      

updateaccts.add(a);   

}   

if(updateaccts.size()>0){

update updateaccts;   

}

pdvaporpdvapor

Now getting 

Error: Compile Error: Method does not exist or incorrect signature: [MAP<Id,Box_Assumptions__c>].add(Id, SOBJECT:Box_Assumptions__c) at line 16 column 9

VPrakashVPrakash

My bad, 

 

use put instead of add 

Rahul SharmaRahul Sharma

Hi pdvapor,

 

I did not get the requirement clearly, but have optimized Prakash's code for you:

 

trigger updatecustomer9box on Account (after insert, after update)
{       
  Set<Id> setAccId = new Set<Id>();   
  Map<Id, Box_Assumptions__c> mapBA = new Map<Id, Box_Assumptions__c>();
  List<Account> lstAccount = new List<Account>();   
  for (Account objAccount : trigger.new)  
    if (objAccount.RecordType.Name == 'CC Client Customer Account')         
      setAccId.add(objAccount.owner.contact.account.id);        
  if (!setAccId.isEmpty())        
  { 
    for (Box_Assumptions__c objBA : [Select Id from Box_Assumptions__c where Account__c In : setAccId])
    mapBA.put(objBA.Account__c , objBA);   
    if(!mapBA.values.isEmpty())
    {
      for (Account objAccount : trigger.new)
      {       
        objAccount.x9box_assumptions__c  = mapBA.get(objAccount.id);      
        lstAccount.add(objAccount);   
      }   
      if(!lstAccount.isEmpty())
      update lstAccount;   
     }
   }
}

 Hope it helps. :)

Let us know if you face any issues furthur

pdvaporpdvapor

Hi Rahul,

You are definitely on the right track, but now I am facing the following error:

  
 Error: Compile Error: Illegal assignment from SOBJECT:Box_Assumptions__c to Id at line 17 column 9



pdvaporpdvapor

So I tried a different approach to this. But now it is not updating anything...can you take a look at this approach?

trigger update9box on account (after insert, after update){
    set<id> accid = new set<id>();
    for (account acc : trigger.new){
        accid.add(acc.owner.contact.account.id);
    }
    list<box_assumptions__c> boxassumptions = [select id, account__c
                                               from box_assumptions__c
                                               where account__c = : accid];
    map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>();
    for (box_assumptions__c ba : boxassumptions){
        boxmap.put(ba.id, ba);
    }
    for (account a : trigger.new){
        box_assumptions__c thisbox = boxmap.get(a.x9box_assumptions__c);
    }
    update boxmap.values();
}

 

SteveBowerSteveBower
trigger update9box on account (after insert, after update){

// This code below is essentially what you had in your first post which looked great.
    set<id> accid = new set<id>();
    for (account acc : trigger.new) accid.add(acc.owner.contact.account.id);

    map<id, box_assumptions__c> boxmap = new map<id, box_assumptions__c>([
         select id, account__c from box_assumptions__c where account__c in :accid
    ]);

/*
    //   Regarding this secion, all you're doing is:

    // Looping through the trigger and...
    for (account a : trigger.new) {
        // setting thisbox to some value.  Sure, it comes from the map, but who cares because...
        box_assumptions__c thisbox = boxmap.get(a.x9box_assumptions__c);
        // you're not doing anything with it, you just set it and forget it.
    }
    // Then you update the box_assumptions in your map.  But, since you've never done a Put into your map to replace an existing 
    // box_assumptions record with something that has changed, you're not updating anything.
    update boxmap.values();
*/
    // I'd like to help, but I don't really understand what you're trying to do.   If there is only one record (Account 1) in your trigger, 
    // and you want to update Account 2 which is somehow related, then you're going to have to query the new set of Accounts somewhere and 
    // then update those.  I don't see anyplace where you are pulling the Accounts to update.

// Best, Steve.


}

 

pdvaporpdvapor

Steve, I appreciate your help.  It is tough to describe, but I will try.  

1.  I have created a custome object "Box Assumptions" ((Box_Assumptions__c) that has a lookup field to an Account (Account__c), let's call this "Portal Account".

2.  I have Partal Users who are related to a Portal Account through their Contact record and are the Owners of their own Accounts.  Let's call these "Customer Accounts".  You can get to their Account ID by going through this path from their Customer Account - Account > Owner > Contact > Account.

3.  I am trying to find the Box Assumptions record that is related to the Portal User's Account (Portal Account) by taking the Portal Account ID and querying for the Box Assumptions record.

4.  Then, I want to take the Box Assumptions record ID and associate it to the "Customer Account" through a Lookup field (x9box_assumptions__s) Lon the "Customer Account record.

 

I hope this helps to explain.  I have tried many variations of this, but cannot seem to get it to work.

 

Really appreciate your help on this!

SteveBowerSteveBower
So, if I understand....
 (Note: since you're changing the Accounts in the trigger, you need these to be "before" triggers.)

trigger update9box on account (before insert, before update) {

    // Set up a map of Portal Account Ids that runs parallel to the Customer Accounts in the Trigger.
    map<id, id> portalAccountMap = new Map<Id, Id>;
    for (Account acc : trigger.new) portalAccountMap.put(acc.id, acc.owner.contact.account.id);

    // Now get the Box Assumptions for these portalAccounts, and set them up so that they can be accessed via the portalAccount Id's
    map<id, id> boxmap = new map<id, id>();
    for (box_assumption__c ba: [select id, account__c from box_assumptions__c where account__c in :portalAccountMap.values()]) 
       boxmap.put(ba.account__c, ba.id);

    // Now, for each Account in the trigger, get the parallel Portal Account Id from the map, and then use that to find it's Box Assumption Id
    for (Account acc: trigger.new) acc.x9box_assumptions = boxmap.get(portalAccountMap.get(acc.id));
}

Hope this helps and makes sense, Best, Steve.

 Note: I'm not going to be surprised if this craps out on this "acc.owner.contact.account.id".  Triggers generally have just the fields in the record being insert/updated.  I'd be surprised if owner.contact.account.id was actually data that was in the record.  Throw a system.debug(acc) into your loop and you'll see the data that's actually in the trigger.new records.

If that's the case, then you're going to have to issue the query yourself to get all that information.  -S

 

And practice using comments... it helps clarify your thinking.  :-)

WizradWizrad
trigger updatecustomer9box on Account (after insert, after update) {
   if(!MyCoolTriggerUtilClass.isRunning) {
       MyCoolTriggerUtilClass.magicalSalesforceMethod(Trigger.new);
   }
}

public class MyCoolTriggerUtilClass {

    public static void isRunning = false;

    public static void magicalSalesforceMethod(List<Account> triggerNewList) {
        isRunning = true;

        //Get Account ID of the current record.
        set<id> acctid = new set<id>();
        List<Account> toUpdate = [SELECT Id, Owner.Contact.AccountId FROM Account WHERE Id in :triggerNewList];
        for (account a : toUpdate)
            acctid.add(a.owner.contact.accountId);
    


        map<id, id> boxmap = new map<id, id>();
        for(Box_Assumption__c ba : [SELECT Account__c, Id FROM Box_Assumption__c where Account__c in :acctid]) {
          boxmap.put(ba.Account__c, ba.Id);
        }

        for (account a : toUpdate) {
            a.x9box_assumptions__c = boxmap.get(a.owner.contact.accountId);
        }

        upsert toUpdate;

        isRunning = false;
    }
}

 

 

This was selected as the best answer
SteveBowerSteveBower

I thought he wanted to update the Account records in the trigger, not the portal accounts.  If that's the case, he just needs to do aread-only query to get the portal account id's, but he doesn't need to worry about the recursion, etc.  Best, Steve.

pdvaporpdvapor

Wizrad, this looks pretty amazing!  When I try to paste this in, I am getting "Compile Error: unexpected token: public at line 7 column 0".

pdvaporpdvapor

I'm embarrased...I see, thanks for your help!