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
Gene T.Gene T. 

Newbie Help: Use record owner name to create new record in another object

Hi All,

 

This is my first attempt at writing an apex trigger and have zero background in coding. The purpose of the code is to create a new account when a new contact is created and is not assigned to an account. Here's what I pieced together:

 

trigger CreateIndividualAccount on Contact (before insert, before update) {
RecordType arec = [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1];
for (Contact c : trigger.new)
{
if(c.AccountID == null)
{
Account[] acc = new Account[0];
string cName = (Owner.Name);
acc.add(new Account (Name = cName, RecordTypeId = arec.Id));

insert acc;
c.AccountID = acc[0].Id;
}
}
}

 

I get the following error when I attempt to save: Error: Compile Error: Variable does not exist: Owner.Name at line 8 column 29

 

Please let me know what I am doing wrong, I'm sure it is something really simple.

 

Cheers

Best Answer chosen by Admin (Salesforce Developers) 
Starz26Starz26

Sorry, did not account for future contacts in same session or new logins...

 

This should cover it:

 

trigger CreateIndividualAccount on Contact (before insert) {


RecordType arec = [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1];
Set<ID> ownerIDS = New Set<ID>();

//Popultae set of Owner IDs for all records in the trigger
For(Contact cID :trigger.new)
    ownerIDS.add(cID.OwnerID);

//This will hold the Accounts that were created for each Unique Contact owner in the trigger records
Map<ID,Account> mConAccount = New Map<ID,Account>();


//Populate the Map with Existing accounts
For(Account a : [Select Name, OwnerID From Account Where Name = :userinfo.getName()])
  mConAccount.put(a.ownerID, a);

//This is a Map for the OPwner ID to their Names. The Owner.Name is not available in the trigger.new context so you have to query for it
Map<ID, User> mOwner = New Map<ID, User>([Select Name from User where ID IN :ownerIDs]);

    //For each record in the trigger
    for (Contact c : trigger.new){

        //If there is no related account
        if(c.AccountID == null){
            //If there is no mapping to the Contact Owner and a New Account, create it
            //Only need to create one record as each contact with the specific owner id will be associated with this new account
            if(!mConAccount.containsKey(c.OwnerID))
                mConAccount.put(c.ownerID, New Account(Name = mOwner.get(c.OwnerID).Name, RecordTypeID = arec.id));
    
}
}

//Make sure we have Account records to insert
if(mConAccount != Null)
  upsert mConAccount.values();

//Cycle through the records in the new trigger again to insert the appropriate account ids
For (Contact con : trigger.new){
    //If the Map contains the OwnerID of the current contact in this loop, Add the Account ID to the record
     if(mConAccount.containsKey(con.OwnerID))   
        con.AccountID = mConAccount.get(con.OwnerID).id;

}
}

 

All Answers

Starz26Starz26

To solve the immediate problem:

 

Should link all new contacts for the owner to the account created for that owner

 

 

***Edited, See below*****

Gene T.Gene T.

Hi Starz,

 

Thanks for helping me out. I just updated my trigger with the code that you had just provided to me. When I create a new contact, the trigger is not creating a new account or creating a relationship between the contact and account.

 

I'm a complete noob at this and am having a hard time deciphering your code and figuring out what may be wrong.

 

Any additioanal guidence would be much appreciated.

 

Starz26Starz26

Sorry about that...

 

I forgot to update the correct variables after editing the code...

 

This is tested and works:

 

trigger CreateIndividualAccount on Contact (before insert) {


RecordType arec = [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1];
Set<ID> ownerIDS = New Set<ID>();

//Popultae set of Owner IDs for all records in the trigger
For(Contact cID :trigger.new)
    ownerIDS.add(cID.OwnerID);

//This will hold the Accounts that were created for each Unique Contact owner in the trigger records
Map<ID,Account> mConAccount = New Map<ID,Account>();

//This is a Map for the OPwner ID to their Names. The Owner.Name is not available in the trigger.new context so you have to query for it
Map<ID, User> mOwner = New Map<ID, User>([Select Name from User where ID IN :ownerIDs]);

    //For each record in the trigger
    for (Contact c : trigger.new){

        //If there is no related account
        if(c.AccountID == null){
            //If there is no mapping to the Contact Owner and a New Account, create it
            //Only need to create one record as each contact with the specific owner id will be associated with this new account
            if(!mConAccount.containsKey(c.OwnerID))
                mConAccount.put(c.ownerID, New Account(Name = mOwner.get(c.OwnerID).Name, RecordTypeID = arec.id));
    
}
}

//Make sure we have Account records to insert
if(mConAccount != Null)
  insert mConAccount.values();

//Cycle through the records in the new trigger again to insert the appropriate account ids
For (Contact con : trigger.new){
    //If the Map contains the OwnerID of the current contact in this loop, Add the Account ID to the record
     if(mConAccount.containsKey(con.OwnerID))   
        con.AccountID = mConAccount.get(con.OwnerID).id;

}
}

 This will work for bulk inserts as well

