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
SFDCDevQASFDCDevQA 

Issues with Trigger to match fields and copy data based on match

This is kind of a two part question.  First off I have a custom object called Country which has a multipicklist field called TimeZone.  I have an identical field on Accounts.  Ideally I want my trigger to do the following - If an account is created or the billing country is updated I want it to look for an exact match by BillingCountryName in the Account to the Country Records (Name field) and bring back the TimeZone information from the matching country record and plug it into the TimeZone field on the Account.  I would also like to have it check US states and give specific time zones for those (so multiple IF statements) before it goes into the lookup portion of the trigger.  For right now though I am just trying to get the portion where it searches the records and finds a match and brings back the timezone.  I keep receiving an error saying "Compile Error: Invalid type: TimeZone__c at line 19 column 64"  I'm sure it's just syntax but I've only done a trigger like this with a standard object so the custom part is throwing me off I think.  Here is the code I have thus far:

 

trigger AccountTimeZone on Account (before insert,before update) {

// gather all the Country Name's in a set

   Set<Name> setCountry_cNames = new Set<Name>();

   Account[] Acc = Trigger.new;
   for (Account a:acc)

   {
      setCountry_cNames.add(a.BillingCountry);

   }

 

   // store each Country Name with it's time zone in a map, such that Country Name => Country.TimeZone__c

   Map<Name, TimeZone__c> mapCountrytoTimeZone = new Map<Name, TimeZone__c>();

   for(Country__c c : [Select Name, TimeZone__c From Country__c Where Name IN : setCountry__cNames])

   {

      mapCountrytoTimezone.put(c.Name, c.TimeZone__c);
   }
   for (Account a:acc)
    {
       if(a.Timezone__c !=null)
       {
           a.Timezone__c = mapCountryToTimeZone.get(a.BillingCountry);
       }
   }  
}

Best Answer chosen by Admin (Salesforce Developers) 
Andrew WilkinsonAndrew Wilkinson

Right because at that line you are calling a put method when you should be calling get.

All Answers

Andrew WilkinsonAndrew Wilkinson

When you are declaring your map the type needs to be a data type or an object custom object. Create the map as follows...

 

Map<String, Country__c> mapCountrytoTimeZone = new Map<String, Country__c>();

 

Your put methods can stay the same. This should get rid of the compile error. I have never used Name as a type in a map. I usually use String...since name is a string. You may need to switch your set to a Set of String instead of a name as well.

sfdcconsultant2010sfdcconsultant2010

You have taken multi-select picklist field inside a map. this might be a problem.

 

Map<Name, TimeZone__c> mapCountrytoTimeZone = new Map<Name, TimeZone__c>();

 

 

If here you use any other field it would not throw the compile error e.g.

Map<Name, Site> mapCountrytoTimeZone = new Map<Name, Site>();

SFDCDevQASFDCDevQA

I changed the fields to text and updated the code to be strings but I keep getting Compile errors.  It now says Compile Error: Incompatible value type String for MAP<String,Name> at line 24 column 7 (in red below)and it gives the same error if I change Name to Country__c.  I still have to add all the caveats in and I can't even get the basic part to work.  I've done this same thing before with IDs on standard objects but for some reason with Names and other fields on a custom object it is giving me issues.  Any help would be greatly appreciated.

 

Thanks,

Amanda

 

trigger AccountTimeZoneUpdate on Account (before insert,before update) {
// gather all the Country Name's in a set

   Set<String> setCountryNames = new Set<String>();

   Account[] acc = Trigger.new;
   for (Account a:acc)

   {
      setCountryNames.add(a.BillingCountry);

   }

 

   // store each Country Name with it's timezone in a map, such that CountryName =>

Country__c.TimeZone__c

   Map<String, Name> mapCountrytoTimezone = new Map<String, Name>();

   for(Country__c c : [Select Name, Time_Zone__c From Country__c Where Name IN :

setCountryNames])

   {

      mapCountrytoTimezone.put(c.Name, c.Time_Zone__c);
   }
   for (Account a:acc)
    {
       if(a.BillingCountry !=null)
       {
           a.TimeZone_2__c = mapCountrytoTimezone.put(a.BillingCountry); //
       }
   }  
}

Andrew WilkinsonAndrew Wilkinson

