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
kali charankali charan 

Trigger on Update parent account based on child contact

Hi everyone,

   I am newbie to salesforce and i want help to update the parent account of amount field when ever the contact of amount field is inserted or updated.and i have the scenario like when ever the contact is created or updated the amount field of account should be auto populated this is the first scenario. The second scenario is when the 2nd contact is created if the amount field is greater the first amount the greater amount field should be populated on the account amount field. The 3rd scenario is there are two check boxes greater amount and lesser amount in the account object this should be populated with the latest contact whether it should be greater or lesser than the previous account.

The fields are
Account object:
Parent_amount__c = Text field
Greater_amount__c = checkbox
Lesser_Amount__c = checkbox

Contact object:
Amount__c 

I have written some code only for update thing and please help me for second and third scenarios.

The 1st scenario is also giving error for me.

trigger UpdateAmount on Contact (after insert, after update) { //You want it on update too, right?
  Map<ID, Account> parentOpps = new Map<ID, Account>(); //Making it a map instead of list for easier lookup
  List<Id> listIds = new List<Id>();

  for (contact childObj : Trigger.new) {
    listIds.add(childObj.Account.id);
  }

  //Populate the map. Also make sure you select the field you want to update, amount
  //The child relationship is more likely called Quotes__r (not Quote__r) but check
  //You only need to select the child quotes if you are going to do something for example checking whether the quote in the trigger is the latest
  parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c,Greater_amount__c,Lesser_Amount__c,Name,(SELECT ID, Amount__c FROM contacts) FROM Account WHERE ID IN :listIds]);

  for (contact con: Trigger.new){
     Account myParentOpp = parentOpps.get(con.Account.id);
     myParentOpp.Parent_amount__c = con.Amount__c;
  }

  update parentOpps.values();

}

The error is 
Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger UpdateAmount caused an unexpected exception, contact your administrator: UpdateAmount: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateAmount: line 16, column 1

Please help in fixing the bug and please suggest me for 2nd and 3rd scenarios

Thanks.
Best Answer chosen by kali charan
Sean McMickleSean McMickle
trigger UpdateAmount on Contact (after insert, after update) { //You want it on update too, right?
  Map<ID, Account> parentOpps = new Map<ID, Account>(); //Making it a map instead of list for easier lookup
  List<Id> listIds = new List<Id>();

  for (contact childObj : Trigger.new) {
    listIds.add(childObj.Account_ID__c);
  }

  parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c, Greater_amount__c, Lesser_Amount__c, Name FROM Account WHERE ID IN :listIds]);

List<Account> updatedParentOpps = new List<Account>();

  for (contact con: Trigger.new){
     if(parentOpps.containsKey(con.Account_ID__c)) { 
        Account myAccount = parentOpps.get(con.Account_ID__c);                                                
         if(myParentOpp.Parent_Amount__c < con.Amount__c) { 
                 myParentOpp.Parent_Amount__c = con.Amount__c; 
                 myParentOpp.Greater_Amount__c = true; 
                 updatedParentOpps.add(myParentOpp); 

         } else if(myParentOpp.Parent_Amount__c > con.Amount__c) { 
                 myParentOpp.Lesser_Amount__c = true;           
                 updatedParentOpps.add(myParentOpp);   } 
     }
  }

  if(parentOpps.size()>0){
       update parentOpps.values();
  }
}

Looks like I added too many brackets and used .contains instead of .containsKey. 

All Answers

Sean McMickleSean McMickle

Hey Kali,

Just FYI, I do not think triggers come with relationships passed the immediate relationship. Notice in this line ::

listIds.add(childObj.Account.id);


You are trying to grab the id of the account. Instead of that, directly reference the name of the relationship. For instance, if the name of the relationship was just called 'Account' you would do something like this ::

