3

I've written the below Trigger to update Opportunities with a date value from MPM4_BASE__Milestone1_Project__crecords. The two objects have a many to many relationship and are related by ProjectxOpp__c records.

The trigger works fine but I wanted to check whether I can update the Opportunity's Implementation_Revenue__c field by making my first SOQL query a for loop & making a cross-object update or can I only retrieve the the contents of a field from a related record through the SOQL query?

If this is possible then there would then be no need for the second SOQL query.

trigger WE_IMProjCompletion on MPM4_BASE__Milestone1_Project__c (before insert, before update) {

    List<WEID__c> weids = WEID__c.getall().values();
    Set<Id> validRecordTypeIds = new Set<Id>();

    //add Opportunity Record Type Ids from Custom Setting to list of valid Ids      
    for(WEID__c weid : weids) {
        try{
            validRecordTypeIds.add(weid.WEProjectId__c);
        }catch (System.StringException e) {
            System.debug(System.LoggingLevel.ERROR,'Invalid Record Type Id ' + weid.WEProjectId__c);
        }
    }

    Set<Id> projects = new Set<Id>();
    Map<Id,Date> deadlineDates = new Map<Id,Date>();
    Set<Id> opps = new Set<Id>();
    Map<Id,Id> projxopps = new Map<Id,Id>();
    List<Opportunity> updOpps = new List<Opportunity>();

    If(Trigger.isInsert){
        for(MPM4_BASE__Milestone1_Project__c p : Trigger.new){
            if(validRecordTypeIds.contains(p.RecordTypeId))
            {
                projects.add(p.Id);
                deadlineDates.put(p.Id, p.MPM4_BASE__Deadline__c);
            }
        }
    }

    If(Trigger.isUpdate){
                for(MPM4_BASE__Milestone1_Project__c p : Trigger.new){
                    if(validRecordTypeIds.contains(p.RecordTypeId) && p.MPM4_BASE__Deadline__c != null)
                    {
                        MPM4_BASE__Milestone1_Project__c oldP = Trigger.oldMap.get(p.Id);

                        if(oldP.MPM4_BASE__Deadline__c != p.MPM4_BASE__Deadline__c){
                            projects.add(p.Id);
                            deadlineDates.put(p.Id, p.MPM4_BASE__Deadline__c);
                        }
                    }
                }
    }

    if(projects.size() > 0){

        for(ProjectxOpp__c junc : [SELECT Project__c, Opportunity__c FROM ProjectxOpp__c
                                    WHERE Project__c In :projects]){
                                       opps.add(junc.Opportunity__c);
                                       projxopps.put(junc.Opportunity__c,junc.Project__c);
                                   }

        if(Opps.size() > 0){

            for(Opportunity o : [SELECT Id, Implementation_Revenue__c FROM Opportunity
                                  WHERE Id In :opps])
            {
                Id relProj = projxopps.get(o.Id);

                o.Implementation_Revenue__c = deadlineDates.get(relProj);
                updOpps.add(o);
            }
            update updOpps;
        }
    }
}
2
  • is your question "can we retrieve the junction object and parent object fields (for update) in same query" ?
    – Anshul
    Commented Jul 10, 2015 at 17:37
  • @anshul I need to retrieve the fields from both objects and update the parent field in the same query - so I wouldn't need to use the second SOQL query.
    – Alex S
    Commented Jul 10, 2015 at 17:39

1 Answer 1

2

@Alex: based on your clarification I understand you want to retrieve both the objects via single SOQL query to update. Yes, this can be done. You'll need to 1. retrieve required opportunity fields in SOQL Query 2. Use Opportunity object (Opportunity__r) to set the value and store this object reference in a list 3. update the list

Updated code - tested & working

    for(ProjectxOpp__c junc : [SELECT Project__c, Opportunity__r.Implementation_Revenue__c FROM ProjectxOpp__c
                                WHERE Project__c In :projects])
    {
        Opportunity o = junc.Opportunity__r;
        o.Implementation_Revenue__c = deadlineDates.get(junc.Project__c);
        updOpps.add(o);
    }
0

You must log in to answer this question.

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