0

I am trying to create a trigger on the Opportunity object so that whenever a particular field (e.g. ProdType) gets updated or is inserted, the value of the field should be copied to a field within a custom object (lets say CusObj.ProdType). The CusObj has a lookup relation with Opportunity. Can somebdoy help me with this please? I tried creating a simple formula earlier but that doesn't seem to help because the field ProdType is a multi-select picklist so there can be more than one selections at a time. I could have written an IF condition had it been just a simple pick-list because there could have been only one selection at a time. But, since there can be lot of permutations and combinations, I don't think that would work so the only option left for me is to create a trigger.

2
  • How many possible picklist values are in your ProdType field? If it's not too many, this could still be a formula field with several nested IF(INCLUDES()) statements. May 20, 2014 at 21:33
  • There are 6 picklist values. So, at a time, I can select just one value or even all the 6 values. Do you think that the IF(INCLUDES()) would work in this case because there can be lot of combinations for all those 6 values. May 20, 2014 at 22:32

3 Answers 3

2

Let me know if this works. You will just need to change the custom object name from Custom_Object__c to the correct name, and also do the same for the lookup from the Opportunity (Custom_Object_Lkp__c). I made the assumption that custom object lookup goes from the Opportunity and not the other direction.

trigger OpportunityTrigger on Opportunity(after insert, after update) {
    // Build map from Opportunity ID to related Custom_Report__c. 
    // Note: This will yield unexpected behaviour if an Opportunity has more than one related Custom_Report__c.

    List<Custom_Report__c> relatedCustomReports = [SELECT Id, Opportunity__c FROM Custom_Report__c WHERE Opportunity__c IN :trigger.new];
    Map<ID, Custom_Report__c> oppIdCustomReportMap = new Map<ID, Custom_Report__c>();

    for(Custom_Report__c cr : relatedCustomReports) {
        oppIdCustomReportMap.add(cr.Opportunity__c, cr);
    }

    // Copy value of Product_Type_c from each Opportunity to related Custom_Report__c and update list of Custom_Report__c.

    List<Custom_Report__c> customReportsToUpdate = new List<Custom_Report__c>();
    for(Opportunity o : trigger.new) {
        Custom_Report__c relatedCustomReport = oppIdCustomReportMap.get(o.Id);
        if(relatedCustomReport.Product_Type__c != o.Product_Type__c) {
            relatedCustomReport.Product_Type__c = o.Product_Type__c;
            customReportsToUpdate.add(relatedCustomReport);
        }
    }
    update customReportsToUpdate;
}
4
  • Hi Luke. Thanks for the help. Just one thing though. I don't have two custom objects. I only have one custom object "Current_Report_c". This custom object has a custom field named "Opportunity_c" whose datatype is Lookup(Opportunity). And this custom object "Current_Report_c" has the custom field "Product_Type_c". My standard "Opportunity" also has the field "Product_Type_c". So, when the Opportunity.Product_Type_c gets updated, I want to update "Current_Report_c.Product_Type_c" with the same value. May 20, 2014 at 23:33
  • So the only issue with having the lookup field from Current_Report_c to Opportunity is that an Opportunity can have more than one related Current_Report__c. If an Opportunity only ever has at most one related Current_Report__c then I would recommend changing your schema so that Opportunity has a lookup field to Current_Report__c. If you don't wish to update you schema then should the value in Product_Type_c be copied to ALL Current_Report__c records that are related to the Opportunity? Let me know your preference and I will update the trigger code in my answer. May 20, 2014 at 23:41
  • Luke, if you mean to say that Opportunity can have more than one related custom object "Current_Report_c" then that is not the case. And I don't think that is even possible because two custom objects can't have the same name. But, yes two differently named custom objects can have the same field "Product_Type_c" but even that is not true in my case. So, in my case only one custom object "Current_Report__c" is going to refer to the custom field "Product_Type_c". May 21, 2014 at 0:33
  • I have updated the answer according to the information you have given me. Let me know how that goes. May 21, 2014 at 1:39
1

A trigger is not a bad choice for this, but with just a few picklist values, this can just be a formula field on your CusObj object, and no code is necessary:

IF(INCLUDES(Opportunity__r.ProdType, "Value 1"),
    "Value 1","")
& ";" &
IF(INCLUDES(Opportunity__r.ProdType, "Value 2"),
    "Value 2","")
& ";" &
IF(INCLUDES(Opportunity__r.ProdType, "Value 3"),
    "Value 3","")
& ";" &
IF(INCLUDES(Opportunity__r.ProdType, "Value 4"),
    "Value 4","")
& ";" &
IF(INCLUDES(Opportunity__r.ProdType, "Value 5"),
    "Value 5","")
& ";" &
IF(INCLUDES(Opportunity__r.ProdType, "Value 6"),
    "Value 6","")

The way this is written, there will be semicolons in between the values. You could tweak it to display however you like.

0

An example would be:


// your trigger
trigger OpportunityTrigger on Opportunity (after update) {
    OpportunityTriggerImpl impl = new OpportunityTriggerImpl();

    if (Trigger.isAfter) {
        if (Trigger.isUpdate) {
            impl.doAfterUpdate(Trigger.old, Trigger.newMap);
        }
    }
}

// the implementation
public with sharing class OpportunityTriggerImpl {
    public OpportunityTriggerImpl();

    public void doAfterUpdate(Opportunity[] oldOpps, Map<Id, Opportunity> newOppsMap) {
        // get the related custom objects
        CustomObject__c objects = [SELECT Id, Field__c, LookupRelationship__c FROM CustomObject__c WHERE LookupRelationship__c = :newOppsMap.keySet()];
        for (CustomObject__c co : objects) {
            Opportunity opp = newOppsMap.get(co.LookupRelationship__c);
            String selectedValues = opp.ProdType__c; // this will be of the form 'AAA;BBB'
            // you could also split the string at the semi-colons and do whatever other logic you needed
            co.Field__c = selectedValues;
        }
        update objects;
    }
}

You must log in to answer this question.

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