+ Start a Discussion
Cory PayneCory Payne 

Help with Trigger to copy Opportunity picklist value into Opportunity lookup field

Hello, total coding noob and trying to simply copy an Opportunity picklist value to a lookup field that is on the same Opportunity; the lookup is to a custom object called Warehouse__c.  I've scoured the forums for coding examples and thought I found what I needed but I am getting an error message in the Apex Trigger editor.

Source field is Opportunity.FMAV_Selling_Office__c (picklist)
Destination field is Opportunity.Selling_Office__c which is a lookup to a custom object Warehouse__c
Picklist values exactly match record names on Warehouse object.

Here is what I have so far?
Trigger GrabReference on Opportunity (before insert, before update)  
{    for (Opportunity dp: trigger.new) {
       if(Opportunity.FMAV_Selling_Office__c != null) {  
        //queries for 1 record's ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
           List<Warehouse__c> dpas = new List<Warehouse__c>(); 
           dpas = [Select Id from Warehouse__c WHERE Warehouse__c.Name = :Opportunity.FMAV_Selling_Office__c ORDER BY Id LIMIT 1];
           // and if we got back anything...
              if (dpas.size() > 0){
            //set your dp.reference field equal to the returned record's ID
                 Opportunity.Selling_Office__c = dpas[0].Id;
              }        
       }
    }
    }

Help?
Best Answer chosen by Cory Payne
Steven NsubugaSteven Nsubuga
Trigger GrabReference on Opportunity (before insert, before update)  
{   
    Set<String> names = new Set<String>();
	for (Opportunity dp: trigger.new) {
		
		if(dp.FMAV_Selling_Office__c != null) {
		   names.add(dp.FMAV_Selling_Office__c);
		}
	}		
	//queries for  record ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
	List<Warehouse__c> dpas = [Select Id, Name from Warehouse__c WHERE Name IN :names];
	
	// and if we got back anything...
	if (dpas.size() > 0) {
		Map<String, Id> nameIds = new Map<String, Id>();
		for (Warehouse__c dpa: dpas) {
			nameIds.put(dpa.Name, dpa.Id);
		}
		
		for (Opportunity dp: trigger.new) {
			//set your dp.reference field equal to the returned record's ID
			dp.Selling_Office__c = nameIds.get(dp.Name);
		}
	}
}
and
@isTest
public with sharing class GrabReferenceTest {


    static testMethod void triggerTest() {
		Warehouse__c testwarehse = new Warehouse__c(Name = 'testWarehse');
		insert testwarehse;
		
		Account testAccount = new Account(Name = 'testAccount');
		insert testAccount;
		
        Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating',
            LocaleSidKey = 'en_US',
            EmailEncodingKey  = 'UTF-8',
			FMAV_Selling_Office__c = 'testWarehse',
            LanguageLocaleKey = 'en_US'
        );
        insert testOpportunity;
		
		Opportunity testOpp = [SELECT Selling_Office__c FROM Opportunity LIMIT 1];
		System.assertEquals(testOpp.Selling_Office__c, testwarehse.Id);
    
	}	

}


 

All Answers

