+ Start a Discussion
David Roth 17David Roth 17 

Trigger - Access Parent Field data to populate child field (Opp field from Opp Product)

Im very new to SF Dev, and I've written my first trigger Befire Insert for newly created Opp Products.   At the opp level, there is a custom field "Corp Ad Class"  Picklist.  When the Opp is created, this field must be assigned a pickist value. 

The trigger is for each new Opp product created on that opp, I want it to enter the Corp Ad Class from the Opportunity as the default value.   I was unsuccessful accessing the Opportunity field to assign the data.  I had to create a custom formula field to capture the Picklist value first and then I could do the assignment using that field.  I'd like not to have these extra fields if I can aviod them and I assume I can access the parent related record to collect the data as need.

This is what I've come up with :

//Replicates the Opportunity level Corp Ad Class to each product line
trigger StampCorpAdClassNewRec on OpportunityLineItem (Before Insert)
for(OpportunityLineItem OpportunityLineItem:Trigger.new)
    OpportunityLineItem.Corp_Ad_Class__c = OpportunityLineItem.OppCorpAdClass__c ;  

Opportunity.Corp_Ad_Class__c is what I first placed to the right of the = but it errored.  I was attempting to reference the Master Record field value, Corp Ad Class field on the Opportunity Object.

OpportunityLineItem.OppCorpAdClass__c is a formula field "text(Opportunity.Corp_Ad_Class__c)"; referencing this field, the trigger works, I can make the default value assignment using that field.  Its likely the most efficient way to do this.  I've created an extra field I likely do not need.

Reading other posts on the topic, It appears I may possibly do a SOQL query for the field value then assign it to oppproduct field.   Im not quite sure.    Any feedback for a better would be greatly appreciated.

thank you, David

I feel creating a formula field is prefect, unless you want to give users the ability to to edit the field on OpportunityLineItem.

If in case you want to field to be editable on Opportunity Line Item - You should be able to achieve this using process builder declaratively(I've not used process builder extensively, but you can check if OpportunityLineItem is available for Process Builder. If yes, you should be able to do it).

If you want to go with an approach of trigger (You should consider it as your last option as there is considerable amount of work involved :) )
You must consider bulkifying your trigger (in simple words - think that more than one opportunitylineitem records are created in trigger context. Just to add complexity think that each record being inserted can be associated to different opportunity).

1. Collect Opportunity ids in a set<Id> (say opptyIds)
2. Query Opportunity records with field of interest
    Map<Id, Opportunity> mapOpptyByIds = new Map<Id, Opportunity>([Select Id, OppCorpAdClass__c FROM Opportunity WHERE Id IN :opptyIds ]);
3. Now iterate through trigger.new and assign field values from related opportunity records
for(OpportunityLineItem recLine :  trigger.new){
     Opportunity recOpp = mapOpptyByIds.get(recLine.OpportunityId);
     if(recOpp != null){
          recLine.OppCorpAdClass__c  = recOpp.OppCorpAdClass__c ;
4. Write a test class.

David Roth 17David Roth 17
Mandy, yes, the OpportunityLineItem Corp Ad Class field may be different than the value set at the Opportunity level.  While vast majority of line items will have the same value as seleted on the opp parent, we do have a few cases where one or more of the line items may have different classification than set on the opp.  The Ad Class field on the opp line item is also a Text / Picklist field with the same picklist values as on the opp.  The goal is to reduce data entry, users may select the "default Ad Class" at the opp level and have that value become the default value on any child line items on that opp.

I'll take a look at the process builder, start with that.  Thank you for assisting with the Trigger version as well. I'll test that out as well.