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
Gaurav Sinha 27Gaurav Sinha 27 

Associate contact with account dynamically

Hi All Veterans
We have a requirement wherein we have to write a trigger on contact after update. There will be a field called IsDeleted in contacts, when that field will be selected the contact will automatically get associated with a private account. Now the challenge is we have to create the  private account dynamically. Before associating the contact we have to check if that pfivate account contains 10000 contacts if yes then create a new private account and associate that contact with the newly created private account else with the previous account, this process will continue.

Thanks in advance...:)
Best Answer chosen by Gaurav Sinha 27
Ravi Dutt SharmaRavi Dutt Sharma
I think this should work. I have not complied it, you may see some compilation errors. Thanks.
 
trigger ContactTrigger on Contact(before update){
	
	List<Account> accList = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE IsPrivate__c = true];
	// list of private accounts with less than 10k contact
	List<Account> eligibleAccounts = new List<Account>();
	// Map of account id vs count of contacts
	Map<Id, Integer> accToContactCount = new Map<Id, Integer>();
	for(Account acc: accList){
	    if(acc.Contacts.size() < 10000){
	        eligibleAccounts.add(acc);
	        accToContactCount.put(acc.Id, acc.Contacts.size());
	    }
	}
	boolean eligibleAccountExists = false;
	Account eligibleAccount;
	if(eligibleAccounts.size() > 0){
		eligibleAccountExists = true;
		eligibleAccount = eligibleAccounts[0];
	}
	for(Contact con: Trigger.new){
		// check if value of IsDeleted is changed from false to true
		if(con.IsDeleted && Trigger.oldMap.get(con.Id).IsDeleted == false) {
			if(eligibleAccountExists && accToContactCount.get(eligibleAccount.Id) < 10000){
				con.AccountId = eligibleAccount.Id;
				Integer existingContactCount = accToContactCount.get(eligibleAccount.Id);
				if(existingContactCount == null){
					existingContactCount = 0;
				}
				accToContactCount.put(eligibleAccount.Id, existingContactCount + 1);
			} else {
				Account acc = new Account(Name = 'Private Account', IsPrivate__c = true);
				insert acc;
				eligibleAccountExists = true;
				eligibleAccount = acc;
				con.AccountId = eligibleAccount.Id;
				Integer existingContactCount = accToContactCount.get(eligibleAccount.Id);
				if(existingContactCount == null){
					existingContactCount = 0;
				}
				accToContactCount.put(eligibleAccount.Id, existingContactCount + 1);
			}
		}
	}
}

 

All Answers

Ravi Dutt SharmaRavi Dutt Sharma
Can you please post the code which you have tried till now?
Gaurav Sinha 27Gaurav Sinha 27
@Ravi Dutt Sharma
I am trying something like this:
trigger CreatePrivateAccount on Contact (Before update)
{
    List<Account>PrivateAccountList=new List<Account>();
    List<Contact>RelatedContactList=new List<Contact>();
    List<Account> LatestPrivateAccount=new List<Account>();
    //List<Contact>ContactToScan=[Select Id, IsDeleted__c From Contact Where IsDeleted__c=True];
    for (Contact con : Trigger.new)
    {        
        LatestPrivateAccount=[Select Id, Name, CreatedDate from Account Where Id IN:PrivateAccountList ORDER BY CreatedDate DESC Limit 1];
        RelatedContactList=[Select Id, LastName from Contact Where AccountID IN: LatestPrivateAccount];
        if(con.IsDeleted__c == True)
        {
            for(integer i=0;i<300;i++)
            {
                Account acc=new Account();
                acc.name= 'Private Account'+i;
                if(RelatedContactList.size() <= 10000) PrivateAccountList.add(acc);              
            }            
        }        
    }
    insert PrivateAccountList;
    for(Account acc: LatestPrivateAccount)  con.AccountId= acc.Id;           
    Update con;

}

the challenge is that in for loop while creating account record we have to check if any Private account is there or not (an identifier will be there in account lets say a checkbox indicating if its a private account), if there is no private account then we have to create one and add the contact to it, if there is private account then we have to check if has its max contact limit of 10000 or not, if max limit is not achieved then we have to attach contact to that account else create new account and attach to it. Account name should be created dynamically with unique name everytime.
Ravi Dutt SharmaRavi Dutt Sharma
I think this should work. I have not complied it, you may see some compilation errors. Thanks.
 
