+ Start a Discussion
NikiVNikiV 

Test Method for trigger that updates a Person Account not working

Hello,

 

I've written a trigger on a custom object that updates a picklist field on a Contact record, and I have Person Accounts enabled.  The trigger works, updating the Contact only under the right circumstances.  I'm now trying to write a test method to move this into Prod and am having trouble updating a Contact record in the method.   Before the trigger is even fired I'm trying to set up my Contacts with the right information. 

 

Here is what my test method looks like so far, just setting up the initial Person Account contact:

 

// create person account by filling in the Account's lastname field.
Account a1 = new Account();
a1.lastname = 'Test1';
insert a1;
// now pull up Contact to set the value of my picklist field
Contact c1;
c1 = [select id, courses_completed__c from Contact where accountid = :a1.id];
c1.courses_completed__c = 'POE';
update c1;

 

At this point my method throws up a DML error on the update:

 

System.DmlException: Update failed. First exception on row 0 with id 003S0000002u36xIAA; first error: INVALID_CROSS_REFERENCE_KEY, Can not select a contact: [AccountId]

 

Any ideas on how to update a Person Account's contact fields in the test method?  I don't think I can update the contact field on my Account object - it comes up as invalid field when I access a1.courses_completed__c or a1.personcourses_completed__c.

 

Any thoughts would be much appreciated.  The API docs say you can't create or delete a Person Account type Contact but I should be able to update it.  The fact that my trigger works when I test it out in the UI points to an issue with the test method rather than my trigger coding.

 

Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
Vijay RautVijay Raut

Micwa,

 

Once person accounts are enabled on your org, Account object would have LastName and FirstName field (only for Person Account) like contacts.

 

Hi Niki,

 

As you mentioned, we cannot create, delete person account - contact. Also you cannot directly update contact which is related to person account. Rather your code needs some tweaking as follows.

 

 

// create person account by filling in the Account's lastname field.
Account a1 = new Account();
a1.lastname = 'Test1';
a1.RecordTypeId = PERSON_ACCOUNT_RECORD_TYPE_ID;
insert a1;

// now update Person Account Contact to set the value of my picklist field

a1.courses_completed__pc = 'POE';
update a1;

 

As you see in the code, you can refer Contact custom fields in Person Account using "__pc". Also i suggest to set RecordTypeId as Person Account Record Type Id on your org in the code (so please replace PERSON_ACCOUNT_RECORD_TYPE_ID with actual record type id.

 

Hope this would help.

 

Cheers,

V.R.

 

Message Edited by Vijay Raut on 01-29-2009 08:16 AM

All Answers

micwamicwa

Your code has a couple of mistakes:

 

Line 3: There's no Field Lastname on Account

Line 7: Are you sure that excactly one contact exists? otherwise use a list or use "Limit 1" keyword in the SOQL query.

 

will this work:

 

// create person account by filling in the Account's lastname field. Account a1 = new Account(); a1.Name= 'Test1'; insert a1; // now pull up Contact to set the value of my picklist field List<Contact> cList = [select id, courses_completed__c from Contact where accountid = :a1.id]; if(!cList.isEmpty()){ Contact c1 = cList[0]; c1.courses_completed__c = 'POE'; update c1; }

 

 

 

Vijay RautVijay Raut

Micwa,

 

Once person accounts are enabled on your org, Account object would have LastName and FirstName field (only for Person Account) like contacts.

 

Hi Niki,

 

As you mentioned, we cannot create, delete person account - contact. Also you cannot directly update contact which is related to person account. Rather your code needs some tweaking as follows.

 

 

// create person account by filling in the Account's lastname field.
Account a1 = new Account();
a1.lastname = 'Test1';
a1.RecordTypeId = PERSON_ACCOUNT_RECORD_TYPE_ID;
insert a1;

// now update Person Account Contact to set the value of my picklist field

a1.courses_completed__pc = 'POE';
update a1;

 

As you see in the code, you can refer Contact custom fields in Person Account using "__pc". Also i suggest to set RecordTypeId as Person Account Record Type Id on your org in the code (so please replace PERSON_ACCOUNT_RECORD_TYPE_ID with actual record type id.

 

Hope this would help.

 

Cheers,

V.R.

 

Message Edited by Vijay Raut on 01-29-2009 08:16 AM
This was selected as the best answer
NikiVNikiV

Thank you Vijay for the tip about the contact fields showing up in the Account table with the __pc suffix.  I didn't see that anywhere in the API docs or other help files I have scoured and am very relieved to find a solution.

 

One thing about the recordtypeid - by setting the new Account's lastname field instead of the name field, the Account record automatically knows it is a Person Account and will pick my default Person Account Record Type.  In my case I only have one so I don't need to specifically set it, but it is a good point to remember.

 

I find it odd that my previous version of the trigger that directly updated Contact fields worked through the UI, however the test case created dml errors.  Once I converted the trigger over to update the Account __pc fields, the UI still worked AND so did my test cases.  That makes me wonder if any of the AppExchange packages or other pre-built Contact related code will also bomb when I'm ready to begin plugging things in.  Any thoughts on that?

 

Thanks again!

Ron WildRon Wild

I've did a couple of tests on this and found that if you retrieve a person account as a Contact (e.g. with a "Select ... from Contact")

 you CAN update the fields defined as Contact fields (mailingaddress, email, even custom fields) through the API using the Contact Id.

 

However, if I attempt to do that in Apex code  I get the INVALID_CROSS_REFERENCE_KEY error you described above. 

Is this a bug?  I don't know. But I would think packaged apps would be breaking left and right in accounts with Person Accounts turned on if this the case.  Mine are - and I have to build in work-arounds, or disable features if I detect that the code is running in a Person Account enabled instance.

 

 

 

 

Message Edited by Ron Wild on 08-09-2009 09:33 PM