Gene T.Gene T.

It worked after I removed "Abbott_Account_ID__c = '509834586'" from the code.

 

You sir are a gentleman & a scholar. I owe you a beer if we ever cross paths in IRL.

Gene T.Gene T.

Hey Starz,

 

Sorry to keep bothering you. But I've been trying to trouble shoot an issue. When the user logs out and logs back in, the trigger no longer adds the contacts to the same account, it will aad a new account for every new contact using the contact owner's name.

Starz26Starz26

Sorry, did not account for future contacts in same session or new logins...

 

This should cover it:

 

trigger CreateIndividualAccount on Contact (before insert) {


RecordType arec = [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1];
Set<ID> ownerIDS = New Set<ID>();

//Popultae set of Owner IDs for all records in the trigger
For(Contact cID :trigger.new)
    ownerIDS.add(cID.OwnerID);

//This will hold the Accounts that were created for each Unique Contact owner in the trigger records
Map<ID,Account> mConAccount = New Map<ID,Account>();


//Populate the Map with Existing accounts
For(Account a : [Select Name, OwnerID From Account Where Name = :userinfo.getName()])
  mConAccount.put(a.ownerID, a);

//This is a Map for the OPwner ID to their Names. The Owner.Name is not available in the trigger.new context so you have to query for it
Map<ID, User> mOwner = New Map<ID, User>([Select Name from User where ID IN :ownerIDs]);

    //For each record in the trigger
    for (Contact c : trigger.new){

        //If there is no related account
        if(c.AccountID == null){
            //If there is no mapping to the Contact Owner and a New Account, create it
            //Only need to create one record as each contact with the specific owner id will be associated with this new account
            if(!mConAccount.containsKey(c.OwnerID))
                mConAccount.put(c.ownerID, New Account(Name = mOwner.get(c.OwnerID).Name, RecordTypeID = arec.id));
    
}
}

//Make sure we have Account records to insert
if(mConAccount != Null)
  upsert mConAccount.values();

//Cycle through the records in the new trigger again to insert the appropriate account ids
For (Contact con : trigger.new){
    //If the Map contains the OwnerID of the current contact in this loop, Add the Account ID to the record
     if(mConAccount.containsKey(con.OwnerID))   
        con.AccountID = mConAccount.get(con.OwnerID).id;

}
}

 

This was selected as the best answer
Gene T.Gene T.

You are a Rock Star!

Gene T.Gene T.

I need to move this from our sandbox to our production and need some help.

 

I know I need to create a test class to test the code, which I have done:

 

@isTest
private class TestCreateIndividualAccount{
 static testMethod void validateIndividualAccount() {

 Contact testnewaccount = new Contact(FirstName='Test',LastName='123');
 try{
  insert testnewaccount;
 }catch(DMLException e){
 system.assert(false,'An Error occurred inserting the test record:');

 }
 //I just put in my name, as I will be the logged on user.
 Contact testcontact = [select id,Name,Account.Name from Contact where Account.Name = 'Gene T.' LIMIT 1];

 system.assert((testcontact.Account.Name=='Gene T.'),'Trigger fired successfully');
  }
}

 I'm a bit lost from there, when I package the two and try to deploy them to production, I get this error:

 

Failure Message: "System.AssertException: Assertion Failed: An Error occurred inserting the test record:", Failure Stack Trace: "Class.TestCreateIndividualAccount.validateIndividualAccount: line 11, column 1"

 

I'm guess the account names aren't matching but I may be wrong. Any advice would be helpful.

 

Gene T.Gene T.

Anyone?

Starz26Starz26

can you post the debug log?

 

 

