I have the following structure:

Object A (Parent) < = Object B (Child) < = Object C (Child of Child)

I need to count the number total child records of Object C then show it in Object A

Below is the code the came up:

trigger oppProjectCostUpdate on Opportunity (after update) {

    Set<id> lstOppId = new set<id>();

    //get the Opportunity Id to store in the variable
    for(Opportunity opp : trigger.new){
        System.Debug('lstOppId ' + lstOppId);

    list<pse__Proj__c> lstVProjId = [SELECT Id 
                                     FROM pse__Proj__c 
                                     WHERE pse__Opportunity__c IN: lstOppId];
    set<id> lstProjId = new set<id>();
    //get the Project Id to store in the variable
    for(pse__Proj__c prj : lstVProjId){
        if(lstVProjId != null){
            System.Debug('lstProjId ' + lstProjId);

    list<pse__Timecard__c> lstVTcId = [SELECT Id
                                       FROM pse__Timecard__c
                                       WHERE pse__Project__c IN: lstProjId];
    set<id>lstTcId = new set<id>();
    //get the Timecard Id to store in the variable    
    for(pse__Timecard__c tc : lstVTcId){
        if(lstVTcId != null){
            System.Debug('lstTcId ' + lstTcId);

    List<AggregateResult> vLstAggr = [SELECT SUM(Charge_Cost_New__c) NoOfChild
                                     FROM pse__Timecard__c
                                     WHERE pse__Project__c IN: lstTcId
                                     GROUP BY ID];

    Opportunity vOpportunity;
    list<Opportunity> vLstOpp = new list<Opportunity>();

    for(AggregateResult vAggr : vLstAggr){
        System.debug('Opp Id '+vAggr.get('pse__Project__c'));
        System.debug('AggregateResult valuesare'+vAggr.get('NoOfChild'));

        string oppId = (string) vAggr.get('pse__Project__c');
        decimal countOfChild = (decimal) vAggr.get('NoOfChild');

        vOpportunity = new Opportunity(Id = oppId, Total_Charge__c = countOfChild);
    update vLstOpp;

Debug log is showing the following result:


HEAP_ALLOCATE|[28]|Bytes:5 16:33:17.0


But when I try to remove the code after Aggregate, lstTcId is showing some results (I'm updating the same record)

Any ideas on how to achieve my goal? Is my code on the right track? I'm new to programming so I'm still learning.

Thank you and appreciate your help and explanations!


As per above code, the object structure is

Opportunity (Parent) < = pse__Proj__c (Child) < = pse__Timecard__c(Child of Child)

and the requirement is the field(Total_Charge__c) of opportunity is the no of child count(pse__Proj__c).

Assumption : If one Opportunity is having one pse__Proj__c record and pse__Proj__c can have multiple pse__Timecard__c record.

Write a trigger on pse__Timecard__c object.

    trigger oppProjectCostUpdate on pse__Timecard__c (after create) {  

       if(Trigger.isAfter && Trigger.isCreate){
            //get project Ids  
            Set<Id> setProjIds = new Set<Id>();
            for(pse__Timecard__c timecard : trigger.new){

            //Query pse__Project__c     List<pse__Project__c> projectList = new
             List<pse__Project__c>([SELECT id,pse__Opportunity__c, (SELECT Id FROM pse__Timecard__r) FROM  pse__Project__c WHERE ID IN : setProjIds]);

            List<Opportunity> oppListToUpdate = new List<Opportunity>();
            for(pse__Project__c project : projectList ){ 
                Opportunity opp =  new Opportunity(Id=project.pse__Opportunity__c); 
                opp.Total_Charge__c = project.pse__Timecard__r.size(); 

            //Update Opportunity list 
            UPDATE oppListToUpdate; 

Please let me know if the requirement is different.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.