for (Contact contact : Trigger.new) {
    listIds.add(contact.Account);
}
This will give you the id of the account. I'm willing to bet that Account myParentOpp = parentOpps.get(con.Account.id); is your null object. Check this out by putting this in front of it ::
if(parentOpps.contains(con.Account.id)) {
    Account myParentOpp = parentOpps.get(con.Account.id);
...
This will ensure that you actually have it in your map. Throw some debugs in there to help you figure out what is going on.
For instance
parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c,Greater_amount__c,Lesser_Amount__c,Name,(SELECT ID, Amount__c FROM contacts) FROM Account WHERE ID IN :listIds]);

System.debug(parentOpps);

Then take a look at the debug log, see if anything is there for parentOpps.

Good luck!

-Sean
kali charankali charan
Thank you for the reply sean and i the trigger want satisfy the 2nd and 3rd scenarious which i have listed above.plz rly me back.
Sean McMickleSean McMickle

Ahh, my bad Kali!

 

For this scenerio, you would want this on update / insert of contact trigger.

For the update, you'd want to check to see if the amount has changed. Compare the old value and the new value. If it has changed, you'll end up doing the same thing you do on the insert trigger.

List<Account> updatedParentOpps = new List<Account>();

if(parentOpps.contains(con.Account.id)) {
    Account myParentOpp = parentOpps.get(con.Account.id);
    if(myParentOpp.Amount__c < con.Amount__c) {
        myParentOpp.Amount__c = con.Amount__c;
        myParentOpp.Greater_Amount__c = true;
        updatedParentOpps.add(myParentOpp);
    } else if(myParentOpp.Amount__c > con.Amount__c) {
        myParentOpp.Lesser_Amount__c = true;
        updatedParentOpps.add(myParentOpp);
    }
}

// Ensure there are parent accounts that have been updated, then update the accounts.
if(!updatedParentOpps.isEmpty()) {
    update updatedParentOpps;
}

 

I didn't notice a scenerio for if the amounts were equal to one another.  

Good luck!

-Sean

kali charankali charan
Hi Sean,Thanq once again for the reply i have updated the code for the first scenario its working fine for the first scenario can u please check it and update the 2nd and 3rd scenario

trigger UpdateAmount on Contact (after insert, after update) { //You want it on update too, right?
  Map<ID, Account> parentOpps = new Map<ID, Account>(); //Making it a map instead of list for easier lookup
  List<Id> listIds = new List<Id>();

  for (contact childObj : Trigger.new) {
    listIds.add(childObj.AccountID);
  }

  parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c,Greater_amount__c,Lesser_Amount__c,Name,(SELECT ID, Amount__c FROM contacts) FROM Account WHERE ID IN :listIds]);

  for (contact con: Trigger.new){
     Account myParentOpp = parentOpps.get(con.AccountID);
     myParentOpp.Parent_amount__c = con.Amount__c;
  }

  if(parentOpps.size()>0){
  update parentOpps.values();
  }

}

Please reply me back.
Sean McMickleSean McMickle
trigger UpdateAmount on Contact (after insert, after update) { //You want it on update too, right?
  Map<ID, Account> parentOpps = new Map<ID, Account>(); //Making it a map instead of list for easier lookup
  List<Id> listIds = new List<Id>();

  for (contact childObj : Trigger.new) {
    listIds.add(childObj.AccountID);
  }

  parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c, Greater_amount__c, Lesser_Amount__c, Name FROM Account WHERE ID IN :listIds]);

List<Account> updatedParentOpps = new List<Account>();

  for (contact con: Trigger.new){
     if(parentOpps.contains(con.AccountID)) { 
​         Account myParentOpp = parentOpps.get(con.AccountID);
                                                            
         if(myParentOpp.Amount__c < con.Amount__c) { 
                 myParentOpp.Amount__c = con.Amount__c; 
                 myParentOpp.Greater_Amount__c = true; 
                 updatedParentOpps.add(myParentOpp); 

         } else if(myParentOpp.Amount__c > con.Amount__c) { 
                 myParentOpp.Lesser_Amount__c = true;           
                 updatedParentOpps.add(myParentOpp);   } }
         }
   }

  if(parentOpps.size()>0){
       update parentOpps.values();
  }

}