Gene T.Gene T.
User	John Maseredjian	Date	2/17/2012 12:47:14 PM PST
Status	Assertion Failed: An Error occurred inserting the test record:	Application	Browser
Request Type	Application	Operation	/setup/build/runApexTest.apexp
Duration (ms)	836	Log Size (bytes)	8,014
Log	
24.0 APEX_CODE,FINE;APEX_PROFILING,FINE;DB,INFO;VALIDATION,INFO;WORKFLOW,FINEST
12:47:14.086 (86841000)|EXECUTION_STARTED
12:47:14.086 (86892000)|CODE_UNIT_STARTED|[EXTERNAL]|01pJ0000000CvG0|TestCreateIndividualAccount.validateIndividualAccount
12:47:14.087 (87301000)|METHOD_ENTRY|[2]|01pJ0000000CvG0|TestCreateIndividualAccount.TestCreateIndividualAccount()
12:47:14.087 (87430000)|METHOD_EXIT|[2]|TestCreateIndividualAccount
12:47:14.087 (87914000)|DML_BEGIN|[9]|Op:Insert|Type:Contact|Rows:1
12:47:14.095 (95797000)|CODE_UNIT_STARTED|[EXTERNAL]|01qJ0000000CfDU|CreateIndividualAccount2 on Contact trigger event BeforeInsert for [new]
12:47:14.096 (96393000)|SOQL_EXECUTE_BEGIN|[4]|Aggregations:0|select ID from RecordType where (SobjectType = 'Account' and Name = 'Individual') limit 1
12:47:14.099 (99584000)|SOQL_EXECUTE_END|[4]|Rows:1
12:47:14.101 (101993000)|SOQL_EXECUTE_BEGIN|[12]|Aggregations:0|select Name, OwnerID from Account 
12:47:14.103 (103711000)|SOQL_EXECUTE_END|[12]|Rows:0
12:47:14.103 (103875000)|SYSTEM_METHOD_ENTRY|[7]|QueryLocatorIterator.QueryLocatorIterator()
12:47:14.103 (103903000)|SYSTEM_METHOD_EXIT|[7]|QueryLocatorIterator
12:47:14.104 (104287000)|SOQL_EXECUTE_BEGIN|[15]|Aggregations:0|select Name from User where ID = :tmpVar1
12:47:14.106 (106714000)|SOQL_EXECUTE_END|[15]|Rows:1
12:47:14.108 (108300000)|DML_BEGIN|[26]|Op:Upsert|Type:Account|Rows:1
12:47:14.111 (111776000)|CODE_UNIT_STARTED|[EXTERNAL]|Validation:Account:new
12:47:14.111 (111792000)|VALIDATION_RULE|03dU00000009CJP|Check_CompanyId_Value
12:47:14.111 (111979000)|VALIDATION_FORMULA|AND(
	(LID__LinkedIn_Company_Id__c <> NULL),
	NOT(ISNUMBER(LID__LinkedIn_Company_Id__c))
)|LID__LinkedIn_Company_Id__c=null
12:47:14.111 (111995000)|VALIDATION_PASS
12:47:14.112 (112000000)|CODE_UNIT_FINISHED|Validation:Account:new
12:47:14.212 (212866000)|DML_END|[26]
12:47:14.137 (213324000)|CUMULATIVE_LIMIT_USAGE
12:47:14.137|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 3 out of 100
  Number of query rows: 2 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 2 out of 150
  Number of DML rows: 2 out of 10000
  Number of script statements: 11 out of 200000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 10
  Number of Email Invocations: 0 out of 10
  Number of fields describes: 0 out of 100
  Number of record type describes: 0 out of 100
  Number of child relationships describes: 0 out of 100
  Number of picklist describes: 0 out of 100
  Number of future calls: 0 out of 10

12:47:14.137|TOTAL_EMAIL_RECIPIENTS_QUEUED|0
12:47:14.137|STATIC_VARIABLE_LIST|
  double:MAX_VALUE:0
  long:serialVersionUID:0
  int:MAX_EXPONENT:0
  int:MIN_EXPONENT:0
  Boolean:TRUE:0
  long:serialVersionUID:0
  double:POSITIVE_INFINITY:0
  double:MIN_NORMAL:0
  double:MIN_VALUE:0
  Boolean:FALSE:0
  int:SIZE:0
  char[]:DigitOnes:0
  int[]:sizeTable:0
  char[]:DigitTens:0
  double:NaN:0
  int:MAX_VALUE:0
  char[]:digits:0
  long:serialVersionUID:0
  double:NEGATIVE_INFINITY:0
  int:MIN_VALUE:0
  int:SIZE:0

