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
OleGoRulesOleGoRules 

Need help with creation of account from contact trigger

Hey guys need some help with my logic below. So essentially, a company has B2C and B2B Accounts & Contacts. To avoid person accounts for B2C contacts, i have written a trigger below to automatically create an account with recordtype 'Aministrative'. The trigger works fine, but it creates an account for all types of contacts - I need to create an 'Aministrative' Account only for Contact recordtype 'Customer'. Any other type of contacts (B2B), must lookup its Account beloew save or should create a new Account first, if the Account does not exist. 

Also, the company does a yearly load of all 'Customer' contacts - is there any governance issues with mass triggers? there could potentially 10k+ Contacts in the data load that would require auto creation of Accounts.

trigger CustomerAccountCreation on Contact (after insert) {

  RecordType arec = [SELECT ID FROM RecordType WHERE sObjectType = 'Account' AND DeveloperName = 'Administrative'];

    Map<Id, Account> aMap = new Map<Id, Account>();

    for (Contact con : trigger.new){
        if(con.AccountID == null){
            Account acc = new Account();
                acc.name = con.FirstName + ' ' + con.LastName + ' ' + 'Administrative';
                acc.RecordTypeId = arec.Id;
            aMap.put(con.Id, acc);
        }
    }

    if (!aMap.isEmpty()) {
        insert aMap.values();

        List<Contact> cList = new List<Contact>();

        for (Id cId : aMap.keySet()) {
            Contact con = new Contact();
                con.Id = cId;
                con.AccountId = aMap.get(cId).Id;
            cList.add(con);
        }

        update cList;

    }

}
Best Answer chosen by OleGoRules
Amit Singh 1Amit Singh 1
Hello,

You need to made a check whether the contact is of Customer recordtype or Not and then insert new account. Also, you need to put your trigger on Before Insert event.

I have modified the trigger and below is the code.
trigger CustomerAccountCreation on Contact (before insert) {

  RecordType arec = [SELECT ID FROM RecordType WHERE sObjectType = 'Account' AND DeveloperName = 'Administrative'];
 Id recordTypeId = [Select Id From RecordType Where sObjectType='Contact' AND DeveloperName ='Customer'].id;
    Map<Id, Account> aMap = new Map<Id, Account>();

    for (Contact con : trigger.new){
        if(con.AccountID == null){
            Account acc = new Account();
                acc.name = con.FirstName + ' ' + con.LastName + ' ' + 'Administrative';
                acc.RecordTypeId = arec.Id;
            IF(con.RecordTypeId!=null && recordTypeId==con.RecordTypeId)aMap.put(con.Id, acc);
        }
    }

    if (!aMap.isEmpty()) {
        insert aMap.values();

        //List<Contact> cList = new List<Contact>();

        for (Contact Con : Trigger.New) {
            con.AccountId = aMap.get(con.id).Id;
            
        }
        //update cList;
    }

}
Please let me know the outcomes.

Thanks,
Amit Singh

All Answers

Amit Singh 1Amit Singh 1
Hello,

You need to made a check whether the contact is of Customer recordtype or Not and then insert new account. Also, you need to put your trigger on Before Insert event.

I have modified the trigger and below is the code.
trigger CustomerAccountCreation on Contact (before insert) {

  RecordType arec = [SELECT ID FROM RecordType WHERE sObjectType = 'Account' AND DeveloperName = 'Administrative'];
 Id recordTypeId = [Select Id From RecordType Where sObjectType='Contact' AND DeveloperName ='Customer'].id;
    Map<Id, Account> aMap = new Map<Id, Account>();

    for (Contact con : trigger.new){
        if(con.AccountID == null){
            Account acc = new Account();
                acc.name = con.FirstName + ' ' + con.LastName + ' ' + 'Administrative';
                acc.RecordTypeId = arec.Id;
            IF(con.RecordTypeId!=null && recordTypeId==con.RecordTypeId)aMap.put(con.Id, acc);
        }
    }

    if (!aMap.isEmpty()) {
        insert aMap.values();

        //List<Contact> cList = new List<Contact>();

        for (Contact Con : Trigger.New) {
            con.AccountId = aMap.get(con.id).Id;
            
        }
        //update cList;
    }

}
Please let me know the outcomes.

Thanks,
Amit Singh
This was selected as the best answer
OleGoRulesOleGoRules
Thank you so much Amit - works like a charm. If I may ask, initially i had before insert, and it wasn't passing the required account lookup, so i had changed it to an after insert. For my own knowledge, can you please advise how to choose?
 
Amit Singh 1Amit Singh 1
Hi Omayer,

glad to hear that it works for you.

User Before trigger when you only need to update some values into the same object OR you need to populate values into some fields. Like in the above case you only need to populate AccountId to contacts and need to insert the account from Contact information so we simply use before trigger.

Use After trigger when you need to perform in related objects and need the Record Id of that object in which you have written the trigger.

Also, please visit the below link for more info.
https://developer.salesforce.com/forums/?id=906F0000000AafFIAS

Thanks,
Amit Singh.