-1

Trigger to Sum values (like Lookup relationship)

trigger NewLucy on Contact (after insert, after delete, after update) {
   if(Trigger.isInsert){
      try {
         for (Contact co : Trigger.new) {
            Account po = [SELECT Id,SumAllContactCurrency__c  FROM Account WHERE Id = :co.AccountId];
            List<Contact> l_co = [SELECT Id,amount__c FROM Contact WHERE AccountId = :po.Id];
            for(Contact am_co : l_co) {
               amount += am_co.Amount__c;  
            }
            po.SumAllContactCurrency__c = amount;
            update po;
         }
      } catch (Exception e) {
         System.debug(e);
      }
   }

   if(Trigger.isAfter) {
      if(Trigger.isUpdate) {
         try {
            for (Contact co : Trigger.old) {
               Account po = [SELECT Id,SumAllContactCurrency__c  FROM Account WHERE Id = :co.AccountId];
               List<Contact> l_co = [SELECT Id,amount__c FROM Contact WHERE AccountId = :po.Id];
               for(Contact am_co : l_co) {
                  amount += am_co.Amount__c;  
               }
               po.SumAllContactCurrency__c = amount;
               update po;
            }
         } catch (Exception e) {
            System.debug(e);
         }
      }
      
      if(Trigger.isDelete){
         try {
            for (Contact co : Trigger.old){
               Account po = [SELECT Id,SumAllContactCurrency__c  FROM Account WHERE Id = :co.AccountId];
               List<Contact> l_co = [SELECT Id,amount__c FROM Contact WHERE AccountId = :po.Id];
               for(Contact am_co : l_co) {
                  amount += am_co.Amount__c;  
               }
               po.SumAllContactCurrency__c = amount;
               update po;
            }
         } catch (Exception e) {
            System.debug(e);
         }
      }
   }
}
2
  • 1
    You may want to bulkify this trigger by moving the queries and DML's out of for loop. Trailhead is a good place to start. In terms of your trigger, once bulkified, it should work fine. Here is a similar question which lists several ways to achieve what you are trying to do. salesforce.stackexchange.com/questions/33650/…
    – manjit5190
    Commented Jun 12, 2021 at 10:28
  • What manjit said ^^^, plus: If this trigger is firing and you are getting errors, or unexpected results, or unexpected debug messages, please edit your post and add that information.
    – Moonpie
    Commented Jun 12, 2021 at 13:16

1 Answer 1

0

The SOQL and DML inside loop can be taken out and by using maps, it can be handled in a better manner. Check below code for insert scenario, it will help you understand the use of maps and you can modify the update and delete scenarios accordingly

 trigger ContactTrigger on  Contact (after insert, after delete, after update) {
   if(Trigger.isInsert){
      try {
          Set<Id> relatedAccIds = new Set<id>();
          for(Contact co : trigger.new){
              if(co.accountid <> null){
                  relatedAccIds.add(co.accountId);
              }
          }
          List<Account> relatedAccountList = [SELECT Id, SumAllContactCurrency__c  FROM Account WHERE Id in :relatedAccIds];
          List<Contact> l_co = [SELECT Id, amount__c FROM Contact WHERE AccountId in :relatedAccIds];
          Map<Id, Account> accountToAmountMap = new map<Id, Account>();
          for(Contact conObj : l_co) {
              if(accountToAmountMap.containsKey(conObj.accountId)){
                  accountToAmountMap.get(conObj.accountid).SumAllContactCurrency__c += am_co.Amount__c;
              }
              else{
                  accountToAmountMap.put(conObj.accountid, new Account(id = conObj.accountid, SumAllContactCurrency__c = conObj.Amount__c));
              }
              //amount += am_co.Amount__c;  
          }
         if(accountToAmountMap <> null)
            update accountToAmountMap.value();
         }
      } catch (Exception e) {
         System.debug(e);
      }
   }

Not the answer you're looking for? Browse other questions tagged .