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
kathybbkathybb 

Before Insert Trigger question

I am writting a before insert trigger to copy information from the related Account record to an opporunity record on insert.  I'm creating the test account records, and using them in the opportunities that my test creates.  When I look at the Opportunities records as I am creating them, the Account fields  (name and ID) are filled in correctly on the opportunities.  When my trigger tries to build a set of accounts to copy from, the Account field(s) do not show up in the Trigger.new copies of the records, although all the other fields do show up.  I'll attach the trigger and the test code below.  Can someone help me understand what is happening to my Account fields?  Do I need to store the Account IDs in separate text fields to be able to get the accounts back?

 

Here's the code for the trigger:

 

trigger FillFieldsFromAcct on Opportunity (before insert){ 
{
    RecordType rt1 = [select id from RecordType where Name = 'PubDev Opportunities' and SobjectType = 'Opportunity' limit 1];
    Set<String> aNameSet1 = new Set<String>();
    List<Opportunity> oppsToInsert = new List<Opportunity>();
	List<Account> acctsToInsert = new List<Account>();
    Map<string,string> MasterMap= new Map<string,string>();
	
    for(Opportunity o : Trigger.New){
        o = (Opportunity)o;
        aNameSet1.add(o.Account.Name);
		MasterMap.put(o.name, o.account.name);
    }
    string qry = 'Select Name,Mobile__c, Video__c, Display__c, Monthly_Display_Imps__c, Monthly_Mobile_Imps__c, Monthly_Video_Imps__c,' + 
                    ' uniques__c, vertical__c, Pageviews__c  from Account where Name IN :aNameSet1';
     string qry2 = 'Select Name,Mobile__c, Video__c, Display__c, Monthly_Display_Impressions__c, Monthly_Mobile_Impressions__c, Monthly_Video_Impressions__c,' + 
                    ' uniques__c, vertical__c, Pageviews__c, Account.id, Account.name  from Opportunity where Account.name IN :aNameSet1';
                                          
    Map<string, Account>aNameToAccountMap = new Map<Id,Account>((List<Account>)Database.query(qry));
    Map<string, Opportunity>OppMap= new Map<string, Opportunity>((List<Opportunity>)Database.query(qry2));
    
    For(Opportunity thisopp : Trigger.new){
        thisopp = (Opportunity)thisopp;
        Account acctToCopy = new Account();
    
        if(thisopp.RecordTypeId != rt1.id){
            system.debug('thisopp.RecordTypeId = ' + thisopp.RecordTypeID );
            return;
        }
            string myAcct = thisopp.Account.name;
            acctToCopy = aNameToAccountMap.get(myAcct);
            if(acctToCopy == NULL){
                return;
            } 
            acctToCopy = (Account)acctToCopy;
        	system.debug('acctToCopy = '+ acctToCopy.name);
            thisopp.Display__c = acctToCopy.Display__c;
            thisopp.Mobile__c = acctToCopy.Mobile__c;
            thisopp.Video_PubDev__c = acctToCopy.Video__c;
            thisopp.Monthly_Display_Impressions__c = acctToCopy.Monthly_Display_Imps__c;
            thisopp.Monthly_Video_Impressions__c = acctToCopy.Monthly_Video_Imps__c;
            thisopp.Monthly_Mobile_Impressions__c = acctToCopy.Monthly_Mobile_Imps__c;
            thisopp.Uniques__c = acctToCopy.Uniques__c;
            thisopp.Pageviews__c = acctToCopy.Uniques__c;
            thisopp.Vertical__c = acctToCopy.Vertical__c;
        	system.debug('thisopp has been created -- back to Test ' + thisopp);
                    }
    
    }
}

 And here is the test:

 