When I was first learning to program in Apex, I would put debug statements everywhere to help me figure out what was going on. I'd advise the same for you as well!

Good luck in your coding endeavors!

-Sean
kali charankali charan
It is throwing an error like Error: Compile Error: line 15:0 no viable alternative at character '​' at line 15 column 0
Sean McMickleSean McMickle
trigger UpdateAmount on Contact (after insert, after update) { //You want it on update too, right?
  Map<ID, Account> parentOpps = new Map<ID, Account>(); //Making it a map instead of list for easier lookup
  List<Id> listIds = new List<Id>();

  for (contact childObj : Trigger.new) {
    listIds.add(childObj.Account_ID__c);
  }

  parentOpps = new Map<Id, account>([SELECT id, Parent_amount__c, Greater_amount__c, Lesser_Amount__c, Name FROM Account WHERE ID IN :listIds]);

List<Account> updatedParentOpps = new List<Account>();

  for (contact con: Trigger.new){
     if(parentOpps.containsKey(con.Account_ID__c)) { 
        Account myAccount = parentOpps.get(con.Account_ID__c);                                                
         if(myParentOpp.Parent_Amount__c < con.Amount__c) { 
                 myParentOpp.Parent_Amount__c = con.Amount__c; 
                 myParentOpp.Greater_Amount__c = true; 
                 updatedParentOpps.add(myParentOpp); 

         } else if(myParentOpp.Parent_Amount__c > con.Amount__c) { 
                 myParentOpp.Lesser_Amount__c = true;           
                 updatedParentOpps.add(myParentOpp);   } 
     }
  }

  if(parentOpps.size()>0){
       update parentOpps.values();
  }
}

Looks like I added too many brackets and used .contains instead of .containsKey. 
This was selected as the best answer
Sean McMickleSean McMickle
Replace Account_ID__c with your AccountID. I just tested it in my system and it appears to work.
Sean McMickleSean McMickle
Just replace Account_ID__c with AccountID. I use Account_ID__c in my environment. 
kali charankali charan
I am getting Error: Compile Error: Invalid field Account_ID__c for SObject Contact at line 6 column 17
Sean McMickleSean McMickle
Replace all instances of Account_ID__c with AccountID.
kali charankali charan
Ya its working thanq so much but the issue is i am getting the Greater_amount__c always checked it should not check always when ever the new contact is inserted if it is greater amount it should be checked and if it is lesser amount it should uncheck previous and check latest one for the account
Sean McMickleSean McMickle
if(myParentOpp.Parent_Amount__c < con.Amount__c) { 
                 myParentOpp.Parent_Amount__c = con.Amount__c; 
                 myParentOpp.Greater_Amount__c = true;
                 myParentOpp.Lesser_Amount__c = false
                 updatedParentOpps.add(myParentOpp); 

         } else if(myParentOpp.Parent_Amount__c > con.Amount__c) { 
                 myParentOpp.Lesser_Amount__c = true;
                 myParentOpp.Greater_Amount__c = false;           
                 updatedParentOpps.add(myParentOpp);   
         }

You need to set it to false when there is a lesser amount then. 
Sean McMickleSean McMickle
Does parent amount start at 0 or at blank? If it starts at 0, you need to ensure that the parent amount is not 0 before updating the max amount. If it starts at blank, ensure the amount is not blank before updating the Greater Amount field.
kali charankali charan
parent amount start from blank
Sean McMickleSean McMickle
Ok, you got this. I'll let you try to do this one. If it is blank, then we wouldn't want to update the checkboxes. If it isn't blank, then update the checkboxes. You can do this! Let me see your updated code if you still have questions.