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
nlang1.388093286234183E12nlang1.388093286234183E12 

Create Apex Trigger for Cross Object

Hello,
I am an experienced admin with no apex experience. I was hoping someone can point me in the right direction, I would like to take a stab at creating a simple Apex trigger on the opportunity object to update a field when a field is changed on a child custom object named Implementations (lookup relationship). I understand that cross object workflows can be done with master deatil relationships, however, I do not want to create a master relationship in this case. Any direction would be appreciated. 

Thanks!
sfdcfoxsfdcfox
The basic code would look like this:

trigger ImplementationsTrigger on Implementation__c (after insert, after update) {
    Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>();
    Opportunity[] updates;
    Map<Id, Database.SaveResult> failures = new Map<Id, Database.SaveResult>();

// Build map for opportunities to update (avoiding duplicates)
    for(Implementation__c record: Trigger.new) {
        if(record.Opportunity__c != null) {
            opportunities.put(record.Opportunity__c, new Opportunity(Id=record.Opportunity__c, FieldToUpdate__c=record.FieldToCopy__c));
        }
    }

// Make into a list we can depend on by value
updates = opportunities.values();

// Update the records, capturing any errors
    Database.SaveResult[] results = Database.Update(updates, false);

// Note which records (if any) had errors
for(Integer index = 0; index < results.size(); index++) {
  if(!results[index].isSuccess()) {
   failures.put(updates[index].Id, results[index]);
  }
}

// Report errors back to the calling operation
for(Implementation__c record: Trigger.new) {
  if(failures.containskey(record.Opportunity__c)) {
   record.addError('Error while updating parent opportunity: '+failures.get(record.Opportunity__c).getErrors()[0].getMessage());
  }
}
}

Your specific milage may vary, but hopefully this leads you in the right direction.
Amit MalikAmit Malik
Very helpful sfdcfox

Using your approach, I made one implementation

1) Create custom object named shipment with custom field status which has 3 values pending, dispatched,delivered
2) Create lookup field in shipment object to opportunity object
3) Create shipmentstatus field of type text in opportunity object
4) Create trigger on shipment object as follows

trigger triggeropportunityupdate on Shipment__c (after insert,after update) {
Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>();
    Opportunity[] updates;
     Map<Id, Database.SaveResult> failures = new Map<Id, Database.SaveResult>();
    
    
     // Build map for opportunities to update (avoiding duplicates)
    for(Shipment__c record: Trigger.new) {
        if(record.Opportunity__c != null) {
            opportunities.put(record.Opportunity__c, new Opportunity(Id=record.Opportunity__c, shipmentstatus__c=record.status__c));
        }
        }
       
        // Make into a list we can depend on by value
        updates = opportunities.values();
       
        // Update the records, capturing any errors
    Database.SaveResult[] results = Database.Update(updates, false);
   
   
    // Note which records (if any) had errors
for(Integer index = 0; index < results.size(); index++) {
  if(!results[index].isSuccess()) {
   failures.put(updates[index].Id, results[index]);
  }

   // Report errors back to the calling operation
for(Shipment__c record: Trigger.new) {
  if(failures.containskey(record.Opportunity__c)) {
   record.addError('Error while updating parent opportunity: '+failures.get(record.Opportunity__c).getErrors()[0].getMessage());
  }
}   
       
    }
   
   
}

5) Test it

I hope this will be helpful for you to understand how trigger works.

Enjoy

Amit
ElkayElkay
I know this is an old posts but it is very informative. I have a question regarding the AddError Method used in here.  For example 'failures.containskey(record.Opportunity__c)' will consider all the child records associated with the Opportunity ID. So in case of bulk update if there is a failure due to one record all the associated child record will not be inserted/updated. Any thoughts on this