Steven NsubugaSteven Nsubuga
Here is the trigger, it will need to be bulkified.
Trigger GrabReference on Opportunity (before insert, before update)  
{    for (Opportunity dp: trigger.new) {
       if(dp.FMAV_Selling_Office__c != null) {  
        //queries for 1 record's ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
           List<Warehouse__c> dpas = new List<Warehouse__c>(); 
           dpas = [Select Id from Warehouse__c WHERE Name = :dp.FMAV_Selling_Office__c LIMIT 1];
           // and if we got back anything...
              if (dpas.size() > 0){
            //set your dp.reference field equal to the returned record's ID
                 dp.Selling_Office__c = dpas[0].Id;
              }        
       }
    }
}

 
Cory PayneCory Payne
Thank you very much, this is fabulous and indeed the Apex editor allows me to save this new code without error messages. I understand the concept of bulkify but not sure how to accomplish it or indeed if we would ever have issues with governor limits. I guess to future-proof the code it is worthwhile. Do you have any suggestions to bulkify, and indeed to test this in order to qualify it for a move to Production? Thanks again.
Steven NsubugaSteven Nsubuga
Hi Cory, find updated trigger
Trigger GrabReference on Opportunity (before insert, before update)  
{    
	for (Opportunity dp: trigger.new) {
		set<String> names = new List<String>();
		if(dp.FMAV_Selling_Office__c != null) {
		   names.add(dp.FMAV_Selling_Office__c);
		}
	}		
	//queries for  record ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
	List<Warehouse__c> dpas = [Select Id, Name from Warehouse__c WHERE Name IN :names];
	
	// and if we got back anything...
	if (dpas.size() > 0) {
		Map<String, Id> nameIds = new Map<String, Id>();
		for (Warehouse__c dpa: dpas) {
			nameIds.put(dpa.Name, dpa.Id);
		}
		
		for (Opportunity dp: trigger.new) {
			//set your dp.reference field equal to the returned record's ID
			dp.Selling_Office__c = nameIds.get(dp.Name);
		}
	}
}
and test class 
@isTest
public with sharing class GrabReferenceTest {


    static testMethod void triggerTest() {
		Warehouse__c testwarehse = new Warehouse__c(Name = 'testWarehse');
		insert testwarehse;
		
		Account testAccount = new Account(Name = 'testAccount');
		insert testAccount;
		
        Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating',
            LocaleSidKey = 'en_US',
            EmailEncodingKey  = 'UTF-8',
			FMAV_Selling_Office__c = 'testWarehse',
            LanguageLocaleKey = 'en_US'
        );
        insert testOpportunity;
		
		Opportunity testOpp = [SELECT Selling_Office__c FROM Opportunity LIMIT 1];
		System.assertEquals(testOpp.Selling_Office__c, testwarehse.Id);
    
	}	

}

 
Cory PayneCory Payne
Compile Error: Illegal assignment from List<String> to Set<String> at line 4 column 21?
Steven NsubugaSteven Nsubuga
Trigger GrabReference on Opportunity (before insert, before update)  
{    
	for (Opportunity dp: trigger.new) {
		Set<String> names = new Set<String>();
		if(dp.FMAV_Selling_Office__c != null) {
		   names.add(dp.FMAV_Selling_Office__c);
		}
	}		
	//queries for  record ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
	List<Warehouse__c> dpas = [Select Id, Name from Warehouse__c WHERE Name IN :names];
	
	// and if we got back anything...
	if (dpas.size() > 0) {
		Map<String, Id> nameIds = new Map<String, Id>();
		for (Warehouse__c dpa: dpas) {
			nameIds.put(dpa.Name, dpa.Id);
		}
		
		for (Opportunity dp: trigger.new) {
			//set your dp.reference field equal to the returned record's ID
			dp.Selling_Office__c = nameIds.get(dp.Name);
		}
	}
}