What datatype is TimeZone__c

SFDCDevQASFDCDevQA

TimeZone__c is a multipicklist but in all but the notes I changed it to Time_Zone__c which is a text field.

Andrew WilkinsonAndrew Wilkinson

try a map of String,String...make sure to change it on both sides of the constructor.

SFDCDevQASFDCDevQA

If I change both to String on both sides of the map the error changes to

Compile Error: Method does not exist or incorrect signature: [MAP<String,String>].put(String) at line 32 column 30

 

Thanks,

Amanda

Andrew WilkinsonAndrew Wilkinson

Right because at that line you are calling a put method when you should be calling get.

This was selected as the best answer
SFDCDevQASFDCDevQA

That worked!  My other trigger that is based off IDs uses put in that spot....why would it change to get for this one?  Now I just have to figure out how to add multiple if then statements....is that possible?  Essentially like a formula but in a trigger?  So far all my triggers only have one if statement.

 

Thanks,

Amanda

Andrew WilkinsonAndrew Wilkinson

Put adds a key and value to the map. Get retrieves the value based off of the key you supply. So in this case you are retrieving the time zone based off of the Country Name key.

 

Yes you can have multiple if and else statements in a trigger. 

SFDCDevQASFDCDevQA

I've got my if else statement in and working - just a quick question about if I'm doing my OR statements properly or am I using too much defining?  What I've started with is the Eastern Time zone by state and have

