4

I have a method below which is supposed to be called from an unauthenticated Sites page (via https). It is intended to take some personal details and create a Person Account with them and then activate that record for use on the customer portal.

However when I run this method I find that the return value of the Site.createPersonAccountPortalUser method is null and the person account is not created.

I have been trying to follow the instructions from the Site Class documentation without success.

I have set up a force.com site, associated it to a customer portal, enabled the profile and defined a default user profile and licence to be high-volume portal user.

public static String createPersonAccountPortalUser(String FirstName, String LastName, String Email, String Phone, Map<String, String> mResponseMap){
    ID userId;
    User u = new User();

    //Name and email are required.
    if(FirstName != null && FirstName != '' && LastName != null && LastName != ''){
        if(Email != null && Email != ''){
            u.FirstName =FirstName;
            u.LastName =LastName;
            u.Username = Email;
            u.Email = Email;
            u.Phone = Phone;
            u.CommunityNickname = LastName;             
            system.debug('## createPersonAccountPortalUser: user =' + u);
            system.debug('## createPersonAccountPortalUser: PortalOwnerId = ' + PortalOwnerId);
            String strRecTypeId = queryForPersonRecType();
            try{
                userId = Site.createPersonAccountPortalUser(u, PortalOwnerId, 'testpassword');
                system.debug('## createPersonAccountPortalUser: userId = ' + userId);
                mResponseMap.put(KeyId, userId);
                UtilityMap.appendValue(KeyStatus, SuccessNewPersonAccount, mResponseMap);
                return userId;                                      
            }catch(Exception e){
                UtilityMap.appendValue(KeyError, FailureNewPersonAccount, mResponseMap);
                mResponseMap.put(KeyErrorMessage, EncodingUtil.urlEncode(e.getMessage(), 'UTF-8'));
                return null;
            }                               
        }else{UtilityMap.appendValue(KeyError, EmailErr, mResponseMap);}            
    }else{UtilityMap.appendValue(KeyError, NamesRequired, mResponseMap);}
    return userId;      
}

I have also tried running the following code as anonymous apex in the developer console and I still get a null returned.


User u = new User();
u.FirstName ='FirstName';
u.LastName ='LastName';
u.Username = 'testuser';
u.Email = 'testuser@magardner.co.uk';
u.Phone = 'Phone';
u.CommunityNickname = 'LastName';
String userId = Site.createPersonAccountPortalUser(u, Label.B2C_Portal_Person_Account_Owner_Id, 'testpass');
system.debug('user Id = ' + userId);

What am I doing wrong?

For reference here is my visualforce page

<apex:page showHeader="false" sidebar="false" controller="ServiceRegistrationController" action="{!createRegistration}" contentType="application/json">
<apex:outputText value="{!response}" escape="false"/>

  • How are you getting PortalOwnerId? Are you able to manually create a portal user with that owner? – metadaddy Oct 9 '12 at 14:54
  • I'm defining that as a hard coded value from a custom label so it can be changed in-life. – Born2BeMild Oct 9 '12 at 14:56
  • Have you confirmed that you are able to manually create a portal user with that owner? – metadaddy Oct 9 '12 at 15:01
  • Yes I have just tested that and it works OK through the salesforce UI. – Born2BeMild Oct 9 '12 at 15:06
  • I'm stumped - I'll ask the gurus in the Portal team... – metadaddy Oct 9 '12 at 21:50
3

I found some further information here: Provisioning Customer Portal Users with Apex

This post suggests that the problem is that you cannot create a contact and a user record in the same APEX transaction. Doing so is called mixed DML and is not allowed. Therefore if you must create a contact and user at the same time the only way to do so is for one of them to be created asynchronously via a method marked with the @future annotation.

This is the method I have used.


    //Async method, using @future, to create the User record and associate it to the previously created Contact
    //This uses @future because you can not have mixed DML operations for standard objects (Account, Contact) and Setup objects(User)
    @future public static void createUser(String contactId, String email, String firstName, String lastName, String userName, String profileId) {
        Database.DMLOptions dmo = new Database.DMLOptions();
        dmo.EmailHeader.triggerUserEmail = true;
        //take the first few characters of the username for the alias
        String alias = userName.substring(0, 7);
        User u = new User(alias = alias, email=email, 
            emailencodingkey=EmailEncoding, lastname=lastname, languagelocalekey=LanguageLocaleKey, 
            localesidkey=LocaleSidKey, profileid = profileId, contactId=contactId,
            timezonesidkey=TimeZoneSidKey, username=username);

        u.setOptions(dmo);
        insert u;
    }

This appears to be working better than my previous attempt. The error messages now show up in the Apex Jobs page (Administration Setup > Monitoring > Apex Jobs) which makes it easier to debug than the silence that the first attempt gave.

  • So are you not using the createPersonAccountPortalUser method at all now? – Phil B Dec 13 '12 at 19:53
  • No I gave up on that method. – Born2BeMild Dec 20 '12 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.