@isTest
private class TestingOppTrigger {
static testMethod void verify_Opp_Fillin() {
List<Opportunity> oppsToInsert = new List<Opportunity>();
List<Account> acctsToInsert = new List<Account>();
RecordType rt = [select id from RecordType where Name = 'PubDev Opportunities' and SobjectType = 'Opportunity' limit 1];
integer y = 0;
Account s = new Account();

Opportunity o = new Opportunity();

//create Accounts

Account testAcct1 = new Account(Name='KBBTestAcct1', Vertical__c = 'Education',Uniques__c = 30000, Pageviews__c=20000,Display__c=TRUE, Video__c =TRUE,
Mobile__c = TRUE, Monthly_Display_Imps__c = 500000,Monthly_Mobile_Imps__c = 500003, Monthly_Video_Imps__c = 500002);
acctsToInsert.add(TestAcct1);
Account testAcct2 = new Account(Name='KBBTestAcct2');
acctsToInsert.add(TestAcct2);
try{
database.insert(acctsToInsert);
} catch(DMLException e) {
system.debug('ERROR: ' + e);
}

//Map inserted Accounts
string qry3 = 'select name, id, display__c, mobile__c, video__c, Monthly_Display_Imps__c, Monthly_video_Imps__c,' +
' Monthly_Mobile_Imps__c, Uniques__c, Pageviews__c, Vertical__c ' +
' from Account where CreatedDate = TODAY';
Map<string, Account> AccountMap = new Map<string, Account>((List<account>)Database.query(qry3));


//Create new Opportunities
for(y=0;y<2;y++){
Opportunity TestOppFilled = new Opportunity(RecordTypeID = rt.id, Name='KBBTestOpp' + y, Account= (Account)testAcct1,
StageName = '3 - On Hold',Id_Surrogate__c = 'KBBTestOpp' + y,
CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
oppsToInsert.add(TestOppFilled);

Opportunity TestOppEmpty = new Opportunity(RecordTypeID = rt.id, Name= 'KBBTestOpp' + 1000 + y,
Account = (Account)testAcct2, StageName = '3 - On Hold',Id_Surrogate__c = 'KBBTestOpp' + 1000 + y,
CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
oppsToInsert.add(TestOppEmpty);
}
// Insert Opportunities
try{
system.debug ('trying to insert Opportunities');
database.insert(oppsToInsert);
} catch(DMLException e1) {
system.debug('ERROR: ' + e1);
}

Map<string,Account>oIdToAccountMap = new Map<string, Account>();

for(Sobject z : Trigger.new){
Opportunity Oppty = new Opportunity();
Oppty = (Opportunity)z;
oIdToAccountMap.put(Oppty.Name, AccountMap.get(Oppty.Account.name));

//verify opportunity copy of account data
system.assertEquals(Oppty.Vertical__c,Oppty.Account.Vertical__c );
system.assertEquals(Oppty.Uniques__c,Oppty.Account.Uniques__c );
system.assertEquals(Oppty.Pageviews__c,Oppty.Account.Pageviews__c );
system.assertEquals(Oppty.Display__c,Oppty.Account.Display__c );
system.assertEquals(Oppty.Video_PubDev__c,Oppty.Account.Video__c );
system.assertEquals(Oppty.Mobile__c,Oppty.Account.Mobile__c );
system.assertEquals(Oppty.Monthly_Display_Impressions__c,Oppty.Account.Monthly_Display_Imps__c );
system.assertEquals(Oppty.Monthly_Video_Impressions__c,Oppty.Account.Monthly_Video_Imps__c);
system.assertEquals(Oppty.Monthly_Mobile_Impressions__c,Oppty.Account.Monthly_Mobile_Imps__c );
}
}
}

 

Thanks in advance.  This is my first non-trivial trigger, so I'm a newbie and will appreciate any insight you can offer.

 

kbb

Best Answer chosen by Admin (Salesforce Developers) 
kathybbkathybb

Thanks to everyone who helped me with this problem -- I understand triggers much better now.  The actual problem occurred because I was using a before insert trigger when I needed to be using an after insert trigger.

 

When the documentation says (paraphrasing here) that system generated fields are not available in Trigger.new in before insert triggers, they are talking about  fields that create a relationship as well as formula fields, fields that get changed by workflow rules, etc.  Because of the order of execution, at the time I was trying to use information in a relationship field, the relational Account fields were not available.  Attempting to use them resulted in a return of NULL, which I could see in the debug log.

 

An after insert trigger works the way I needed it to in this case.  It didn't matter if I used AccountID or the Account.id, Account.name nomenclature -- Trigger.new just didn't have the information needed at the before insert point in time.  This was counter-intuative for me because I had filled in the Account field on the opportunity record that fired the trigger but it turns out that this is the way before insert triggers work.  The relationships are generated after a record is inserted.

 

Thank you to everyone who answered my question -- your input helped me with using maps and generally structuring my trigger so it did what I needed done.  The discussion board has helped me a lot, and is the first place I look when I encounter a new problem.  You all are awesome!

 

All Answers

kirkevonphillykirkevonphilly

Hi KBB,

 

Rather than building a set of accounts to copy from, you could build a <id,Account> map to pull the values from.  I think doing this could greatly reduce the complexity of your code and make testing easier too.  

 

You'll need to add your record type criteria and the Account fields to the map query:

trigger FillFieldsFromAcct on Opportunity (before insert){ 
    set<id> tmpSet = new set<id>();
    for (Opportunity o : trigger.new){
        tmpSet.add(o.AccountID);
    }
    
    map<id,Account> acct_map;
    if (!tmpSet.isEmpty()){
        acct_map = new map<id,Account>([select id, Custom_Field_1__c, Custom_Field_2__c from Account where id in:tmpSet]);
        if(!acct_map.isEmpty()){
            for (Opportunity o : trigger.new){
                o.Custom_Field_1__c = acct_map.get(o.AccountID).Custom_Field_1__c;
                o.Custom_Field_2__c = acct_map.get(o.AccountID).Custom_Field_2__c;
            }
        }
    }
}

 

harsha__charsha__c
aNameSet1.add(o.Account.Name);

 I think this is your 11th line  of your trigger

 

This is not possible in the trigger as the trigger.new won't provide the reference values

You can access only Opprtunity fieds in this case

 

And if youo need any referenced fields you need to externally query and use them

 

 

If this makes your case solved, mark it as a solution

kathybbkathybb

Thanks for your help, Kirk.

  I tried the code you sent me, and have pasted what I have in the code window.  The problem now is that the tmpSet remains empty because Trigger.new doesn't give me access to the Account field.  This problem isdriving me crazy.  Do you have any other suggestions for keeping the account mapped to the relevant opportunity?  Thank you for your help.

 

trigger FillFieldsFromAcct on Opportunity (before insert){ 
    set<id> tmpSet = new set<id>();
    for (Opportunity o : trigger.new){
        tmpSet.add(o.AccountID); }   //not getting anything in the tmpSet
    map<id,Account> acct_map; 
    if (!tmpSet.isEmpty()){ 
        acct_map = new map<id,Account>([select id,Mobile__c, Video__c, Display__c, Monthly_Display_Imps__c, Monthly_Mobile_Imps__c, Monthly_Video_Imps__c,
                    uniques__c, vertical__c, Pageviews__c from Account where id in:tmpSet]);; 
        if(!acct_map.isEmpty())  { 
        for (Opportunity o : trigger.new){
            o.Mobile__c = acct_map.get(o.AccountID).Mobile__c; 
     		o.Video_PubDev__c = acct_map.get(o.AccountID).Video__c;
     		o.Display__c = acct_map.get(o.AccountID).Display__c; 
     		o.Monthly_Display_Impressions__c = acct_map.get(o.AccountID).Monthly_Display_Imps__c; 
     		o.Monthly_Video_Impressions__c = acct_map.get(o.AccountID).Monthly_Video_Imps__c;
         	o.Monthly_Mobile_Impressions__c= acct_map.get(o.AccountID).Monthly_Mobile_Imps__c; 
     		o.Vertical__c = acct_map.get(o.AccountID).Vertical__c; 
     		o.Pageviews__c = acct_map.get(o.AccountID).Pageviews__c;
             o.Uniques__c = acct_map.get(o.AccountID).Uniques__c; 
        } 
    } 
} 
}

 

kathybbkathybb

Hi, Hasha_trekbin,

 

I'm sure you are correct as to the reason for my problems.  Can you please explain what you mean by "externally query"?  That is, I know how to include a SOQL query in the body of my trigger, but that doesn't get me any Account IDs to map (naturally, since Trigger.New doesn't see this as an Opportunity field.  Is there some way to gather the Accounts for mapping outside my code?  Here is what I have so far:

trigger FillFieldsFromAcct on Opportunity (before insert){ 
    set<id> tmpSet = new set<id>();
    for (Opportunity o : trigger.new){
        tmpSet.add(o.AccountID); }
    map<id,Account> acct_map; 
    if (!tmpSet.isEmpty()){ 
        acct_map = new map<id,Account>([select id,Mobile__c, Video__c, Display__c, Monthly_Display_Imps__c, Monthly_Mobile_Imps__c, Monthly_Video_Imps__c,
                    uniques__c, vertical__c, Pageviews__c from Account where id in:tmpSet]);; 
        if(!acct_map.isEmpty())  { 
        for (Opportunity o : trigger.new){
            o.Mobile__c = acct_map.get(o.AccountID).Mobile__c; 
     		o.Video_PubDev__c = acct_map.get(o.AccountID).Video__c;
     		o.Display__c = acct_map.get(o.AccountID).Display__c; 
     		o.Monthly_Display_Impressions__c = acct_map.get(o.AccountID).Monthly_Display_Imps__c; 
     		o.Monthly_Video_Impressions__c = acct_map.get(o.AccountID).Monthly_Video_Imps__c;
         	o.Monthly_Mobile_Impressions__c= acct_map.get(o.AccountID).Monthly_Mobile_Imps__c; 
     		o.Vertical__c = acct_map.get(o.AccountID).Vertical__c; 
     		o.Pageviews__c = acct_map.get(o.AccountID).Pageviews__c;
             o.Uniques__c = acct_map.get(o.AccountID).Uniques__c; 
        } 
    } 
} 
}

 Thank you again for your help.

Kathybb

kirkevonphillykirkevonphilly

Hi kbb,

 

On your Opportunity object, are you both using and populating the standard Account field?

rajjjjrajjjj

I am also learning apex code and I got that working...

please check that you are not assigning ur field values of accountid and accountname.

 

trigger CopyAccounttoOpp on Opportunity (before insert) {
	
	Set<Id> accIdSet = new Set<Id>();
	for(Opportunity opp : trigger.new)
	{
		accIdSet.add(opp.AccountId); 
	}
Map<Id,Account> accmap = new Map<Id,Account>([select Id, Name from Account where Id IN: accIdSet]);
for(Opportunity o : trigger.new) { o.AccountName__c = accmap.get(o.AccountId).Name; o.AccountNumber__c = accmap.get(o.AccountId).Id;
//insert whatever fields to need to insert... } }

 

kathybbkathybb
Yes, my test is creating opportunity records by assigning Account=[whatever] which assigns the account name and accou nt id. This is present before the records are inserted. I'm looking at them using system.debug. However at the point they are inserted (that is, when the trigger is fired) there is nothing in either field because Account is the parent record to the opporunity. Thank you again for your help. Kathybb
kirkevonphillykirkevonphilly

Can you provide your latest code?

kathybbkathybb

Sure.  Here's the trigger:

 

trigger FillFieldsFromAcct on Opportunity (before insert){ 
    set<id> tmpSet = new set<id>();
    for (Opportunity opp : trigger.new){
        tmpSet.add(opp.AccountID); 
    	system.debug(opp.AccountID);
    }          
    map<id,Account> acct_map; 
    
    if (!tmpSet.isEmpty()){ 
        acct_map = new map<id,Account>([select id,Mobile__c, Video__c, Display__c, Monthly_Display_Imps__c, Monthly_Mobile_Imps__c, Monthly_Video_Imps__c,
                    uniques__c, vertical__c, Pageviews__c from Account where id in:tmpSet]);
        if(!acct_map.isEmpty())  { 
        for (Opportunity o : trigger.new){
            o.Mobile__c = acct_map.get(o.AccountID).Mobile__c; 
     		o.Video_PubDev__c = acct_map.get(o.AccountID).Video__c;
     		o.Display__c = acct_map.get(o.AccountID).Display__c; 
     		o.Monthly_Display_Impressions__c = acct_map.get(o.AccountID).Monthly_Display_Imps__c; 
     		o.Monthly_Video_Impressions__c = acct_map.get(o.AccountID).Monthly_Video_Imps__c;
         	o.Monthly_Mobile_Impressions__c= acct_map.get(o.AccountID).Monthly_Mobile_Imps__c; 
     		o.Vertical__c = acct_map.get(o.AccountID).Vertical__c; 
     		o.Pageviews__c = acct_map.get(o.AccountID).Pageviews__c;
             o.Uniques__c = acct_map.get(o.AccountID).Uniques__c; 
        }
        }
    } 
}

 And here's the test:

 

@isTest
private class TestingOppTrigger {
static testMethod void verify_Opp_Fillin() {
    List<Opportunity> oppsToInsert = new List<Opportunity>();
    List<Account> acctsToInsert = new List<Account>();
    RecordType rt = [select id from RecordType where Name = 'PubDev Opportunities' and SobjectType = 'Opportunity' limit 1];
    integer y = 0;
    Account s = new Account();
    
    Opportunity o = new Opportunity();
        
                        //create Accounts
    
    Account testAcct1 = new Account(Name='KBBTestAcct1', Vertical__c = 'Education',Uniques__c = 30000, Pageviews__c=20000,Display__c=TRUE, Video__c =TRUE,
    Mobile__c = TRUE, Monthly_Display_Imps__c = 500000,Monthly_Mobile_Imps__c = 500003, Monthly_Video_Imps__c = 500002);
    acctsToInsert.add(TestAcct1);
    Account testAcct2 = new Account(Name='KBBTestAcct2');
    acctsToInsert.add(TestAcct2);
    try{
    database.insert(acctsToInsert);
    } catch(DMLException e) {
        system.debug('ERROR:  ' + e);
    }
   	
    //Map inserted Accounts
    string qry3 = 'select name, id, display__c, mobile__c, video__c, Monthly_Display_Imps__c, Monthly_video_Imps__c,' +
        ' Monthly_Mobile_Imps__c, Uniques__c, Pageviews__c, Vertical__c ' + 
           ' from Account where CreatedDate = TODAY'; 
    Map<id, Account> AccountMap = new Map<id, Account>((List<account>)Database.query(qry3));
    
   
    					//Create new Opportunities
     for(y=0;y<2;y++){
            Opportunity TestOppFilled = new Opportunity(RecordTypeID = rt.id, Name='KBBTestOpp' + y, Account= testAcct1, 
            StageName = '3 - On Hold',
            CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
            oppsToInsert.add(TestOppFilled);
                  
             Opportunity TestOppEmpty = new Opportunity(RecordTypeID = rt.id, Name= 'KBBTestOpp' + 1000 + y,
             Account = testAcct2, StageName = '3 - On Hold',
             CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
             oppsToInsert.add(TestOppEmpty);
         }
   					// Insert Opportunities
      try{
         system.debug ('trying to insert Opportunities');
         database.insert(oppsToInsert);
         } catch(DMLException e1) {
             system.debug('ERROR:  ' + e1);
         }
    
    Map<string,Account>oIdToAccountMap = new Map<string, Account>(); 
     
    for(Sobject z : Trigger.new){
        Opportunity Oppty = new Opportunity();
        if(Oppty != Null){
            
        Oppty = (Opportunity)z;
        oIdToAccountMap.put(Oppty.Name, AccountMap.get(Oppty.Account.name));
        
                                //verify opportunity copy of account data
        system.assertEquals(Oppty.Vertical__c,Oppty.Account.Vertical__c );
        system.assertEquals(Oppty.Uniques__c,Oppty.Account.Uniques__c );
        system.assertEquals(Oppty.Pageviews__c,Oppty.Account.Pageviews__c );
        system.assertEquals(Oppty.Display__c,Oppty.Account.Display__c );
        system.assertEquals(Oppty.Video_PubDev__c,Oppty.Account.Video__c );
        system.assertEquals(Oppty.Mobile__c,Oppty.Account.Mobile__c );      
        system.assertEquals(Oppty.Monthly_Display_Impressions__c,Oppty.Account.Monthly_Display_Imps__c );
        system.assertEquals(Oppty.Monthly_Video_Impressions__c,Oppty.Account.Monthly_Video_Imps__c);
        system.assertEquals(Oppty.Monthly_Mobile_Impressions__c,Oppty.Account.Monthly_Mobile_Imps__c ); 
         }
    }
}
      }

 I really appreciate your help with this.  The weird thing is that the trigger works properly with only one record at a time, but comes up with NULL when I try to query for the related accounts with multiple inserts in the test.  I really want to understand what is going on with this because I can a see several places where before insert triggers would be good to use if only I can get this working.

 

Thank you again,

Kathy

kirkevonphillykirkevonphilly

After inserting your opportunities, you need to pull them back into a new list, being sure to include the Account fields in the query.

 

Using this line as an example, we have no idea what Oppty.Account.Vertical__c is as we've never asked SF for it, resulting in the NULL.

system.assertEquals(Oppty.Vertical__c,Oppty.Account.Vertical__c );

You'll want to do something like this:

list<Opportunity> o_list = [select Vertical__c, Account.Vertical__c from Opportunity where id in:oppsToInsert];

for(Opportunity Oppty :o_list){ system.assertEquals(Oppty.Vertical__c,Oppty.Account.Vertical__c ); }

 

kathybbkathybb

Thank you so much for your help.

I changed my test code to to query back the opportunities before the assertions..  My basic problem still remains.  The documentation says that on the trigger side of a before insert query, I don't have access to relationship fields, in this case Account.id and Account.name.  This trigger is supposed to copy the custom field information from the related account custom fields.  However, when I build my set of Account IDs in the trigger itself, it is inserting NULL for all of  them and the trigger has no information as to which Account it should be copying from.

 

Here's the trigger code:

 

trigger FillFieldsFromAcct on Opportunity (before insert){ 
    set<id> tmpSet = new set<id>();
    for (Opportunity opp : trigger.new){
        tmpSet.add(opp.Account.ID);              //// This is where the NULLs are coming from, because somehow the Account relational fields are disappearing between the Test where they are present, and the Trigger where they are not.
    	system.debug(opp.Account.ID);
    }          
    map<id,Account> acct_map; 
    
    if (!tmpSet.isEmpty()){ 
        acct_map = new map<id,Account>([select id,Mobile__c, Video__c, Display__c, Monthly_Display_Imps__c, Monthly_Mobile_Imps__c, Monthly_Video_Imps__c,
                    uniques__c, vertical__c, Pageviews__c from Account where id in:tmpSet]);
        if(!acct_map.isEmpty())  { 
        for (Opportunity o : trigger.new){
            o.Mobile__c = acct_map.get(o.AccountID).Mobile__c; 
     		o.Video_PubDev__c = acct_map.get(o.AccountID).Video__c;
     		o.Display__c = acct_map.get(o.AccountID).Display__c; 
     		o.Monthly_Display_Impressions__c = acct_map.get(o.AccountID).Monthly_Display_Imps__c; 
     		o.Monthly_Video_Impressions__c = acct_map.get(o.AccountID).Monthly_Video_Imps__c;
         	o.Monthly_Mobile_Impressions__c= acct_map.get(o.AccountID).Monthly_Mobile_Imps__c; 
     		o.Vertical__c = acct_map.get(o.AccountID).Vertical__c; 
     		o.Pageviews__c = acct_map.get(o.AccountID).Pageviews__c;
             o.Uniques__c = acct_map.get(o.AccountID).Uniques__c; 
        }
        }
    } 
}

 Can you suggest any way to solve this problem?  I don't want to use an update trigger because I only want this to happen on insert.  I'm probably doing something wrong in all of this, I know, but can you help me figure out the way to make this work?

 

for completeness, here's my Test code as it stands:

@isTest
private class TestingOppTrigger {
static testMethod void verify_Opp_Fillin() {
    List<Opportunity> oppsToInsert = new List<Opportunity>();
    List<Account> acctsToInsert = new List<Account>();
    RecordType rt = [select id from RecordType where Name = 'PubDev Opportunities' and SobjectType = 'Opportunity' limit 1];
    integer y = 0;
    Account s = new Account();
    
    Opportunity o = new Opportunity();
        
                        //create Accounts
    
    Account testAcct1 = new Account(Name='KBBTestAcct1', Vertical__c = 'Education',Uniques__c = 30000, Pageviews__c=20000,Display__c=TRUE, Video__c =TRUE,
    Mobile__c = TRUE, Monthly_Display_Imps__c = 500000,Monthly_Mobile_Imps__c = 500003, Monthly_Video_Imps__c = 500002);
    acctsToInsert.add(TestAcct1);
    Account testAcct2 = new Account(Name='KBBTestAcct2');
    acctsToInsert.add(TestAcct2);
    try{
    database.insert(acctsToInsert);
    } catch(DMLException e) {
        system.debug('ERROR:  ' + e);
    }
   	
    //Map inserted Accounts
    string qry3 = 'select name, id, display__c, mobile__c, video__c, Monthly_Display_Imps__c, Monthly_video_Imps__c,' +
        ' Monthly_Mobile_Imps__c, Uniques__c, Pageviews__c, Vertical__c ' + 
           ' from Account where CreatedDate = TODAY'; 
    Map<id, Account> AccountMap = new Map<id, Account>((List<account>)Database.query(qry3));
    
   
    					//Create new Opportunities
     for(y=0;y<2;y++){
            Opportunity TestOppFilled = new Opportunity(RecordTypeID = rt.id, Name='KBBTestOpp' + y, Account= testAcct1, 
            StageName = '3 - On Hold',
            CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
            oppsToInsert.add(TestOppFilled);
                  
             Opportunity TestOppEmpty = new Opportunity(RecordTypeID = rt.id, Name= 'KBBTestOpp' + 1000 + y,
             Account = testAcct2, StageName = '3 - On Hold',
             CloseDate = date.parse('3/30/2033'), Pub_Dev_Rep__c = 'Jason');
             oppsToInsert.add(TestOppEmpty);
         }
   					// Insert Opportunities
      try{
         system.debug ('trying to insert Opportunities');
         database.insert(oppsToInsert);
         } catch(DMLException e1) {
             system.debug('ERROR:  ' + e1);
         }
    
            List<Opportunity>o_list = new List<Opportunity>();
            o_list = [select display__c, Account.display__c, mobile__c, Account.mobile__c, video__c,Account.video__c,
                                       Monthly_Display_Impressions__c,Account.Monthly_Display_Imps__c, Monthly_video_Impressions__c,
                                       Account.Monthly_Video_Imps__c, Monthly_Mobile_Impressions__c, Account.Monthly_Mobile_Imps__c,
                                       uniques__c, Account.Uniques__c, Pageviews__c, Account.Pageviews__c, Vertical__c, Account.Vertical__c from Opportunity
                                       where name LIKE 'KBBTestOpp%'];
        
                                //verify opportunity copy of account data
            For(Opportunity newOppty : o_list){
                if(newOppty != NULL){
                    if(newOppty.Vertical__c != NULL){
                        system.assertEquals(newOppty.Vertical__c,newOppty.Account.Vertical__c );
                    } else {
                        system.assertEquals(newOppty.Account.Vertical__c, NULL);
                            }
                    
                    if(newOppty.Uniques__c != NULL){
                        system.assertEquals(newOppty.Uniques__c,newOppty.Account.Uniques__c );
                    } else {
                        system.assertEquals(newOppty.Account.Uniques__c, NULL);
                            }
        			if(newOppty.Uniques__c != NULL){
                        system.assertEquals(newOppty.Pageviews__c,newOppty.Account.Pageviews__c );
                    } else {
                        system.assertEquals(newOppty.Account.Uniques__c, NULL);
                            }
         			if(newOppty.Display__c != NULL){
                        system.assertEquals(newOppty.Display__c,newOppty.Account.Display__c );
                    } else {
                        system.assertEquals(newOppty.Account.Display__c, NULL);
                            }
        			if(newOppty.Video_Pubdev__c != NULL){
                        system.assertEquals(newOppty.Video_Pubdev__c,newOppty.Account.Video__c );
                    } else {
                        system.assertEquals(newOppty.Account.Video__c, NULL);
                            }
         			if(newOppty.Mobile__c != NULL){
                        system.assertEquals(newOppty.Mobile__c,newOppty.Account.Mobile__c );
                    } else {
                        system.assertEquals(newOppty.Account.Mobile__c, NULL);
                            }
       				 if(newOppty.Monthly_Display_Impressions__c != NULL){
                        system.assertEquals(newOppty.Monthly_Display_Impressions__c,newOppty.Account.Monthly_Display_Imps__c );
                    } else {
                        system.assertEquals(newOppty.Account.Monthly_Display_Imps__c, NULL);
                            } 
        			if(newOppty.Monthly_Video_Impressions__c != NULL){
                        system.assertEquals(newOppty.Monthly_Video_Impressions__c,newOppty.Account.Monthly_Video_Imps__c );
                    } else {
                        system.assertEquals(newOppty.Account.Monthly_Video_Imps__c, NULL);
                            } 
                                            
         			if(newOppty.Monthly_Mobile_Impressions__c != NULL){
                        system.assertEquals(newOppty.Monthly_Mobile_Impressions__c,newOppty.Account.Monthly_Mobile_Imps__c );
                    } else {
                        system.assertEquals(newOppty.Account.Monthly_Mobile_Imps__c, NULL);
                            } 
                                            }
        
         }
    }
}

 

 

I really appreciate all the help you've given me so far.

 

Kathy

 

kirkevonphillykirkevonphilly

On the line you pointed out, you have the following instead of what was in my block of code:

tmpSet.add(opp.Account.ID);  

Remove the "."

tmpSet.add(opp.Account.ID);  

This will keep you on the Opportunity level, rather than trying to traverse the Opportunity-->Account relationship.

 

for (Opportunity opp : trigger.new){
        tmpSet.add(opp.AccountID);
    	system.debug(opp.AccountID);  //should give you the ID
system.debug(opp.Account.ID); //will continue to give you null

 

 

 

 

kathybbkathybb

Thanks to everyone who helped me with this problem -- I understand triggers much better now.  The actual problem occurred because I was using a before insert trigger when I needed to be using an after insert trigger.

 

When the documentation says (paraphrasing here) that system generated fields are not available in Trigger.new in before insert triggers, they are talking about  fields that create a relationship as well as formula fields, fields that get changed by workflow rules, etc.  Because of the order of execution, at the time I was trying to use information in a relationship field, the relational Account fields were not available.  Attempting to use them resulted in a return of NULL, which I could see in the debug log.

 

An after insert trigger works the way I needed it to in this case.  It didn't matter if I used AccountID or the Account.id, Account.name nomenclature -- Trigger.new just didn't have the information needed at the before insert point in time.  This was counter-intuative for me because I had filled in the Account field on the opportunity record that fired the trigger but it turns out that this is the way before insert triggers work.  The relationships are generated after a record is inserted.

 

Thank you to everyone who answered my question -- your input helped me with using maps and generally structuring my trigger so it did what I needed done.  The discussion board has helped me a lot, and is the first place I look when I encounter a new problem.  You all are awesome!

 

This was selected as the best answer