if (a.billingcountry == 'United States'&& (a.billingstate == 'CT'|| a.billingstate == 'DC'|| a.billingstate == 'DE'|| a.billingstate == 'FL'|| a.billingstate == 'GA'|| a.billingstate == 'IN'|| a.billingstate == 'ME'|| a.billingstate == 'MD'|| a.billingstate == 'MA'|| a.billingstate == 'MI'|| a.billingstate == 'NH'|| a.billingstate == 'NJ'|| a.billingstate == 'NY'|| a.billingstate == 'NC'|| a.billingstate == 'OH'|| a.billingstate == 'PA'|| a.billingstate == 'RI'|| a.billingstate == 'SC'|| a.billingstate == 'VT'|| a.billingstate == 'VA'|| a.billingstate == 'WV'|| a.billingstate == 'ON'|| a.billingstate == 'QC'|| a.billingstate == 'NB'|| a.billingstate == 'NS'|| a.billingstate == 'NL'|| a.billingstate == 'PE')) {

    a.TimeZone__c = 'Eastern Time GMT-5';

 

Do I need to have a.billingstate == repeated for each state or is there a way to shorten that?

 

Thanks so much,

Amanda

Andrew WilkinsonAndrew Wilkinson

You have to define it somewhere so this works. If you ever wanted to reuse this in other classes then you may consider creating a static method that you pass the country and state in...then your method could return the time zone. The static method would look like that but it would be reusable.

 

Can you please mark my previous posts as a solution. Thanks. This way others may view it and benefit.

SFDCDevQASFDCDevQA

Thanks so much.  Your response regarding methods makes me worry I'm going to have a time trying to get the test class right but we'll see.  I posted the final part that got the first section of code working as the solution, although really it was multiple ones together that helped....kinda wish you could mark multiples but I guess it doesn't matter.

 

Thanks again,

Amanda

SFDCDevQASFDCDevQA

Got most of my test class done but I am getting a failure - System.AssertException: Assertion Failed.  Says line 34, column 1.  Debug log says FATAL_ERROR|System.AssertException: Assertion Failed

Class.AccountTimeZoneUpdate.testTrigger: line 34, column 1
11:51:53.690 (1690610000)|FATAL_ERROR|System.AssertException: Assertion Failed

Class.AccountTimeZoneUpdate.testTrigger: line 34, column 1
11:51:53.121 (1690629000)|

 

Here is my test class.  I tried removing the reload part thinking maybe that was it but that didn't help.  Aside from the Assertion failure I don't know how to get it to cover the line in the trigger "mapCountrytoTimezone.put(c.Name, c.TimeZone__c);" but I'm more worried about the Assertion failure.

 

Thanks so much,

Amanda

 

@IsTest
private class AccountTimeZoneUpdate
{
    private static TestMethod void testTrigger(){
         test.startTest();       
        //Step 1 : Data Insertion
        Account a=new Account(Name='Test Account', BillingCountry='Brazil');
           insert a;  
        Account a1=new Account(Name='Test Account1', BillingCountry='United States', BillingState='NC');
           insert a1;
        Account a2=new Account(Name='Test Account2', BillingCountry='United States', BillingState='TN');
           insert a2;
        Account a3=new Account(Name='Test Account3', BillingCountry='United States', BillingState='UT');
           insert a3;
        Account a4=new Account(Name='Test Account4', BillingCountry='United States', BillingState='CA');
           insert a4;
        Account a5=new Account(Name='Test Account5', BillingCountry='United States', BillingState='AZ');
           insert a5;
        Account a6=new Account(Name='Test Account6', BillingCountry='United States', BillingState='AK');
           insert a6;
        Account a7=new Account(Name='Test Account7', BillingCountry='United States', BillingState='HI');
           insert a7;
        Country__c c=new Country__c (Name='Brazil', Timezone__c='GMT-03:00');
             insert c;      
       
        //assert your results using system.assert and system.asserEquals

//reload objects to make sure values are loaded
        a= [select id, billingcountry, timezonepicklist__c from Account where id=:a.id];
        a1= [select id, billingcountry, billingstate, timezonepicklist__c from Account where id=:a1.id];
        c = [select id, name, Timezone__c from country__c where name=:a.billingcountry];


        system.assert(a.Timezonepicklist__c == c.Timezone__c);
        system.assert(a1.Timezonepicklist__c == 'Eastern Time GMT-5');
        system.assert(a2.Timezonepicklist__c == 'Central Time GMT-6');
        system.assert(a3.Timezonepicklist__c == 'Mountain Time GMT-7');
        system.assert(a4.Timezonepicklist__c == 'Pacific Time GMT-8');
        system.assert(a5.Timezonepicklist__c == 'Arizona GMT-7');
        system.assert(a6.Timezonepicklist__c == 'Alaska GMT-9');
        system.assert(a7.Timezonepicklist__c == 'Hawaii GMT-10');
               
        
        
        
        test.stopTest();
    }
}
Andrew WilkinsonAndrew Wilkinson

You need to insert the Country first for a to work. When a is inserted it is looking for a country object but none exist. All test data has to be created when you use @isTest. You can specify

 

@isTest

(SeeAllDate = true)

 

which would allow you to use Country objects you already created. But it is considered best practice to construct your own objects in your test class. This will ensure that when you move this code to another org it will not fail.

 

So construct and insert all of your Country objects first. One needs to match for each of your accounts. Then insert the accounts.

 

Currently since there is not a match for a1-a7 those will fail as well until you construct and insert country objects.

 

Also as a suggestion since you are inserting so many accounts.

 

It may be best to add them to a List<Account> first then insert them all in one DML. But that is just another best practice.

SFDCDevQASFDCDevQA

Andrew,

I tried changing it to insert the two countries I'm testing first and then the accounts but I'm still getting the same assertion error.

 

@IsTest
private class AccountTimeZoneUpdate
{
    private static TestMethod void testTrigger(){
         test.startTest();       
        //Step 1 : Data Insertion
        Country__c c=new Country__c (Name='Peru', Timezone__c='GMT-05:00');
           insert c;
        Country__c c1=new Country__c (Name='United States', Timezone__c='GMT-07:00-GMT-11:00');
           insert c1; 
        Account a=new Account(Name='Test Account', BillingCountry='Peru');
           insert a;  
        Account a1=new Account(Name='Test Account1', BillingCountry='United States', BillingState='NC');
           insert a1;
        Account a2=new Account(Name='Test Account2', BillingCountry='United States', BillingState='TN');
           insert a2;
        Account a3=new Account(Name='Test Account3', BillingCountry='United States', BillingState='UT');
           insert a3;
        Account a4=new Account(Name='Test Account4', BillingCountry='United States', BillingState='CA');
           insert a4;
        Account a5=new Account(Name='Test Account5', BillingCountry='United States', BillingState='AZ');
           insert a5;
        Account a6=new Account(Name='Test Account6', BillingCountry='United States', BillingState='AK');
           insert a6;
        Account a7=new Account(Name='Test Account7', BillingCountry='United States', BillingState='HI');
           insert a7;
     
       
        //assert your results using system.assert and system.asserEquals

        system.assert(a.Timezonepicklist__c == c.Timezone__c);
        system.assert(a1.Timezonepicklist__c == 'Eastern Time GMT-5');
        system.assert(a2.Timezonepicklist__c == 'Central Time GMT-6');
        system.assert(a3.Timezonepicklist__c == 'Mountain Time GMT-7');
        system.assert(a4.Timezonepicklist__c == 'Pacific Time GMT-8');
        system.assert(a5.Timezonepicklist__c == 'Arizona GMT-7');
        system.assert(a6.Timezonepicklist__c == 'Alaska GMT-9');
        system.assert(a7.Timezonepicklist__c == 'Hawaii GMT-10');
               
        
        
        
        test.stopTest();
    }
}
Andrew WilkinsonAndrew Wilkinson

You have to query the updated accounts and then assert against the query results. A is a reference to the object you created without the trigger updates to it.

 

so for example

 

Before your assert you can do

 

a = [SELECT TimeZonePickList__c FROM Account WHERE Id = :a.Id];

 

then your first assertion would work.

SFDCDevQASFDCDevQA

I had that in previously and took it out because it seemed like it wasn't doing anything.  I just added it back in and tried calling all of them seperately (as you see below) or above each of their assert lines and neither way worked.  It is still saying Assert failed.  I think the daylight savings time switch must be getting to me or something.

 

Thanks,

Amanda

 

@IsTest
private class AccountTimeZoneUpdate
{
    private static TestMethod void testTrigger(){
    test.startTest();        
        //Step 1 : Data Insertion
        Country__c c1=new Country__c (Name='United States', Timezone__c='GMT-07:00-GMT-11:00');
           insert c1;  
        Account a1=new Account(Name='Test Account1', BillingCountry='United States', BillingState='NC');
           insert a1;
        Account a2=new Account(Name='Test Account2', BillingCountry='United States', BillingState='TN');
           insert a2;
        Account a3=new Account(Name='Test Account3', BillingCountry='United States', BillingState='UT');
           insert a3;
        Account a4=new Account(Name='Test Account4', BillingCountry='United States', BillingState='CA');
           insert a4;
        Account a5=new Account(Name='Test Account5', BillingCountry='United States', BillingState='AZ');
           insert a5;
        Account a6=new Account(Name='Test Account6', BillingCountry='United States', BillingState='AK');
           insert a6;
        Account a7=new Account(Name='Test Account7', BillingCountry='United States', BillingState='HI');
           insert a7;
        Country__c c=new Country__c (Name='Peru', Timezone__c='GMT-05:00');
           insert c;
        Account a=new Account(Name='Test Account', BillingCountry='Peru');
           insert a;  
    
        //reload objects to make sure values are loaded
        c1 = [select id, name, Timezone__c from country__c where id=:c1.id];
        c = [select id, name, Timezone__c from country__c where id=:c.id];
        a1= [select id, billingcountry, Timezonepicklist__c from Account where id=:a1.id];
        a2= [select id, billingcountry, Timezonepicklist__c from Account where id=:a2.id];
        a3= [select id, billingcountry, Timezonepicklist__c from Account where id=:a3.id];
        a4= [select id, billingcountry, Timezonepicklist__c from Account where id=:a4.id];
        a5= [select id, billingcountry, Timezonepicklist__c from Account where id=:a5.id];
        a6= [select id, billingcountry, Timezonepicklist__c from Account where id=:a6.id];
        a7= [select id, billingcountry, Timezonepicklist__c from Account where id=:a7.id];
        a= [select id, billingcountry, Timezonepicklist__c from Account where id=:a.id];
               
       
        //assert your results using system.assert and system.asserEquals
        system.assert(a1.Timezonepicklist__c == 'Eastern Time GMT-5');
        system.assert(a2.Timezonepicklist__c == 'Central Time GMT-6');
        system.assert(a3.Timezonepicklist__c == 'Mountain Time GMT-7');
        system.assert(a4.Timezonepicklist__c == 'Pacific Time GMT-8');
        system.assert(a5.Timezonepicklist__c == 'Arizona GMT-7');
        system.assert(a6.Timezonepicklist__c == 'Alaska GMT-9');
        system.assert(a7.Timezonepicklist__c == 'Hawaii GMT-10');
        system.assert(a.Timezonepicklist__c == c.Timezone__c);            
        
     test.stopTest();
    }
}
sruthiforcesruthiforce
Trigger  convert billing Country(text field)  to std Country name before copying customer Country using ISO Country mapping
Billing Country is text field and can have any value. We need to convert it to Standard Country name before copying it over to custom country field using the ISO – Country mapping.
          There is a custom object for this mapping called Country. Based on the billing country get the correct country value from Country Object   and update custom country. If billing country is blank look for ISO country code based on that query the custom object and update.  If any time a match is not found for the country from the ISO country code, don’t copy the country value. Leave it blank.
 
 
 
trigger BillingAddress  on Account (before insert, before update) {
   

        for(Account acct : Trigger.new){


       if((acct.OS_Address_1__c==null && acct.OS_City__c==null && 

           acct.OS_State__c==null &&  acct.D_B_Country__c==null  &&

           acct.D_B_Postal_Code__c==null) &&  

        

          ( acct.BillingStreet !=null || acct.BillingCity !=null || 

           acct.
BillingCountry !=null || acct.BillingPostalCode !=null ||
           acct.BillingState !=null )){
          

       

                acct.OS_Address_1__c = acct.BillingStreet;

                acct.OS_City__c = acct.BillingCity;

                acct.OS_State__c = acct.BillingState;

                acct.D_B_Country__c = acct.BillingCountry;

                acct.OS_Postal_Code__c = acct.BillingPostalCode;      

     

        }    

     }    

 }
Pleas help me on this
SFDCDevQASFDCDevQA

I'm not fully following what you are trying to do here.  How do you plan to convert a country name of any value to a standard country name?  And then why are you copying it to a custom country field?  Can you explain this in a bit more detail?  Also it would probably be best helped via starting a new Message.

 

Thanks,

Amanda

sruthiforcesruthiforce

 

Trigger on account: If custom address is null and billing address is not null, populate the custom address with billing address.

 

 

          Billing Country is text field and can have any value. We need to convert it to Standard Country   name before copying it over to custom country field using the ISO – Country mapping.

          There is a custom object for this mapping called Country. Based on the billing country get the correct country value from Country Object   and update custom country. If billing country is blank look for ISO country code based on that query the custom object and update.  If any time a match is not found for the country from the ISO country code, don’t copy the country value. Leave it blank.

Fields:Account Object                            Fields: Countries Object

  OS_Address_1__c--Text(200)                           Country__c  -- Picklist
  OS_City__c          --Text(100)                            ISO2__c   -- Picklist
  OS_State__c        --Text(100)
  OS_Postal_Code__c  --Text(40)
  D_B_Country__c      --Picklist
  ISO_Country_Code__c--Text(2)
Standard Fields
  Billing Address         Address
 

please check once.

trigger BillingAddPopulateOnCustomAddrs  on Account (before insert, before update) {
   
       list<Country__c> ct =  [select name,ISO2__c from Country__c];
        Country__c  obj = new Country__c();
        set<Country__c> set1=new set<Country__c>();
        set1.addall(ct);
        for(Account acct : Trigger.new){

       if((acct.OS_Address_1__c==null && acct.OS_City__c==null && 
           acct.OS_State__c==null &&  acct.D_B_Country__c==null  &&
           acct.D_B_Postal_Code__c==null) &&  
        
          ( acct.BillingStreet !=null || acct.BillingCity !=null || 
           acct.BillingState !=null || acct.BillingPostalCode !=null ||
           acct.BillingCountry !=null  )) {
           
        //Moving Billing Address to CustomAddress
                acct.OS_Address_1__c = acct.BillingStreet;
                acct.OS_City__c = acct.BillingCity;
                acct.OS_State__c = acct.BillingState;
                acct.OS_Postal_Code__c = acct.BillingPostalCode;
                
                obj.name = acct.BillingCountry;
                if(set1.contains(obj))
               {
                acct.D_B_Country__c = acct.BillingCountry;
                acct.ISO_Country_Code__c = obj.ISO2__c;
               }
               else
               acct.D_B_Country__c = '    ';
                
     
        }    
     }    
 }