function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Thomas Reinman 16Thomas Reinman 16 

Apex Trigger Not Updating Lookup Field

Hello,

I need a trigger that will update a lookup field on a Task of a particular record type based upon the users' picklist value selection on that task record. The lookup field should be populated with the ID of another custom object. Both the task and custom object have a lookup to Opportunites, and the picklist on the task record matches the values of a picklist on the custom object. The matching criteria should be a combination of: (1) Task.WhatId and CustomObject.OpportunityId, (2) Task.PicklistValue and CustomObject.PicklistValue. So far, I have the following solution written:

User-added image

It is saved and active in my sandbox, but it is not updating the lookup field as expected. 

Does anyone have a correct solution?

Thanks,
Tom
Raj VakatiRaj Vakati
Can u give me code in edit mode not in image i will write it for u 
Thomas Reinman 16Thomas Reinman 16
Thanks Raj!


trigger updateMCPLookup on Task (before insert, before update) {
Set<Id> mcpObjIDSet = new Set<Id>();
Set<String> mcpObjSubSet = new Set<String>();
// Iterate over our trigger context variable
for (Task t : Trigger.new){
// Make sure the record type is Mutual Closing Plan
if(t.RecordType.Name == 'Mutual_Closing_Plan'){
// Declare collections to hold values (IDs and Subjects) we will need in the WHERE clause of the query
mcpObjIDSet.add(t.WhatId);
mcpObjSubSet.add(t.Subject);
}
}
// Declare a map, this map will be used to hold the data we care about
Map<String, Id> mcpIdToTaskNameMap = new Map<String, Id>();
// Perform a query for the information we want to retrieve
for(Mutual_Closing_Plan_Objective__c mcpObj : [SELECT Id, Subject__c FROM Mutual_Closing_Plan_Objective__c WHERE Opportunity__c IN :mcpObjIDSet AND Subject__c IN :mcpObjSubSet LIMIT 1]){
// Inside this loop, we populate the map with the data we're interested in.
mcpIdToTaskNameMap.put(mcpObj.Subject__c, mcpObj.Id);
// Finally, iterate one more time over the records we initially had. Since this is a 'before' trigger, no further DML is required.
for(Task task : trigger.new){
task.MCP_Objective__c = mcpIdToTaskNameMap.get(mcpObj.Id);
}
}
}



 
Steven NsubugaSteven Nsubuga
Try this
trigger updateMCPLookup on Task (before insert, before update) {
	Set<Id> mcpObjIDSet = new Set<Id>();
	Set<String> mcpObjSubSet = new Set<String>();
	Map<String, Schema.RecordTypeInfo> recordTypes = Schema.SObjectType.Task.getRecordTypeInfosByName();
	
	// Iterate over our trigger context variable
	for (Task t : Trigger.new){
		// Make sure the record type is Mutual Closing Plan
		if(t.RecordTypeId == recordTypes.get('Mutual_Closing_Plan').getRecordTypeId()){
		// Declare collections to hold values (IDs and Subjects) we will need in the WHERE clause of the query
			mcpObjIDSet.add(t.WhatId);
			mcpObjSubSet.add(t.Subject);
		}
	}
	// Declare a map, this map will be used to hold the data we care about
	Map<String, Id> mcpIdToTaskNameMap = new Map<String, Id>();
	// Perform a query for the information we want to retrieve
	List<Mutual_Closing_Plan_Objective__c> mcpObj = [SELECT Id, Subject__c FROM Mutual_Closing_Plan_Objective__c WHERE Opportunity__c IN :mcpObjIDSet AND Subject__c IN :mcpObjSubSet];
	// Inside this loop, we populate the map with the data we're interested in.
	for(Mutual_Closing_Plan_Objective__c m : mcpObj){
		mcpIdToTaskNameMap.put(m.Subject__c, mcpObj.Id);
	}		
	
	// Finally, iterate one more time over the records we initially had. Since this is a 'before' trigger, no further DML is required.
	for(Task task : trigger.new){
		task.MCP_Objective__c = mcpIdToTaskNameMap.get(task.Subject);
	}
}

 
Raj VakatiRaj Vakati
trigger updateMCPLookup on Task (before insert, before update) {
	Set<Id> mcpObjIDSet = new Set<Id>();
	Set<String> mcpObjSubSet = new Set<String>();
	Map<String, Schema.RecordTypeInfo> recordTypes = Schema.SObjectType.Task.getRecordTypeInfosByName();
	
	// Iterate over our trigger context variable
	for (Task t : Trigger.new){
		// Make sure the record type is Mutual Closing Plan
		if(t.RecordTypeId == recordTypes.get('Mutual_Closing_Plan').getRecordTypeId()){
		// Declare collections to hold values (IDs and Subjects) we will need in the WHERE clause of the query
			mcpObjIDSet.add(t.WhatId);
			mcpObjSubSet.add(t.Subject);
		}
	}
	// Declare a map, this map will be used to hold the data we care about
	Map<String, Id> mcpIdToTaskNameMap = new Map<String, Id>();
	// Perform a query for the information we want to retrieve
	List<Mutual_Closing_Plan_Objective__c> mcpObj = [SELECT Id, Subject__c FROM Mutual_Closing_Plan_Objective__c WHERE Opportunity__c IN :mcpObjIDSet AND Subject__c IN :mcpObjSubSet];
	// Inside this loop, we populate the map with the data we're interested in.
	for(Mutual_Closing_Plan_Objective__c m : mcpObj){
		mcpIdToTaskNameMap.put(m.Subject__c, mcpObj.Id);
	}		
	
	// Finally, iterate one more time over the records we initially had. Since this is a 'before' trigger, no further DML is required.
	for(Task task : trigger.new){
		if(mcpIdToTaskNameMap.get(task.Subject)!=null){
		task.MCP_Objective__c = mcpIdToTaskNameMap.get(task.Subject);
		}
	}
}

 
Thomas Reinman 16Thomas Reinman 16
Thank you both -- I haven't had time to test yet but I will be later today and will let you both know.
Thomas Reinman 16Thomas Reinman 16
So this is the updated code I've got saved, but I'm still receiving a null pointer exception on the RecordType bit for tasks...

