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
Vitaliy Beliy 15Vitaliy Beliy 15 

Problem with Trigger / SOQL / Update field parent from child

I have 2 objects, Child__c and Parent__c. Field Parent__c->LastDate must be updated automatically every time if Child__c->Status becomes 'Finished'
Trigger looks like this
ChildObjTrigger on Child_c(before update){
        Set<Id> rcID = new Set<Id>();
        for (Child_c child : Trigger.new){
            rcID.add(child.Id);
            System.Debug('ID added to list' + child.Id);
        }

        for (Child__c child : [SELECT Id, Name FROM Child__c WHERE Parent__r.Id IN :rcID]){
            if (child.Status__c == 'Finished')
            child.Parent__r.LastDate__c = System.today();

        }
    }

 
Best Answer chosen by Vitaliy Beliy 15
Ajay K DubediAjay K Dubedi
Hi Vitaliy,

Use this code to fulfill your requirement-
 
ChildObjTrigger on Child_c(before update){
        Set<Id> rcID = new Set<Id>();
        for (Child_c child : Trigger.new){
            rcID.add(child.Id);
            System.Debug('ID added to list' + child.Id);
        }

        for (Child__c child : [SELECT Id, Name FROM Child__c WHERE Parent__r.Id IN :rcID]){
         if(child.Status__c != Trigger.oldMap.Status__c && child.Status__c == 'Finished' &&       child.Parent__c != null) {
            child.Parent__r.LastDate__c = System.today();

        }
    }
}


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Ajay Dubedi
www.ajaydubedi.com  (http://www.ajaydubedi.com )

All Answers

Nayana KNayana K
You must perform dml on parent object records(insert,update,etc)
 
ChildObjTrigger on Child_c(after update){
        Set<Id> rcID = new Set<Id>();
        Map<Id, Parent__c> mapParent = new Map<Id,Parent>();
        for (Child_c child : Trigger.new){
            if(child.Status__c == 'Finished' && child.Parent__c != null){

            mapParent.put(child.Parent__c, new Parent__c(Id = child.Parent__c, LastDate__c = System.Today());
            System.Debug('ID added to list' + child.Id);
          }
        }
     if(!mapParent.isEmpty()) {
          update mapParent.values();
      }
    }
If you try above code, it should work. But there is a problem.
lets say, child c1 status gets changed to Finished, this trigger fires, updates parent p1 LastDate = Today 
Now, the database is having these values.:
1. C1 (Name=abc, Status=Finished)
2. P1(Name=ppp, LastDate=10/26/2019)

After two days, user updates the name or any other field values on c1. Say, name is changed from abc to abcChanged. Trigger fires and updates the p1.LastDate to 10/28 because c1.Status=Finished condition matches.

To avoid this, a line should be changed to say, only if Status is changed from something else to Finished, then update Parent.LastDate:
if(child.Status__c != Trigger.oldMap.Status__c && child.Status__c == 'Finished' && child.Parent__c != null) {

 
Ajay K DubediAjay K Dubedi
Hi Vitaliy,

Use this code to fulfill your requirement-
 
ChildObjTrigger on Child_c(before update){
        Set<Id> rcID = new Set<Id>();
        for (Child_c child : Trigger.new){
            rcID.add(child.Id);
            System.Debug('ID added to list' + child.Id);
        }

        for (Child__c child : [SELECT Id, Name FROM Child__c WHERE Parent__r.Id IN :rcID]){
         if(child.Status__c != Trigger.oldMap.Status__c && child.Status__c == 'Finished' &&       child.Parent__c != null) {
            child.Parent__r.LastDate__c = System.today();

        }
    }
}


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Ajay Dubedi
www.ajaydubedi.com  (http://www.ajaydubedi.com )
This was selected as the best answer