trigger ContactTrigger on Contact(before update){
	
	List<Account> accList = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE IsPrivate__c = true];
	// list of private accounts with less than 10k contact
	List<Account> eligibleAccounts = new List<Account>();
	// Map of account id vs count of contacts
	Map<Id, Integer> accToContactCount = new Map<Id, Integer>();
	for(Account acc: accList){
	    if(acc.Contacts.size() < 10000){
	        eligibleAccounts.add(acc);
	        accToContactCount.put(acc.Id, acc.Contacts.size());
	    }
	}
	boolean eligibleAccountExists = false;
	Account eligibleAccount;
	if(eligibleAccounts.size() > 0){
		eligibleAccountExists = true;
		eligibleAccount = eligibleAccounts[0];
	}
	for(Contact con: Trigger.new){
		// check if value of IsDeleted is changed from false to true
		if(con.IsDeleted && Trigger.oldMap.get(con.Id).IsDeleted == false) {
			if(eligibleAccountExists && accToContactCount.get(eligibleAccount.Id) < 10000){
				con.AccountId = eligibleAccount.Id;
				Integer existingContactCount = accToContactCount.get(eligibleAccount.Id);
				if(existingContactCount == null){
					existingContactCount = 0;
				}
				accToContactCount.put(eligibleAccount.Id, existingContactCount + 1);
			} else {
				Account acc = new Account(Name = 'Private Account', IsPrivate__c = true);
				insert acc;
				eligibleAccountExists = true;
				eligibleAccount = acc;
				con.AccountId = eligibleAccount.Id;
				Integer existingContactCount = accToContactCount.get(eligibleAccount.Id);
				if(existingContactCount == null){
					existingContactCount = 0;
				}
				accToContactCount.put(eligibleAccount.Id, existingContactCount + 1);
			}
		}
	}
}

 
This was selected as the best answer
Gaurav Sinha 27Gaurav Sinha 27
@Ravi Dutt Sharma
thanks for your time and effort, but its not working, not changing the contact account id.
Gaurav Sinha 27Gaurav Sinha 27
@Ravi Dutt Sharma
I have made some changes as below and its working fine now. Thanks a lot for your help. :)
trigger ContactTrigger on Contact(before update){
    
    List<Account> accList = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE IsPrivate__c = true Order By CreatedDate DESC Limit 1];
    // list of private accounts with less than 10k contact
    List<Account> eligibleAccounts = new List<Account>();
    // Map of account id vs count of contacts
    Map<Id, Integer> accToContactCount = new Map<Id, Integer>();
    for(Account acc: accList){
        if(acc.Contacts.size() < 10000){
            eligibleAccounts.add(acc);
            accToContactCount.put(acc.Id, acc.Contacts.size());
        }
    }
    boolean eligibleAccountExists = false;
    Account eligibleAccount;
    if(eligibleAccounts.size() > 0){
        eligibleAccountExists = true;
        eligibleAccount = eligibleAccounts[0];
    }Else{
    Account acc = new Account(Name = 'Private Account', IsPrivate__c = true);
    insert acc;
    eligibleAccountExists = true;
    eligibleAccount = acc;
    }
    for(Contact con: Trigger.new){
        // check if value of IsDeleted is changed from false to true
        if(con.IsDeleted__c == True) {
            if(eligibleAccountExists == True && accToContactCount.get(eligibleAccount.Id) < 10000){
                con.AccountId = eligibleAccount.Id;
                //Update con;
                Integer existingContactCount = accToContactCount.get(eligibleAccount.Id);
                if(existingContactCount == null){
                    existingContactCount = 0;
                }
                accToContactCount.put(eligibleAccount.Id, existingContactCount + 1);
            } 
        }
    }
Gaurav Sinha 27Gaurav Sinha 27
@Ravi Dutt Sharma
Can you advice if below code will generate unique account name everytime its created
trigger ContactTrigger on Contact(before update)
{    
    List<Account> accList = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE IsPrivate__c = true Order By CreatedDate DESC Limit 1];
    // list of private accounts with less than 10k contact
    List<Account> eligibleAccounts = new List<Account>();
    // Map of account id & count of contacts
    Map<Id, Integer> accToContactCount = new Map<Id, Integer>();
    Integer AccountIndex=0;
    for(Account acc: accList)
    {
        if(acc.Contacts.size() < 10000)
        {
            eligibleAccounts.add(acc);
            accToContactCount.put(acc.Id, acc.Contacts.size());
        }
    }
    boolean eligibleAccountExists = false;
    Account eligibleAccount;
    if(eligibleAccounts.size() > 0)
    {
        eligibleAccountExists = true;
        eligibleAccount = eligibleAccounts[0];
    }
    Else
    {   
        Account acc = new Account(Name = 'Private Account'+AccountIndex, IsPrivate__c = true);
        insert acc;
        AccountIndex++;
        eligibleAccountExists = true;
        eligibleAccount = acc;
    }
    for(Contact con: Trigger.new)
    {        
        if(con.IsDeleted__c == True) 
        {
            if(eligibleAccountExists == True)  con.AccountId = eligibleAccount.Id;           
        }
    }
}

 
Ravi Dutt SharmaRavi Dutt Sharma
No, it wont generate a random name everytime. Instead of using accountIndex variable, use Math.random.
You can find the documentation at this link: Math.random (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_math.htm)
Gaurav Sinha 27Gaurav Sinha 27
Have added below code to generate string with random number:
List<String> availableValues = new List<String>{'Private Account'};
        Integer listSize = availableValues.size()+1;
        Integer randomNumber = Integer.valueof((Math.random() * listSize));
        //to generate random number
        Integer randomNumber1 = Integer.valueof((Math.random() * 300));       
        String randomString= availableValues[randomNumber]+randomNumber1;
        System.debug('randomString is==>'+randomString);
        Account acc = new Account(Name = randomString, IsPrivate__c = true);
        insert acc;