[SalesForce] Updating Parent Field After Child Record is Deleted

I have two custom objects: ObjectA__c as the master object, while ObjectB__c as the detail object.

Objects with Fields:

ObjectA__c : Id, Name, checkbox__c, Total__c
ObjectB__c : Id, Name, ObjectA__c, Qty__c

I created an apex class that is supposed to update Total__c field from ObjectA__c, every time I delete an ObjectB__c record. This class is called in an apex trigger.

I know that my problem with would be clearer if I provide an example.

example:

Total__c = 1000 (assume that this is the current value)

Then suppose we have an ObjectB__c record with the Qty__c of 500

Now when I delete this ObjectB__c record, Total__c now must be updated to 500, following this formula:

Total__c = current total field value - qty field value of recently deleted ObjectB__c record

Thus: 1000 - 500 = 500

Problem is, every time I delete a detail record, Total__c field is not updated at all.

Apex Class

public class MyController {

 public static void UpdateTotalViaObjectBDelete(List<ObjectB__c> objBList) {

        List<ObjectA__c> newObjA = new List<ObjectA__c>();
        Decimal t = 0;
        List<ObjectA__c> aToUpdate = new List<ObjectA__c>();

        objBList = [SELECT Id, Name, Qty__c, ObjectA__c, ObjectA__r.Total__c FROM ObjectB__c WHERE ID IN: objBList];  

        if(!objBList.isEmpty()) {

            newObjA = [SELECT Id, Name, checkbox__c, Total__c FROM ObjectA__c WHERE ID =: objBList[0].Id];

            if(!newObjA.isEmpty()) {

                t = newObjA[0].Total__c;

            }

        }        

        for(ObjectA__c a : newObjA) { 

            if(a.checkbox__c) {

                a.Total__c = t - objBList[0].Qty__c;        
                aToUpdate.add(a);        

            }

        }     

        if(!aToUpdate.isEmpty()) {  

            update aToUpdate;

        }    

    } 

}

Apex Trigger

trigger updateTotal on ObjectB__c (after delete) {
    if(Trigger.isAfter && Trigger.isDelete) {
            for(ObjectB__c ob: Trigger.Old) {
                MyController.UpdateTotalViaObjectBDelete(Trigger.Old);
            }    
    }
}

Best Answer

Your code can be optimised in this way. There are few issues with your code.

Trigger:

trigger updateTotal on ObjectB__c (after delete) {
    MyController.UpdateTotalViaObjectBDelete(Trigger.Old);
}

class:

public class MyController {

    public static void UpdateTotalViaObjectBDelete(List<ObjectB__c> objBList) {
        if(!objBList.isEmpty()){
             List<Id> objAIds = new List<Id>();

             for(ObjectB__c obj : objBList){
                 objAIds.add(obj.ObjectA__c);
             } 

             Map<Id, ObjectA__c> objAById = new Map<Id, ObjectA__c>([SELECT Id, Total__c FROM ObjectA__c WHERE Id in :objAIds]);

             for(ObjectB__c objB : objBList){
                  ObjectA__c objA = objAById.get(objB.ObjectA__c);
                  objA.Total__c -= objB.Qty__c;
                  objAById.put(objB.ObjectA__c, objA);
             }
             update objAById.values();
        } 
    }
}
Related Topic