12:47:14.137|CUMULATIVE_LIMIT_USAGE_END

12:47:14.213 (213660000)|CODE_UNIT_FINISHED|CreateIndividualAccount2 on Contact trigger event BeforeInsert for [new]
12:47:14.215 (215685000)|ENTERING_MANAGED_PKG|rethink2
12:47:14.216 (216028000)|SOQL_EXECUTE_BEGIN|[2]|Aggregations:0|select ID from RecordType where (SobjectType = 'Account' and Name = 'Individual') limit 1
12:47:14.218 (218338000)|SOQL_EXECUTE_END|[2]|Rows:1
12:47:14.218 (218754000)|SOQL_EXECUTE_BEGIN|[3]|Aggregations:0|select rethink2__Enable_Auto_Account_Creation__c from REthink_Setup__c limit 1
12:47:14.219 (219876000)|SOQL_EXECUTE_END|[3]|Rows:0
12:47:14.221 (221292000)|DML_END|[9]
12:47:14.221 (221424000)|EXCEPTION_THROWN|[9]|System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, rethink2.CreateIndividualAccount: execution of BeforeInsert

caused by: System.QueryException: List has no rows for assignment to SObject

(rethink2): []
12:47:14.225 (225898000)|EXCEPTION_THROWN|[11]|System.AssertException: Assertion Failed: An Error occurred inserting the test record:
12:47:14.226 (226093000)|FATAL_ERROR|System.AssertException: Assertion Failed: An Error occurred inserting the test record:

Class.TestCreateIndividualAccount.validateIndividualAccount: line 11, column 1
12:47:14.226 (226200000)|FATAL_ERROR|System.AssertException: Assertion Failed: An Error occurred inserting the test record:

Class.TestCreateIndividualAccount.validateIndividualAccount: line 11, column 1
12:47:14.150 (226221000)|CUMULATIVE_LIMIT_USAGE
12:47:14.150|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 1 out of 150
  Number of DML rows: 1 out of 10000
  Number of script statements: 3 out of 200000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 10
  Number of Email Invocations: 0 out of 10
  Number of fields describes: 0 out of 100
  Number of record type describes: 0 out of 100
  Number of child relationships describes: 0 out of 100
  Number of picklist describes: 0 out of 100
  Number of future calls: 0 out of 10

12:47:14.150|TOTAL_EMAIL_RECIPIENTS_QUEUED|0
12:47:14.150|STATIC_VARIABLE_LIST|
  double:MAX_VALUE:0
  long:serialVersionUID:0
  int:MAX_EXPONENT:0
  int:MIN_EXPONENT:0
  Boolean:TRUE:0
  long:serialVersionUID:0
  double:POSITIVE_INFINITY:0
  double:MIN_NORMAL:0
  double:MIN_VALUE:0
  Boolean:FALSE:0
  int:SIZE:0
  char[]:DigitOnes:0
  int[]:sizeTable:0
  char[]:DigitTens:0
  double:NaN:0
  int:MAX_VALUE:0
  char[]:digits:0
  long:serialVersionUID:0
  double:NEGATIVE_INFINITY:0
  int:MIN_VALUE:0
  int:SIZE:0

12:47:14.150|CUMULATIVE_LIMIT_USAGE_END

12:47:14.226 (226366000)|CODE_UNIT_FINISHED|TestCreateIndividualAccount.validateIndividualAccount
12:47:14.226 (226375000)|EXECUTION_FINISHED
12:47:14.755|CUMULATIVE_PROFILING_BEGIN
12:47:14.755|CUMULATIVE_PROFILING|SOQL operations|
(rethink2): [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1]: executed 1 time in 3 ms
Trigger.CreateIndividualAccount2: line 4, column 1: [SELECT ID from RecordType WHERE SobjectType='Account' AND Name='Individual' limit 1]: executed 1 time in 3 ms
Trigger.CreateIndividualAccount2: line 15, column 1: [Select Name from User where ID IN :ownerIDs]: executed 1 time in 2 ms
(rethink2): [select Enable_Auto_Account_Creation__c from REthink_Setup__c limit 1]: executed 1 time in 1 ms

