1

I am new to coding in Force.com and coding in general.

Object structure:

  • Opportunity has a detail object called Pricing__c
  • The OwnerId is only on the Opportunity object
  • There are two lookup fields on the User object to other users to indicate managers (i.e. the standard ManagerId and custom Senior_Manager__c fields)
  • The lookup fields are needed on the Pricing__c object to support an approval process

Lookup fields on the Pricing__c record for Sales_Manager__c and Senior_Manager__c need to populate based on the Opportunity Owner's user record upon insert of a new Pricing__c record. What's the correct way to make this happen?

The logic to execute this needs to exist in a class and that class is called from a trigger. I have the trigger calling the class properly. I need help with writing the class logic for this scenario.

This is what I've written so far:

public with sharing class pricingManagerAndLeader {
public static void updateLookups(List<Pricing__c> pml){

    // Get the Opportunity Ids by looping over the Pricing Approval Request records, then..
    // Get a list of Opportunity Owner user information from the Opportunity records related to Pricing Approval Request records, then...
    // Take the Opportunity Owner user information to populate Sales_Manager__c and Senior_Manager__c lookup fields on Pricing__c records

    // Get a list of all Opportunity Ids
    Set<Id> optyIds = new Set<Id>();
    for (Pricing__c p : pml){
        optyIds.add(p.Opportunity__c);
    }

// List of Opportunity fields that can be accessed from the Pricing Approval Request object (commented out because I don't know if I need this)
    // List<Pricing__c> pToUpdate = new List<Pricing__c>();
    // pToUpdate = [SELECT p.Opportunity__r.OwnerId, p.Opportunity__r.Name, p.Opportunity__r.Id, p.Opportunity__c FROM Pricing__c p];

    // Since Pricing__c is a detail of master Opportunity, get Pricing__c and User info from the Opportunity
    List<Opportunity> optyList = new List<Opportunity>();
    optyList = [SELECT o.Owner_Opportunity__c, o.Owner.Senior_Manager__c, o.Owner.ManagerId, o.Owner.Name, o.Owner.Id, o.OwnerId, o.Id, o.Record_Type_Name__c,
    (SELECT Id, Name, Opportunity__c, RecordTypeId, Product_Family__c, Sales_Manager__c, VSL__c, Sales_Person__c FROM Pricing__r WHERE (RecordType.Name = 'NA Pricing Request') AND (Opportunity__c IN :optyIds))
    FROM Opportunity o
    WHERE o.Record_Type_Name__c = 'NA'];

    // For each Pricing Approval Request inserted, get o.Owner.ManagerId and o.Owner.Senior_Manager__c and update the Pricing__c fields
    for (Opportunity o : optyList){
        Pricing__c p = new Pricing__c();
        p.Sales_Manager__c = o.Owner.ManagerId;
        p.Senior_Manager__c = o.Owner.Senior_Manager__c;
        insert p;
    }       

}//end updateLookups}//end class
1
  • Does the code compile? Execute as expected? If not, what does it do incorrectly? Jun 7, 2014 at 2:01

2 Answers 2

0

Please post the code for the trigger. Is it firing on update of Opportunity? If so, you may possibly have much of what you need already in trigger.new and/or trigger.old and don't need to be running all of these queries as part of the class. Instead you can pass them to the class from the trigger. Its also very likely that you don't want to have this running with sharing and can remove that stipulation.

If not Opportunity, we need to know what object its firing on. I'd have made these as comments, but there was just too much to include in a single one.

Ideally, the entire trigger could be put into a class using the tidy trigger structure or one of several similar ones referenced throughout the web, including here if you run a search.

1
  • Thank you for your suggestions. I solved it and posted my solution.
    – Tyler
    Jun 7, 2014 at 7:30
0

I figured it out. I updated the trigger to execute on before insert since after insert will conflict with the order of execution. The insert will fail with after insert behavior because the record will be read only when trying to execute the update. I believe it is best to have one trigger per object that can call multiple classes rather than write everything as a individual triggers.

Here's the code:

Trigger

trigger pricingTrigger on Pricing__c (before delete, before insert, before update, 
                                    after delete, after insert, after update) {

    if(trigger.isInsert && trigger.isBefore){
        Pricing__c[] pml = Trigger.new;
        pricingManagerAndLeader.updateLookups(pml); 
        }
}

Class

public with sharing class pricingManagerAndLeader {
    public static void updateLookups(List pml){

        Set optyIds = new Set();
        for (Pricing__c p : pml){
            optyIds.add(p.Opportunity__c);
        }

        List lsOpp = [SELECT o.Id, o.Owner_Opportunity__c, o.Owner.Senior_Manager__c, o.Owner.ManagerId, o.Owner.Name, 
            o.Owner.Id, o.OwnerId, o.Record_Type_Name__c,
                (SELECT Id, Name, Opportunity__c, RecordTypeId, Sales_Manager__c, Senior_Manager__c
                FROM Pricing__r
                WHERE (RecordType.Name = 'NA Pricing Request') AND (Opportunity__c IN :optyIds))
            FROM Opportunity o
            WHERE o.Record_Type_Name__c = 'NA'];

        Map optyMap = new Map(lsOpp);

        for (Pricing__c p : pml){
            p.Sales_Manager__c = optyMap.get(p.Opportunity__c).Owner.ManagerId;
            p.Senior_Manager__c = optyMap.get(p.Opportunity__c).Owner.Senior_Manager__c;
        }

    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.