0

How can I update the parent when all child records have the same value in a field?

Ex. I have five child records under a parent record.

The five child records have a field called Status, if ALL of the child records have “Ready” in that field, we need to update the parent to have their status field “ready” as well

    List<Parent__c> parentsToUpdate = ParentQuery.getStatus(parentIds);
        for(parent__c parent : parentsToUpdate){

            if(parent.Filled__c ==true && parent.Active_children__c ==0){
                Boolean ready= true;
                for(child__c child : parent.childs__r){
                    if(!Test.isRunningTest() && (child.status__c == null || child.status__c !='ready')){
                        ready = false;
                    }
                    else if(ready && child.status__c == 'ready'){
                        parent.Status__c = 'In Progress';
                        parent.ready_Date__c =Date.today();                        
                    }  
                }
            }
        }
        update parentsToUpdate;
    }
}

This method updates the parent field status to ready even when there is just one child record with the status "ready", how can I make it only fire when all of the child records are "ready"?

5

Typically the easiest way to implement such requirements is to have two rollups which you might name for example Child_Count__c and Ready_Count__c. If your relationship is Lookup rather than Master-Detail, you can still use Declarative Rollup Summaries for Lookups.

Once you have properly implemented both rollups, it is quite simple to write criteria for a rule:

AND(ISCHANGED(Ready_Count__c), Ready_Count__c = Child_Count__c)

This strategy is widely applicable and you will find many similar scenarios where it can be applied with minor changes.

1

I would go with the rollup summaries, if for some reason you cannot use master detail relationships or cannot install DLRS, following snippet (bit of pseudo code) will update parent record only when all children meet the criteria.

List<Account> accountsWithContacts = [
    SELECT Id,
    (
        SELECT Id, Status__c
        FROM Contacts
    )
    FROM Account
    WHERE Id IN :contactIds
];

for (Account account : accountsWithContacts) {

    Integer readyCounter = 0;

    for (Contact contact : account.Contacts) {

        if (contact.Status__c == 'ready') readyCounter++;
    }

    if (readyCounter == account.Contacts.size()) {

        account.Status__c = 'In Progress';
        account.Ready_Date__c = Date.today();
    }
}

The scalability of this solution is limited by the SOQL limits for parent-child relationship queries:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm

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.