User-added image

Here is the updated code I have saved:
trigger updateMCPLookup on Task (before insert, before update) {
    Set<Id> mcpObjIDSet = new Set<Id>();
    Set<String> mcpObjSubSet = new Set<String>();
    Map<String, Schema.RecordTypeInfo> recordTypes = Schema.SObjectType.Task.getRecordTypeInfosByName();
    
    // Iterate over our trigger context variable
    for (Task t : Trigger.new){
        // Make sure the record type is Mutual Closing Plan
        if(t.RecordTypeId == recordTypes.get('Mutual_Closing_Plan').getRecordTypeId()){
        // Declare collections to hold values (IDs and Subjects) we will need in the WHERE clause of the query
            mcpObjIDSet.add(t.WhatId);
            mcpObjSubSet.add(t.MCP_Objective_Picklist__c);
        }
    }
    // Declare a map, this map will be used to hold the data we care about
    Map<String, Id> mcpIdToTaskNameMap = new Map<String, Id>();
    // Perform a query for the information we want to retrieve
    List<Mutual_Closing_Plan_Objective__c> mcpObj = [SELECT Id, Subject__c FROM Mutual_Closing_Plan_Objective__c WHERE Opportunity__c IN :mcpObjIDSet AND Subject__c IN :mcpObjSubSet];
    // Inside this loop, we populate the map with the data we're interested in.
    for(Mutual_Closing_Plan_Objective__c m : mcpObj){
        mcpIdToTaskNameMap.put(m.Subject__c, m.Id);
    }       
    
    // Finally, iterate one more time over the records we initially had. Since this is a 'before' trigger, no further DML is required.
    for(Task task : trigger.new){
    if(mcpIdToTaskNameMap.get(task.MCP_Objective_Picklist__c)!=null){
        task.MCP_Objective__c = mcpIdToTaskNameMap.get(task.Subject);
        }
    }
}


 
Steven NsubugaSteven Nsubuga
This means we used the wrong record type name. Here is a suggestion, using the developer console, run the following code and see what it outputs.
It will help you identify the right name for the required record type.
Map<String, Schema.RecordTypeInfo> recordTypes = Schema.SObjectType.Task.getRecordTypeInfosByName();

for (String recordTypeName  : recordTypes.keyset()) {
 System.debug(recordTypeName);
}
Once you review the options listed, you can then replace Mutual_Closing_Plan with the right value in line 9 of the trigger.
 
Thomas Reinman 16Thomas Reinman 16
Thanks Steven, 
I was thinking the same thing but this is the name of the Record Type. I commented that portion of the code out and there are no more errors, but the Lookup field on the Task record still isn't being updated after I update the custom picklist field. Here is the latest sample I'm working with:
 
trigger updateMCPLookup on Task (before insert, before update) {
    Set<Id> mcpObjIDSet = new Set<Id>();
    Set<String> mcpObjSubSet = new Set<String>();
    Map<String, Schema.RecordTypeInfo> recordTypes = Schema.SObjectType.Task.getRecordTypeInfosByName();
    
    // Iterate over our trigger context variable
    for (Task t : Trigger.new){
        // Make sure the record type is Mutual Closing Plan
        // if(t.RecordTypeId == recordTypes.get('Mutual_Closing_Plan').getRecordTypeId()){ //
        // Declare collections to hold values (IDs and Subjects) we will need in the WHERE clause of the query
            mcpObjIDSet.add(t.WhatId);
            mcpObjSubSet.add(t.MCP_Objective_Picklist__c);
        // }
    }
    // Declare a map, this map will be used to hold the data we care about
    Map<String, Id> mcpIdToTaskNameMap = new Map<String, Id>();
    // Perform a query for the information we want to retrieve
    List<Mutual_Closing_Plan_Objective__c> mcpObj = [SELECT Id, Subject__c FROM Mutual_Closing_Plan_Objective__c WHERE Opportunity__c IN :mcpObjIDSet AND Subject__c IN :mcpObjSubSet];
    // Inside this loop, we populate the map with the data we're interested in.
    for(Mutual_Closing_Plan_Objective__c m : mcpObj){
        mcpIdToTaskNameMap.put(m.Subject__c, m.Id);
    }       
    
    // Finally, iterate one more time over the records we initially had. Since this is a 'before' trigger, no further DML is required.
    for(Task task : trigger.new){
    if(mcpIdToTaskNameMap.get(task.MCP_Objective_Picklist__c)!=null){
        task.MCP_Objective__c = mcpIdToTaskNameMap.get(task.Id);
        }
    }
}

Thanks again for all of your assistance.
Thomas Reinman 16Thomas Reinman 16
Thanks Steven, I've tried that too but it's still not populating.