+ Start a Discussion
sumit dsumit d 

Trigger on Account to insert contact and checkbox field to true

Hi All,
i have a field on Account called “Only_Default_Contact”, checkbox, default off
 
When a new Account is created, create a new Contact that has the following data points:
First Name = “Info”
Last Name = “Default”
Email = “info@websitedomain.tld”
and set Account Field Only_Default_Contact = TRUE

When the Account has more than 1 Contact, update Account field  Only_Default_Contact to FALSE.
public class TriggerAccountHelper {
    public static List<Account> newAccount = new List<Account>();
    public static List<Account> oldAccount = new List<Account>();
    public static Map<Id, Account> newMapAccount = new Map<Id, Account>();
    public static Map<Id, Account> oldMapAccount = new Map<Id, Account>();
  

    public static void CreatContact(){
         List<Contact> contactToInsert = new List<Contact>();
        for(Account acc : newAccount){
            Contact con = new Contact(LastName = 'test30',
                                      AccountId=acc.id
                                     );
            contactToInsert.add(con);
            if(contactToInsert.size() == 0){
                acc.OnlyDefaultContact__c = True;
            }
            else{
                acc.OnlyDefaultContact__c = False;
            }
        }
        
        if(!contactToInsert.isEmpty()){ 
            insert contactToInsert; 
         }
    
     }
}
i am executing the trigger on After insert.
its showing me this error:-Trigger_Account: execution of AfterInsert caused by: System.FinalException: Record is read-only Class.TriggerAccountHelper.CreatContact: line 19, column 1 Trigger.Trigger_Account: line 12, column 1
Khan AnasKhan Anas (Salesforce Developers) 
Hi Sumit,

Greetings to you!

This is because you are in an after insert trigger and the records are read-only in that context as they have been written, but not committed, to the database.

This kind of error occurs if you try to update lists/record which are/is read-only in the trigger execution. For example, trigger.new and trigger.old are both read-only lists and cannot be applied with a DML operation.

Your trigger is relying on the ids of the records, which means you won't be able to use before insert as the ids won't be populated at that time (as the records haven't been written to the database at that point so while you can write to them, database generated fields aren't populated).
In this instance you'll need to clone the record (or query anew via SOQL) and make changes to the new copy of the record, then execute the update against the new copies.

Reference: 
https://salesforce.stackexchange.com/questions/23922/system-finalexception-record-is-read-only-trigger-updatecompetitors-line-24

http://sfdcsrini.blogspot.com/2014/09/what-is-record-is-read-only-trigger.html

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Prabhat Gangwar007Prabhat Gangwar007
what it Mean - Account has more than 1 Contact, update Account field  Only_Default_Contact to FALSE.  

see on the creation of Account you want to create one contact By default and after second contact creation by manually then the checkbox will false of account Right?
 
sumit dsumit d
Hi Prabhat ,
                   you are right.
Can you tell me how to it?
 
Jolly_BirdiJolly_Birdi
Hello Sumit,

Please try this below Code:
Add these two triggers:
 
trigger AccountTrigger on Account (after insert) {
    if(trigger.isafter && trigger.isinsert) {
		ContactNameUpdate.newContactCreated(Trigger.new);
    }
}
 
trigger ContactTrigger on Contact (after insert) {
    if(trigger.isafter && trigger.isinsert) {
		ContactNameUpdate.updateCheckboxOnAccount(Trigger.new);
    }
}
 
public class ContactNameUpdate {
	// Method to handle the contact inserts.
	public static void newContactCreated(List<Account> accList){
		List<Contact> conList = new List<Contact>();
		for(Account acc : accList) {
			  Contact con = new Contact(AccountId = acc.Id);
			  List<String> nameStr = acc.Name.split(' ');
			  if(nameStr.size()>0)
				 con.LastName = nameStr[0];
			  if(nameStr.size()>1)
				  con.FirstName = nameStr[1];
				  
			con.Email = 'info@websitedomain.tld';
			con.Only_Default_Contact__c = TRUE;
			conList.add(con);
		}
		insert conList;		
	}
	public static void updateCheckboxOnAccount(List<Contact> contactList){
		Set<Id> accountIds = new Set<Id>();
		for(Contact con : contactList) {
			 accountIds.add(con.AccountId);
		}
		
		List<Account> updatedAccounts = new List<Account>();
		for(AggregateResult ar : [select count(id) , AccountId from Contact where AccountId IN :accountIds group by AccountId having count(id)  >1 ]){
			updatedAccounts.add(new Account(Id = (Id)ar.get('AccountId'), Only_Default_Contact__c=false));    
		}
		
		if(!updatedAccounts.isEmpty())
			update updatedAccounts;
	}
}

Please like and mark this as best answer if you find it positive.

Thanks
Jolly Birdi
Akash KainturaAkash Kaintura
It is not working