0

Question: How can I update a parent field with some information I parse from the child? Invoice__c is the Master/parent and LineItem__c is the Detail/child object.

My code so far: (See WHAT I WANT TO DO: below.)

trigger SetInvoiceResellerID on LineItem__c (after insert) {  
    for(LineItem__c lineItem : Trigger.new){
        
        string recipientName = lineItem.RecipientName__c;
        
        //Parse out Reseller ID from RESELLERCODE~id~.
        string reseller = '';
        if (recipientName.length() > 0 && recipientName.contains('RESELLERCODE~'))
        {
            string[] arr = recipientName.split('~');
            for (integer i = 0; i < arr.size(); i++)
            {
                if (arr[i].Contains('RESELLERCODE'))
                {
                    reseller = arr[i + 1];
                    i = arr.size(); //To stop the for loop.
                }
            }
        }
        else
        {
            //Recipient name is empty, or does not contain "RESELLERCODE~".
            return;
        }
        //Set the reseller ID.
        if(reseller != null && reseller != ''){
            //WHAT I WANT TO DO: parentInvoice.Reseller_ID__c = reseller;
                
        }
        return;
    }
}

2 Answers 2

0

Your code has a few problems, even before updating the parent. First, your code presumes it will not run in bulk. This is a bad idea. Do not use return statements to end early unless there are no updates to complete. Further, you ignore a potential null value, so that's a problem. There's also some optimizations you can use: ?. to skip the null check, String.isNotBlank(value) instead of value != null && value != '', and a Map to make sure you update multiple parents if necessary.

Here's the revised code:

trigger SetInvoiceResellerID on LineItem__c (after insert) {
    Map<Id, Invoice__c> invoices = new Map<Id, Invoice__c>();
    for(LineItem__c record: Trigger.new) {
        String recipientName = record.RecipientName__c?.substringBetween('RESELLERCODE~','~');
        if(String.isNotBlank(recipientName)) {
            invoices.put(record.Invoice__c, new Invoice__c(Id=record.Invoice__c,Reseller_Id__c=recipientName));
        }
    }
    update invoices.values();
}
6
  • This is much more graceful than my solution. There is a problem where it is saying that the "variable does not exist: Invoice__c" for the line where you use .put.
    – Caroline
    Nov 11, 2020 at 20:43
  • Can you explain more the line invoices.put(record.Invoice__c, [...etc.]? Thank you.
    – Caroline
    Nov 11, 2020 at 20:45
  • In case this is helpful to anyone in the future, here's a link to the docs about map functions in Apex: developer.salesforce.com/docs/atlas.en-us.apexcode.meta/…
    – Caroline
    Nov 11, 2020 at 20:46
  • I was able to fix the line from record.Invoice__c to what I have as record.InvoiceID__c. Thank you again.
    – Caroline
    Nov 11, 2020 at 20:50
  • @Caroline I had to make some assumptions about the object and field names. You'll need to alter them as appropriate.
    – sfdcfox
    Nov 11, 2020 at 20:50
0

If you have the Id of your parent invoice, the simplest way to do this would be to use the SObject constructor to set the Id field (one of the few ways we can set the Id field) as well as your target Reseller_Id__c field.

//Set the reseller ID.
if(reseller != null && reseller != ''){
    //WHAT I WANT TO DO: parentInvoice.Reseller_ID__c = reseller;
    // The only thing you absolutely need when updating a record is the Id
    // If you already have the Id, then there's no need to spend a query (SOQL
    //   queries are a precious resource)
    Invoice__c parentInvoice = new Invoice__c(Id = lineitem.Invoice__c, Reseller_Id__c = reseller);
    
    // You can then add this new record to a Map<Id, Invoice__c> so you can perform DML
    //   to update your invoice records
    // It's important that you use a map here so that you avoid the "duplicate Id in list" error
}

Since you're in an after trigger here, you need to perform DML to update records (you can only avoid dml in before triggers, and only for changes to the records inside of trigger.new or trigger.newMap).

DML, like queries, should basically never be performed inside of a loop (gather the results in a collection, and perform the DML outside of the loop)

2
  • Can you explain or share any resources about learning the DML or map stuff? I haven't learned this yet. Thank you.
    – Caroline
    Nov 11, 2020 at 20:36
  • @Caroline Trailhead is the place to go if you're new to Apex (or really any part/feature of Salesforce that you're not familiar with). Bulk Apex Triggers is the module you're looking for, though it does have some knowledge prerequisites. The Developer Beginner Trail would help you build the requisite knowledge (it also contains the Bulk Apex Triggers module near the end).
    – Derek F
    Nov 11, 2020 at 20:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .