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
toddmcgrathtoddmcgrath 

create new Person Account via API

Hello,

 

I'd like to create a new Person Account via API.  I have Person Account enabled.  Ideally, I want to create a Person Account in one shot, but I don't think it's possible?  I need to create an Account and 1 associated Contact and then convert the account to a Person Account type?  

 

 

void testCreateAndDestroyStudentAccount() { def first = "APIFirst" def last = "APILast" // create new, non-person Account first Account acct = new Account() acct.name = "${last}" def organizationaccount = getRecordTypes().find { it.name =='Educational Organization' } acct.recordTypeId = organizationaccount.id acct.ownerId = salesforce_owner_id acct.gender__pc = '' acct.languages__pc = '' acct.firstName = '' acct.lastName = '' acct.salutation = '' acct.level__pc = '' SaveResult[] result = salesForceService.createObjects(acct) result.each { it.errors.each { com.sforce.soap.partner.Error er -> println "ERROR: ${er.getMessage()}" } assertTrue("should have created account", it.success) println "Account ID: ${it.id}" acct.id = it.id } println "creating contact..." Contact contact = new Contact() contact.setFirstName(first) contact.setLastName(last) contact.accountId = acct.id contact.recordTypeId = '' contact.ownerId = salesforce_owner_id result = salesForceService.createObjects(contact) result.each { it.errors.each { com.sforce.soap.partner.Error er -> println "Create contact ERROR: ${er.getMessage()}" } assertTrue("should have created contact", it.success) println "CONTACT ID: ${it.id}" contact.id = it.id } def studentaccount = getRecordTypes().find { it.name =='Student Account' } acct.recordTypeId = studentaccount.id result = salesForceService.updateObjects(acct) result.each { it.errors.each { com.sforce.soap.partner.Error er -> println "Update Account ERROR: ${er.getMessage()}" } fail("should have converted to Person Account") } }

 

Code creates an Account and Contact fine, but fails at the update when attempting to convert to a Person Account (at the end) with message:

 

Cannot specify any additional fields when marrying or separating a Person-Account

 

 

 

Ideas?  Thoughts? Suggestions?

 

I appreciate any insight

 

Todd

SuperfellSuperfell
You can create a person account in one shot by creating an account record with a person account recordType specified.
toddmcgrathtoddmcgrath

Thanks so much for reply.  I have been trying to create in one shot; e.g.

 

void testCreateAndDestroyStudentAccount2() { println "creating account" Account acct = new Account() // acct.name = "${last}, ${first}" def studentaccount = getRecordTypes().find { it.name =='Student Account' } acct.recordTypeId = studentaccount.id acct.ownerId = salesforce_owner_id //acct.isPersonAccount = true acct.gender__pc = '' acct.languages__pc = '' acct.firstName = "StudentAPIFirst" acct.lastName = "StudentAPILast" acct.salutation = '' acct.level__pc = '' SaveResult[] result = salesForceService.createObjects(acct) result.each { it.errors.each { com.sforce.soap.partner.Error er -> println "ERROR: ${er.getMessage()}" } assertTrue("should have created person account", it.success) println "Account ID: ${it.id}" acct.id = it.id } DeleteResult[] delresult = salesForceService.delete(acct.id) delresult.each { DeleteResult del -> del.errors.each { com.sforce.soap.partner.Error er -> println "ERROR: ${er.getMessage()}" } assertTrue("should have deleted student account", del.success) } }

 

But always error:

bad field names on insert/update call: Name

 

 

happens regardless of whether acct.Name is set or not; example of above does to set Name.

 

any ideas?

 

 

toddmcgrathtoddmcgrath

Well, I don't get it, but here's the fix

 

void testCreateAndDestroyStudentAccount2() { println "creating account" Account acct = new Account() acct.name = "" def studentaccount = getRecordTypes().find { it.name =='Student Account' } acct.recordTypeId = studentaccount.id acct.ownerId = salesforce_owner_id acct.gender__pc = '' acct.languages__pc = '' acct.firstName = "StudentAPIFirst" acct.lastName = "StudentAPILast" acct.salutation = '' acct.level__pc = '' SaveResult[] result = salesForceService.createObjects(acct) result.each { it.errors.each { com.sforce.soap.partner.Error er -> println "ERROR: ${er.getMessage()}" } assertTrue("should have created person account", it.success) println "Account ID: ${it.id}" acct.id = it.id } DeleteResult[] delresult = salesForceService.delete(acct.id) delresult.each { DeleteResult del -> del.errors.each { com.sforce.soap.partner.Error er -> println "ERROR: ${er.getMessage()}" } assertTrue("should have deleted student account", del.success) } }

 

 Setting name to "" did it.

 

SuperfellSuperfell
for person accounts the name field is a read-only view of firstname lastname, so right, you shouldn't be trying to set it, you should set firstname & lastname instead.
JDevJDev
I believe the problem is that on a personAccount insert from a Visualforce Controller extension the isPersonAccount field (which is not writeable) is not yet set in the Visualforce viewstate, so the Account.FirstName and Account.LastName fields are not enterable. Once the record is saved (and the system sets the isPersonAccount field based on RecordTypeId) the Account.FirstName and Account.LastName fields fields are available for edit in Visualforce.

If you use custom text input fields on the new account page and then set the Account.FirstName Account.LastName fields in the controller to the values of your custom fields you should be fine. Also if you want to take advantage of Visualforce input fields, just use a contact in the controller (to provide input fields for the first and last names) and map the entered data to the Account.FirstName and Account.LastName fields in the controller when you save (don't save the Contact.)

The problem is that unlike other standard account fields which are prefixed by person (such as PersonMailingCity ) or custom account fields identified as customfield__pc the Account.LastName and Account.FirstName on a person account are not distinguished from the contact equivalents Contact.FirstName and Contact.LastName, which looks like a bug, but as it has been around so long I think it counts as a feature now......
jhartjhart

Going back to the original posting and the difficulties surrounding "marrying" an regular Account and its sole Contact into a Person Account in the same transaction that creates both objects.

 

The (nonobvious) solution here is that, when you change the RecordType of the Account, you need to be operating on an Account object that has nothing but its Id defined.

 

In other words, this does NOT work:

 

 

Account a = new Account(Name = 'Test PAConv');
insert a;

Contact c = new Contact(LastName = 'PAConv', AccountId = a.Id);
insert c;

a.RecordTypeId = PA.getRecordTypes()[0].Id;
update a;

 

It fails with "INVALID_FIELD_FOR_INSERT_UPDATE, Cannot specify any additional fields when marrying or separating a Person-Account []"

 

 

However, re-fetching the "a" record with only its Id lets the whole thing work:

 

 

Account a = new Account(Name = 'Test PAConv');
insert a;

Contact c = new Contact(LastName = 'PAConv', AccountId = a.Id);
insert c;

// re-fetch a before updating RecordType
a = [select Id from Account where Id = :a.Id];

a.RecordTypeId = PA.getRecordTypes()[0].Id;
update a;

 

 

Mats ErikssonMats Eriksson

If you want to create a PersonAccount, it would probably be best not to bother with the contact at all.

 

The trick is to set a PersonAccount recordtypeId when you save it. I called it "Person Account" below.

 

Like this (a snippet from a web-to-case solution):

String RecTypeId= [select Id from RecordType where (Name='Person Account') and (SobjectType='Account')].Id;

Account Accnt = new Account(
  RecordTypeID=RecTypeId,
  FirstName=caseObj.FName__c,
  LastName=caseObj.LName__c,
  PersonMailingStreet=caseObj.StreetAddress__c,
  PersonMailingPostalCode=caseObj.ZipCode__c,
  PersonMailingCity=caseObj.City__c,
  PersonEmail=caseObj.eMail_address__c,
  PersonHomePhone=caseObj.PhoneNumber__c,
  PersonMobilePhone=caseObj.PhoneNumberInsuredPhone__c,
  SSNumber__c=caseObj.SSNumber__c,
  IsAutoCreated__c=true);

insert newAccount;

 

Cheers /Mats

Unique TwoUnique Two
Hello there,

I am only a Certified Salesforce Administrator but I require some guidance on the following.

We are setting up an Enterprise WSDL API

Once syncronised by way of the external data being updated with current record Id's I'd like it so that we can write a trigger to create a Person Account if the Account ID is blank.

Thoughts?