1

Here's something that I'm trying to do which I feel as though I've made it 75% of the way through. Right now let's assume I have the ability to generate an opportunity when a certain action is performed on an Activity, and then populate a regular text field on the Opportunity (before Insert) that stores the ActivityId (not a lookup) on ActivityId__c.

What I'm trying to do is use that Id (Event or Task) to find the Activity that created the opportunity, and change the WhatId to be the new opportunity. The Activity's original WhatId will be looking up to the Account. Here's what I've done so far:

trigger activityCreatesOpp on Opportunity (after insert) {

// creates lists to store the IDs of Events and Tasks
List<Id> EventIds = New List<Id>();
List<Id> TaskIds = New List<Id>();


for(Opportunity opp : Trigger.new) {
    // checks to see if the Opportunity has ActivityId__c set to an event, and if so adds that EventId to the EventIds list
    String ActivityId = opp.ActivityId__c;
    if(opp.ActivityId__c != null && ActivityId.startsWith('00U')){
        EventIds.add(opp.ActivityId__c);

    }
    // checks to see if the Opportunity has Activity Id set to a task, and if so adds that TaskId to the TaskIds list
    if(opp.ActivityId__c != null && ActivityId.startsWith('00T'){
        TaskIds.add(opp.ActivityId__c);
    }

}

// if there is an Event Id found in the ActivityId field on the Opportunity, set the WhatId to that of the Opportunity
if(EventIds.size() > 0){
    List<Event> eventList = [SELECT Id, WhatId FROM Event WHERE Id in :EventIds];
    for(integer i = 0 ; i < eventList.size(); i++){
        eventList[i].WhatId = ???
    }
}

// if there is a Task Id found in the ActivityId field on the Opportunity, set the WhatId to that of the Opportunity
if(TaskIds.size() > 0){
    List<Task> taskList = [SELECT Id, WhatId FROM Task WHERE Id in :TaskIds];
    for(integer i = 0 ; i < taskList.size(); i++){
        taskList[i].WhatId = ???
    }
}

}

My main issue is trying to figure out how to get the OpportunityId into the WhatId (as you can see). A couple thoughts I had was that perhaps I should also create a list of the OpportunityId when I loop through the opps, and then use that list to populate the WhatId. However, I get the sense that I won't be able to ensure it's the right Id.

My other idea (which I think is probably the better solution) is to use Maps and to map the Opportunity Id to the Event/Task Id. This makes a lot of intuitive sense to me because that is that's the reality of the situation: I need to relate a specific Opportunity to a specific Activity.

Am I on the right track here? Appreciate any help as well as any suggestions/observations regarding my code as a whole.

Thanks!

2 Answers 2

3

You can do something like the following. There may be a better way to do this; however, this will give you an idea of how to do it.

trigger activityCreatesOpp on Opportunity (before update) {

    //Create a set and map to hold our values.
    set<id> oid = new set<id>();
    map<id, task> taskmap = new map<id, task>();

    //Put the activity id from the opportunity in the set.
    for(Opportunity opp : Trigger.new) {
        oid.add(opp.ActivityId__c);
    }

    //Assuming the activity is a task, query for the task record using
    //the activity ID in the set.
    for(task t: [select id from task where id in: oid]){
        taskmap.put(t.id, t);
    }

    //Change the value of WhatID
    for(opportunity o: trigger.new){
        if(taskmap.containskey(o.activityId__c)){
            taskmap.get(o.ActivityId__c).whatid = o.id;
        }
    }
    //Update the task after setting the value.
    update taskmap.values();
}

Also, this is a great overview of maps. https://www.sundoginteractive.com/sunblog/posts/apex-why-maps-are-your-friend

3
  • Thanks for that (and the link), I feel like I'm getting pretty close to a solution. A couple questions: 1) in the first for loop, if the ActivityId is null, will a null value be added to the set? Or should I include an if(ActivityId__c != null) clause? 2) Since I need to account for both Events and Tasks, would it make sense to just re-create the Task for loop for the event? And additionally include a second If statement in the final for loop? Thanks again
    – Dylan
    Commented May 8, 2015 at 20:42
  • You can setup a debug statement in the first loop and create a log. Edit an opportunity to make the trigger fire without the Activity ID. Reference the set in your debug log to see the value of the set. It should be "oid()." You should always implement exception handling in your code. Try Catch blocks are recommended. developer.salesforce.com/page/… You could recreate the for loop or have a condition that checks the sObject. If(var == 'Task'){ // Task loop here } else if(var == 'Event'){ // Event loop }
    – Berg
    Commented May 11, 2015 at 11:55
  • Thanks for that. I think I may have gone around the issue with the null values using the If Statement, but I figured that probably wasn't considered best practice. I'll check out that link and see what I can come up with.
    – Dylan
    Commented May 11, 2015 at 17:48
0

Thanks to SFDC NOOB and some modifications I have a trigger that does exactly what I want. I suppose there might be a few lines of code that I could consolidate but it all seems to be pretty clear to me. Would love any feedback:

trigger activityCreatesOpp on Opportunity (after insert) {


// create set of Activity Ids that are Events; create map of Activity Id to Event
set<Id> eventIds = new set<Id>();
map<Id, Event> eventMap = new map<Id, Event>();
// create set of Activity Ids that are Tasks; create map of Activity Id to Task
set<Id> taskIds = new set<Id>();
map<Id, Task> taskMap = new map<Id, Task>();

// If the Activity Id on the opp is an Event or Task, add it to the appropriate set
for(Opportunity opp : Trigger.new) {
    String actId = opp.ActivityId__c;
    if(actId.startsWith('00U')) {
        eventIds.add(opp.ActivityId__c);
    }
    if(actId.startsWith('00T')) {
        taskIds.add(opp.ActivityId__c);
    }   
}

// If there are any Events that led to opp creation, create a mapping pair
if(eventIds.size() > 0) {
    for(Event e : [SELECT Id from Event WHERE Id IN :eventIds]) {
        eventMap.put(e.Id, e);  
    }
}

// If there are any Tasks that led to opp creation, create a mapping pair
if(taskIds.size() > 0) {
    for(Task t : [SELECT Id from Task WHERE Id IN :taskIds]) {
        taskMap.put(t.Id, t);
    }
}

// changes the WhatId to the Opportunity Id on any Events or Tasks that are referenced on the Opportunity
for(Opportunity opp : Trigger.new) {
    if(eventMap.containsKey(opp.ActivityId__c)) {
        eventMap.get(opp.ActivityId__c).WhatId = opp.Id;
    }   
    if(taskMap.containsKey(opp.ActivityId__c)) {
        taskMap.get(opp.ActivityId__c).WhatId = opp.Id;
    }
}

// update the Events or Tasks that created an Opportunity
if(eventMap.size() > 0) {
    update eventMap.values();
}
if(taskMap.size() > 0) {
    update taskMap.values();
}

}

You must log in to answer this question.

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