12:47:14.755|CUMULATIVE_PROFILING|No profiling information for SOSL operations
12:47:14.755|CUMULATIVE_PROFILING|DML operations|
Class.TestCreateIndividualAccount.validateIndividualAccount: line 9, column 1: Insert: SOBJECT:Contact: executed 1 time in 138 ms

12:47:14.755|CUMULATIVE_PROFILING|method invocations|
External entry point: static testMethod void validateIndividualAccount(): executed 1 time in 139 ms
External entry point: public void invoke(): executed 1 time in 118 ms
Trigger.CreateIndividualAccount2: line 26, column 1: global object values(): executed 2 times in 104 ms
Trigger.CreateIndividualAccount2: line 12, column 1: global static String getName(): executed 4 times in 2 ms
Trigger.CreateIndividualAccount2: line 7, column 1: global object iterator(): executed 4 times in 1 ms
Trigger.CreateIndividualAccount2: line 8, column 1: global Boolean add(ANY): executed 1 time in 0 ms
Trigger.CreateIndividualAccount2: line 17, column 1: global object iterator(): executed 4 times in 0 ms
Trigger.CreateIndividualAccount2: line 19, column 1: global Boolean containsKey(ANY): executed 1 time in 0 ms
Trigger.CreateIndividualAccount2: line 20, column 1: global object get(ANY): executed 2 times in 0 ms
Trigger.CreateIndividualAccount2: line 29, column 1: global Boolean containsKey(ANY): executed 1 time in 0 ms
Trigger.CreateIndividualAccount2: line 28, column 1: global object iterator(): executed 4 times in 0 ms

12:47:14.755|CUMULATIVE_PROFILING_END

 

Starz26Starz26

Your issue is with the managed package rethink....

 

12:47:14.215 (215685000)|ENTERING_MANAGED_PKG|rethink2
12:47:14.216 (216028000)|SOQL_EXECUTE_BEGIN|[2]|Aggregations:0|select ID from RecordType where (SobjectType = 'Account' and Name = 'Individual') limit 1
12:47:14.218 (218338000)|SOQL_EXECUTE_END|[2]|Rows:1
12:47:14.218 (218754000)|SOQL_EXECUTE_BEGIN|[3]|Aggregations:0|select rethink2__Enable_Auto_Account_Creation__c from REthink_Setup__c limit 1
12:47:14.219 (219876000)|SOQL_EXECUTE_END|[3]|Rows:0
12:47:14.221 (221292000)|DML_END|[9]
12:47:14.221 (221424000)|EXCEPTION_THROWN|[9]|System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, rethink2.CreateIndividualAccount: execution of BeforeInsert

caused by: System.QueryException: List has no rows for assignment to SObject

(rethink2): []
12:47:14.225 (225898000)|EXCEPTION_THROWN|[11]|System.AssertException: Assertion Failed: An Error occurred inserting the test record:
12:47:14.226 (226093000)|FATAL_ERROR|System.AssertException: Assertion Failed: An Error occurred inserting the test record:

Class.TestCreateIndividualAccount.validateIndividualAccount: line 11, column 1
12:47:14.226 (226200000)|FATAL_ERROR|System.AssertException: Assertion Failed: An Error occurred inserting the test record:

 

Not sure what it is doing but the query it is trying to do returns no rows and the way the wrote the query does not handle that sceniero....

 

 

 

 

ENTERING_MANAGED_PKG|rethink2
12:47:14.216 (216028000)|SOQL_EXECUTE_BEGIN|[2]|Aggregations:0|select ID from RecordType where (SobjectType = 'Account' and Name = 'Individual') limit 1
12:47:14.218 (218338000)|SOQL_EXECUTE_END|[2]|Rows:1
12:47:14.218 (218754000)|SOQL_EXECUTE_BEGIN|[3]|Aggregations:0|select rethink2__Enable_Auto_Account_Creation__c from REthink_Setup__c limit 1
Gene T.Gene T.

Thanks, I just saw that as well. So there is no way I can push this to production with out uninstalling the managed package?

 

Starz26Starz26

You will have to find out exactly what that managed package needs in order to run with that test record.

 

The issue will be, even if you uninstall it, you will not be able to use the trigger AND that package after you push it to production......

 

Once you find out what the packages needs / does, and code for that you will be fine