Test
@isTest
public with sharing class GrabReferenceTest {


    static testMethod void triggerTest() {
		Warehouse__c testwarehse = new Warehouse__c(Name = 'testWarehse');
		insert testwarehse;
		
		Account testAccount = new Account(Name = 'testAccount');
		insert testAccount;
		
        Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating',
            LocaleSidKey = 'en_US',
            EmailEncodingKey  = 'UTF-8',
			FMAV_Selling_Office__c = 'testWarehse',
            LanguageLocaleKey = 'en_US'
        );
        insert testOpportunity;
		
		Opportunity testOpp = [SELECT Selling_Office__c FROM Opportunity LIMIT 1];
		System.assertEquals(testOpp.Selling_Office__c, testwarehse.Id);
    
	}	

}

 
Cory PayneCory Payne
Sorry, another error Variable does not exist: names at line 10 column 81?  This seems close though, and I so appreciate your help.
Steven NsubugaSteven Nsubuga
Trigger GrabReference on Opportunity (before insert, before update)  
{   
    Set<String> names = new Set<String>();
	for (Opportunity dp: trigger.new) {
		
		if(dp.FMAV_Selling_Office__c != null) {
		   names.add(dp.FMAV_Selling_Office__c);
		}
	}		
	//queries for  record ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
	List<Warehouse__c> dpas = [Select Id, Name from Warehouse__c WHERE Name IN :names];
	
	// and if we got back anything...
	if (dpas.size() > 0) {
		Map<String, Id> nameIds = new Map<String, Id>();
		for (Warehouse__c dpa: dpas) {
			nameIds.put(dpa.Name, dpa.Id);
		}
		
		for (Opportunity dp: trigger.new) {
			//set your dp.reference field equal to the returned record's ID
			dp.Selling_Office__c = nameIds.get(dp.Name);
		}
	}
}
and
@isTest
public with sharing class GrabReferenceTest {


    static testMethod void triggerTest() {
		Warehouse__c testwarehse = new Warehouse__c(Name = 'testWarehse');
		insert testwarehse;
		
		Account testAccount = new Account(Name = 'testAccount');
		insert testAccount;
		
        Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating',
            LocaleSidKey = 'en_US',
            EmailEncodingKey  = 'UTF-8',
			FMAV_Selling_Office__c = 'testWarehse',
            LanguageLocaleKey = 'en_US'
        );
        insert testOpportunity;
		
		Opportunity testOpp = [SELECT Selling_Office__c FROM Opportunity LIMIT 1];
		System.assertEquals(testOpp.Selling_Office__c, testwarehse.Id);
    
	}	

}


 
This was selected as the best answer
Cory PayneCory Payne
Thanks again, I believe I load the test as an Apex Class but doing so gives me error Compile Error: Defining type for testMethod methods must be declared as IsTest at line 4 column 28?
Steven NsubugaSteven Nsubuga
@isTest
public with sharing class GrabReferenceTest {


    @isTest static void triggerTest() {
		Warehouse__c testwarehse = new Warehouse__c(Name = 'testWarehse');
		insert testwarehse;
		
		Account testAccount = new Account(Name = 'testAccount');
		insert testAccount;
		
        Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating',
            LocaleSidKey = 'en_US',
            EmailEncodingKey  = 'UTF-8',
			FMAV_Selling_Office__c = 'testWarehse',
            LanguageLocaleKey = 'en_US'
        );
        insert testOpportunity;
		
		Opportunity testOpp = [SELECT Selling_Office__c FROM Opportunity LIMIT 1];
		System.assertEquals(testOpp.Selling_Office__c, testwarehse.Id);
    
	}	

}

 
Cory PayneCory Payne
Thanks @Steven Nsubuga.  The test Apex class saved OK (at one point I missed line 1 @istest - sorry about that!) though I was getting some errors related to LocaleSidKey, EmailEncodingKey, and LanguageLocaleKey.  It saved if I removed those lines?  That got me as far as running the test but the test itself fails with message that it was actually unable to insert the testOpportunity.  Similarly the Trigger does not fire when I try my own Test Opportunity.  Sure appreciate your help here.
Cory PayneCory Payne
System.AssertException: Assertion Failed: Expected: null, Actual: a0B1k000000bylZEAQ
Steven NsubugaSteven Nsubuga
My bad, the trigger had an issue.
Trigger GrabReference on Opportunity (before insert, before update)  
{   
    Set<String> names = new Set<String>();
	for (Opportunity dp: trigger.new) {
		
		if(dp.FMAV_Selling_Office__c != null) {
		   names.add(dp.FMAV_Selling_Office__c);
		}
	}		
	//queries for  record ID, being the record ID where the dpas.Name field is the same as the dp.picklist field that fired the trigger
	List<Warehouse__c> dpas = [Select Id, Name from Warehouse__c WHERE Name IN :names];
	
	// and if we got back anything...
	if (dpas.size() > 0) {
		Map<String, Id> nameIds = new Map<String, Id>();
		for (Warehouse__c dpa: dpas) {
			nameIds.put(dpa.Name, dpa.Id);
		}
		
		for (Opportunity dp: trigger.new) {
			//set your dp.reference field equal to the returned record's ID
			dp.Selling_Office__c = nameIds.get(dp.FMAV_Selling_Office__c);
		}
	}
}

 
Cory PayneCory Payne
All good, passed tests and working 100% on sample records in Sandbox.

 
Cory PayneCory Payne
THANK YOU THANK YOU THANK YOU @Steven Nsubuga
Steven NsubugaSteven Nsubuga
You're welcome @Cory Payne