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
skiptomylou11skiptomylou11 

Apex Trigger to copy lookup field name instead of id

Hi,

 

I am actually trying to build a very basic trigger on opportunities.

 

The field country_object__c is a lookup field to an object with country information.

The selection he makes there (country name) should be filled into the country__c field when the entry is saved.

 

The code below however only puts in the id of the country object record.

 

Background is that the field country__c is used in many reports and sharing rules which I do not want to rework.

 

Many thanks!!!!

 

 

Trigger Update_Country on Opportunity (before update, before insert) {

 // Fill the Country__c field with the lookup name
 
  for (Opportunity o : Trigger.new) {
     o.Country__c = o.Country_Object__c;
  }

}

 

Best Answer chosen by Admin (Salesforce Developers) 
krprkrpr

Hi,

 

Just to clarify

 

1. There is a Country_Object__c with fields Name, Country__c

2. There is a Lookup relation between Opportunity and Country_Object__c

3. When you associate Opportunity with Country_Object__c the Value from Country__c on Country_Object__C must be copied to Country__c on Opportunity.

 

Here is the updated Trigger and Unit Test

 

 

 

Trigger

 

trigger Update_Country on Opportunity (before insert, before update) {
    
    set<ID>cObjectID = new set<ID>();    
    
    for(Opportunity opp : Trigger.new){
        if(opp.Country_Object__c != null){
            cObjectID.add(opp.Country_Object__c);
        }
    }
    
    if(!cObjectID.isEmpty()){
        
        Map<ID,Country_Object__c> cObjectMap = new Map<ID,Country_Object__c>([select Id, Name,     
Country__c from Country_Object__c where Id IN: cObjectID]); for(Opportunity opp : trigger.new){ if(cObjectMap.get(opp.Country_Object__c).Country__c != Null){ // fill the country name on Opportunity with Country Name on Country_Object__c opp.Country__c = cObjectMap.get(opp.Country_Object__c).Country__c; } } } }

 

 

Unit Test

 

 

@isTest
private class TestUpdateCountryOpportunity {

    static testMethod void myUnitTest() {
        
        Account a = new Account(Name = 'Berlington');
        insert a;
        
        Country_Object__c cObj = new Country_Object__c(Name = 'Object1', Country__c = 'India');
        insert cObj;
        
        Opportunity o= new Opportunity ( Name='test',AccountId = a.Id,
CloseDate = Date.today(),Amount=1,
StageName='1 - Marketing', Country_Object__c = cObj.Id); insert o; Opportunity opp = [select Id, Name, Country__c from Opportunity where Id =: o.Id]; system.assertEquals(opp.Country__c, cObj.Country__c); } }

 

 

 

If it works for you, do mark them as 'Solution' as it may help others.

 

Thanks

krpr

All Answers

vishal@forcevishal@force

Hi,

Below code should be good for your requirement :

 

Trigger Update_Country on Opportunity (before update, before insert) 
{
  Set<Id> setCountryObjectIds = new Set<Id>(); // set of all the related contry object id's
  Map<Id, Country_Object__c> mapCountryObjects = new Map<Id, Country_Object__c>(); // map of all the related country objects

  // Add all the country object Id's that are related to the Opportunities.
  for (Opportunity o : Trigger.new) 
  {
     setCountryObjectIds.add(o.Country_Object__c);
  }

  // Store all the related country object id's along with the objects in the map
  for(Country_Object__c obj : [Select Name From Country_Object__c Where Id IN :setCountryObjectIds])
  {
	mapCountryObjects.put(obj.Id, obj);
  }
 
 // Fill the Country__c field with the lookup name
  for (Opportunity o : Trigger.new) 
  {
     o.Country__c = mapCountryObjects.get(o.Country_Object__c).Name;
  }

}

 Let me know if I missed something. Hope it helps!

goabhigogoabhigo

Hey, first of all you can just use a formula field instead of trigger !!

Create a formula field (text) and its value would be something like this : Country_Object__r.Name. Thats it !!

 

In case you want this in trigger, change the code to the following:

 

o.Country__c = o.Country_Object__r.Name;

 

o.Country_Object__c is a lookup field hence it contains the ID of the record to which it is related to.

skiptomylou11skiptomylou11

Hi Vishal,

 

Many thanks for your help!!!

 

I have put together a test class, but unfortunately it is not working.

Maybe you have a chance to have a look...

 

Many thanks in advance!

Patrick

 

@isTest
private class TestUpdateCountryOpportunity{

    static testMethod void myUnitTest() {
          
        Account a = new Account();
        a.Name = 'TEST';
        insert a;  
            
        Opportunity o= new Opportunity (
        Name='test',
        AccountId = a.Id,
        CloseDate=Date.today(),
        Amount=1,
        StageName='1 - Marketing');
    }
}

 

vishal@forcevishal@force

Hi,

 

You created an opportunity but you forgot to insert/update it in your test class. That's the reason your code coverage failed.

Below code should be good for you : 

@isTest
private class TestUpdateCountryOpportunity{

    static testMethod void myUnitTest() {
          
        Account a = new Account();
        a.Name = 'TEST';
        insert a;  

	Country_Object__c co = new Country_Object__c();
	co.Name = 'test';
	insert co; // Please assign values to all the other required fields too.
            
        Opportunity o= new Opportunity (
        Name='test',
        AccountId = a.Id,
        CloseDate=Date.today(),
        Amount=1,
        StageName='1 - Marketing'
	Country_Object__c = co.Id); insert o;
    }
}

 Let me know if you face any issues. 

skiptomylou11skiptomylou11

Hi Vishal,

 

Many thanks for the hint!

When trying to delpoy I still get an error:

 

Failure Message: "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Update_Country_Opportunity: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.Update_Country_Opportunity: line 21, column 70: []", Failure Stac...

 

It seems to be referencing this part of the trigger

o.Country__c = mapCountryObjects.get(o.Country_Object__c).Name;

 

Your help is highly appreciated!!!

skiptomylou11skiptomylou11

Hi,

 

Many thanks for your support.

 

When I try to deploy I get the following error refering to the line of code you proposed.

Do you have any idea what to do?

 

Many thanks!!!!

 

TestUpdateCountryOpportunity.myUnitTest()Class1425Failure Message: "System.QueryException: List has no rows for assignment to SObject", Failure Stack Trace: "Class.TestUpdateCountryOpportunity.myUnitTest: line 14, column 25 External entry point"
krprkrpr

Hi,

 

Just to clarify

 

1. There is a Country_Object__c with fields Name, Country__c

2. There is a Lookup relation between Opportunity and Country_Object__c

3. When you associate Opportunity with Country_Object__c the Value from Country__c on Country_Object__C must be copied to Country__c on Opportunity.

 

Here is the updated Trigger and Unit Test

 

 

 

Trigger

 

trigger Update_Country on Opportunity (before insert, before update) {
    
    set<ID>cObjectID = new set<ID>();    
    
    for(Opportunity opp : Trigger.new){
        if(opp.Country_Object__c != null){
            cObjectID.add(opp.Country_Object__c);
        }
    }
    
    if(!cObjectID.isEmpty()){
        
        Map<ID,Country_Object__c> cObjectMap = new Map<ID,Country_Object__c>([select Id, Name,     
Country__c from Country_Object__c where Id IN: cObjectID]); for(Opportunity opp : trigger.new){ if(cObjectMap.get(opp.Country_Object__c).Country__c != Null){ // fill the country name on Opportunity with Country Name on Country_Object__c opp.Country__c = cObjectMap.get(opp.Country_Object__c).Country__c; } } } }

 

 

Unit Test

 

 

@isTest
private class TestUpdateCountryOpportunity {

    static testMethod void myUnitTest() {
        
        Account a = new Account(Name = 'Berlington');
        insert a;
        
        Country_Object__c cObj = new Country_Object__c(Name = 'Object1', Country__c = 'India');
        insert cObj;
        
        Opportunity o= new Opportunity ( Name='test',AccountId = a.Id,
CloseDate = Date.today(),Amount=1,
StageName='1 - Marketing', Country_Object__c = cObj.Id); insert o; Opportunity opp = [select Id, Name, Country__c from Opportunity where Id =: o.Id]; system.assertEquals(opp.Country__c, cObj.Country__c); } }

 

 

 

If it works for you, do mark them as 'Solution' as it may help others.

 

Thanks

krpr

This was selected as the best answer
skiptomylou11skiptomylou11

Many thanks krpr!!!

 

I was able to deploy the code.