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
hanifa fatimahanifa fatima 

How To delete the related contact based on updation of a particular field using trigger

trigger CreationOfContact on Account (after insert,after Update) {
Map<Id,Decimal> mp=new Map<Id,Decimal>();
list<Contact> lst=new List<Contact>();
  for(Account a:Trigger.New)
  { 
   mp.put(a.id,a.Number_Of_Contacts__c);
  }
   if(Trigger.isInsert && Trigger.isAfter)
   {
    if(mp.size()>0 && mp!=null)
    {
     for(Id a:mp.keyset())
     {
      for(Integer i=1;i<=mp.get(a);i++)
      {
        Contact c=new Contact();
        c.lastname='Test'+i;
        c.accountid=a;
        lst.add(c);
      }
     }
    }
   }
   insert lst;
   if(Trigger.isUpdate && Trigger.isAfter)
   {
    
   for(Account a:Trigger.new)
   {
    Decimal a1=trigger.oldmap.get(a.id).Number_Of_Contacts__c;
    Decimal a2=trigger.newMap.get(a.id).Number_Of_Contacts__c;
    Decimal a3=0;
    if(a2>a1)
    {
      a3=a2-a1;
      for(Integer i=1;i<=a3;i++)
      {
        Contact c=new Contact();
        c.lastname='Update' +i;
        c.AccountId=a.id;
        lst.add(c);
      }
     }    
    }
      insert lst;
   }
   
}


In this trigger i have created a custom field called no.of.contacts on account object, i've the following scenario:
1. When a new account is created and the that field is populated with (say 2) it should create 2 new contacts.

2. When i edit the that field ( say to 5 now before it was 2 ) so the difference of both is now 3, so it should 3 more contacts.

3. when i edit that field to (say to 4 now earlier the new updated value is 5) so the difference is 1 here , therefore 1contact should be deleted.


So, the code i've written works well upto 2nd scenario, the only problem i;m facing now is at 3rd scenario.

Could someone help me out?

Best Answer chosen by hanifa fatima
Steven NsubugaSteven Nsubuga
Try this Hanifa.
trigger CreationOfContact on Account (after insert,after Update) {
Map<Id,Decimal> mp=new Map<Id,Decimal>();
Map<Id,Decimal> mp2=new Map<Id,Decimal>();
list<Contact> lst=new List<Contact>();
list<Contact> toAdd=new List<Contact>();
list<Contact> toDelete=new List<Contact>();

  for(Account a:Trigger.New)
  { 
   mp.put(a.id,a.Number_Of_Contacts__c);
  }
   if(Trigger.isInsert && Trigger.isAfter)
   {
    if(mp.size()>0 && mp!=null)
    {
     for(Id a:mp.keyset())
     {
      for(Integer i=1;i<=mp.get(a);i++)
      {
        Contact c=new Contact();
        c.lastname='Test'+i;
        c.accountid=a;
        lst.add(c);
      }
     }
    }
   }
   insert lst;
   if(Trigger.isUpdate && Trigger.isAfter)
   {
    list<Contact> contactList = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :Trigger.newMap.keyset()];
	Map<Id, List<Contact>> acctContacts = new Map<Id, List<Contact>>();
	for (Contact ct : contactList) {
		List<Contact> contacts = acctContacts.get(ct.AccountId);
        if (contacts == null) {
			contacts = new List<Contact>();
		}
		contacts.add(ct);
		
		acctContacts.put(ct.AccountId, contacts);
    }
	
   for(Account a:Trigger.new)
   {
    Decimal a1=trigger.oldmap.get(a.id).Number_Of_Contacts__c;
    Decimal a2=trigger.newMap.get(a.id).Number_Of_Contacts__c;
    Decimal a3=0;
    if(a2>a1)
    {
      a3=a2-a1;
      for(Integer i=1;i<=a3;i++)
      {
        Contact c=new Contact();
        c.lastname='Update' +i;
        c.AccountId=a.id;
        toAdd.add(c);
      }
     }
    if(a2<a1) {
		a3=a1-a2;
		List<Contact> aContacts = acctContacts.get(a.Id);
		for(Integer i=1;i<=a3;i++)
		{
			toDelete.add(aContacts.remove(0))
			
        }
	}
    }
      insert toAdd;
	  delete toDelete;
   }
   
}

 

All Answers

Steven NsubugaSteven Nsubuga
Try this Hanifa.
trigger CreationOfContact on Account (after insert,after Update) {
Map<Id,Decimal> mp=new Map<Id,Decimal>();
Map<Id,Decimal> mp2=new Map<Id,Decimal>();
list<Contact> lst=new List<Contact>();
list<Contact> toAdd=new List<Contact>();
list<Contact> toDelete=new List<Contact>();

  for(Account a:Trigger.New)
  { 
   mp.put(a.id,a.Number_Of_Contacts__c);
  }
   if(Trigger.isInsert && Trigger.isAfter)
   {
    if(mp.size()>0 && mp!=null)
    {
     for(Id a:mp.keyset())
     {
      for(Integer i=1;i<=mp.get(a);i++)
      {
        Contact c=new Contact();
        c.lastname='Test'+i;
        c.accountid=a;
        lst.add(c);
      }
     }
    }
   }
   insert lst;
   if(Trigger.isUpdate && Trigger.isAfter)
   {
    list<Contact> contactList = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :Trigger.newMap.keyset()];
	Map<Id, List<Contact>> acctContacts = new Map<Id, List<Contact>>();
	for (Contact ct : contactList) {
		List<Contact> contacts = acctContacts.get(ct.AccountId);
        if (contacts == null) {
			contacts = new List<Contact>();
		}
		contacts.add(ct);
		
		acctContacts.put(ct.AccountId, contacts);
    }
	
   for(Account a:Trigger.new)
   {
    Decimal a1=trigger.oldmap.get(a.id).Number_Of_Contacts__c;
    Decimal a2=trigger.newMap.get(a.id).Number_Of_Contacts__c;
    Decimal a3=0;
    if(a2>a1)
    {
      a3=a2-a1;
      for(Integer i=1;i<=a3;i++)
      {
        Contact c=new Contact();
        c.lastname='Update' +i;
        c.AccountId=a.id;
        toAdd.add(c);
      }
     }
    if(a2<a1) {
		a3=a1-a2;
		List<Contact> aContacts = acctContacts.get(a.Id);
		for(Integer i=1;i<=a3;i++)
		{
			toDelete.add(aContacts.remove(0))
			
        }
	}
    }
      insert toAdd;
	  delete toDelete;
   }
   
}

 
This was selected as the best answer
hanifa fatimahanifa fatima

It works perfectly fine but could you please explain me why have you used, 

 

  Map<Id, List<Contact>> acctContacts = new Map<Id, List<Contact>>();

I'm just not able to understand that logic.

Thanks

Steven NsubugaSteven Nsubuga
I used Map<Id, List<Contact>> acctContacts = new Map<Id, List<Contact>>() to create a map with AccountId as the key, and a list of Accounts. Basically contacts listed by account. I would then be able to easily locate and delete contacts per Account.
Akshay_DhimanAkshay_Dhiman
Hi Hanifa,

Just try This Below code, Hope it works for you
 
​
trigger CreationOfContact on Account (after insert,after Update) {
    Map<Id,List<Contact>> mapAccVsCon = new Map<Id,List<Contact>>();
    Map<Id,Decimal> mpNew=new Map<Id,Decimal>();
    Map<Id,Decimal> mpOld=new Map<Id,Decimal>();
    List<Contact> conList = new List<Contact>();
    List<Contact> conListToInsert = new List<Contact>();
    List<Contact> conListToDelete = new List<Contact>();
    Set<Id> accIsSet = new  Set<Id>();
    Decimal NumOfContactsToDelete = 0;
    Decimal NumOfContactsToAdd = 0;
    if(trigger.isUpdate && trigger.isAfter)
    {
        for(Account acc : trigger.New)
        {
            if(acc.Number_Of_Contacts__c!=Null)
            {
                accIsSet.add(acc.Id);
                
                mpNew.put(acc.Id , trigger.newMap.get(acc.id).Number_Of_Contacts__c);
                mpOld.put(acc.Id , trigger.oldmap.get(acc.id).Number_Of_Contacts__c);
            }
            
        }
        conList = [Select Id,Name , AccountId from Contact where AccountId IN : accIsSet];
        
        System.debug('conList--->>>>' + conList);
        for(Contact con : conList)
        {
            if(!mapAccVsCon.containsKey(con.AccountId))
            {
                mapAccVsCon.put(con.AccountId, new List<Contact>());
            }
            mapAccVsCon.get(con.AccountId).add(con);
        }
        System.debug('mapAccVsCon--->>>>' + mapAccVsCon);
        for(Account accLoop : trigger.New)
        {
            if(mpNew.get(accLoop.Id) < mpOld.get(accLoop.Id))
            {
                NumOfContactsToDelete = mpOld.get(accLoop.Id) - mpNew.get(accLoop.Id);
                List<Contact> ContactsVal = mapAccVsCon.get(accLoop.Id);
                for(Integer i=1 ; i <= NumOfContactsToDelete ; i++)
                {
                    conListToDelete.add(ContactsVal.remove(i));
                }
            }
            
            if(mpNew.get(accLoop.Id) > mpOld.get(accLoop.Id))
            {
                NumOfContactsToAdd = mpNew.get(accLoop.Id) - mpOld.get(accLoop.Id);
                for(Integer i=1 ; i<= NumOfContactsToAdd ; i++)
                {
                    Contact c=new Contact();
                    c.lastname='Test'+i;
                    c.accountid=accLoop.Id;
                    conListToInsert.add(c);
                }
            }
        }
        if(conListToInsert.size()>0)
        {
            insert conListToInsert;
        }
        if(conListToDelete.size()>0)
        {
            Delete conListToDelete;
        }
    }
    if(trigger.isInsert && trigger.isAfter)
    {
        Map<Id,Decimal> mp=new Map<Id,Decimal>();
        for(Account a:Trigger.New)
        { 
            if(a.Number_Of_Contacts__c!=Null)
            {
                mp.put(a.id,a.Number_Of_Contacts__c);
            }
        }
        if(!mp.isEmpty())
        {
            for(Id a:mp.keyset())
            {
                for(Integer i=1;i<=mp.get(a);i++)
                {
                    Contact c=new Contact();
                    c.lastname='Test'+i;
                    c.accountid=a;
                    conList.add(c);
                }
            }
        }
        if(conList.size()>0)
        {
            insert conList;
        }
    }
    
}



Thanks 
Akshay
hanifa fatimahanifa fatima

How would i write a trigger for deleting a contact related to that account

E.g: If i created an account with no of contacts field as 3 , 3contacts would be created, now if i go to contacts page and delete 1 of those contacts i want to show to no of contacts field on Account as 2.

How can i write a delete trigger for that on contact?.

Steven NsubugaSteven Nsubuga
The trigger below would help
Trigger CountContacts on Contact (after insert, after update, after delete) {
	
	Set<Id> accountIds = new Set<Id>();
    List<Account> accountsToUpdate = new List<Account>();

    for (Contact c : Trigger.new) {
        accountIds.add(c.accountId);
    }

    if (Trigger.isUpdate || Trigger.isDelete) {
        for (Contact ac : Trigger.old) {
            accountIds.add(ac.accountId);
        }
    }

    // get a map of the accounts with the number of items
    Map<id,Account> popMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :accountIds]);

    List<AggregateResult> ars = [SELECT accountId, count(Id) FROM Contact WHERE accountId IN :accountIds];
    
    for (AggregateResult ar : ars) {
        popMap.get(ar.get('accountId')).Number_Of_Contacts__c = ar.get('expr0');
        popsToUpdate.add(popMap.get(ar.get('accountId')));
    }

    update popsToUpdate;
}

 
hanifa fatimahanifa fatima
Could you please simplify this part. i'm unable to get it.

// get a map of the accounts with the number of items Map<id,Account> popMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :accountIds]); List<AggregateResult> ars = [SELECT accountId, count(Id) FROM Contact WHERE accountId IN :accountIds]; for (AggregateResult ar : ars) { popMap.get(ar.get('accountId')).Number_Of_Contacts__c = ar.get('expr0'); popsToUpdate.add(popMap.get(ar.get('accountId'))); } update popsToUpdate; }
Steven NsubugaSteven Nsubuga
Map<id,Account> popMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :accountIds]);
That gets the accounts with the Number_Of_Contacts__c  field.
 
List<AggregateResult> ars = [SELECT accountId, count(Id) FROM Contact WHERE accountId IN :accountIds];
This gets the statistics, number of Contacts per account, from the Contact object by counting the number of times each Account shows up via the AccountId field in the Contact object.
 
for (AggregateResult ar : ars) { 
   popMap.get(ar.get('accountId')).Number_Of_Contacts__c = ar.get('expr0');        popsToUpdate.add(popMap.get(ar.get('accountId'))); } update popsToUpdate; 
}
The above code runs through the statistics and then updates the Number_Of_Contacts__c field of Account with the actual number of Contacts per Account


 
shiva reddy 59shiva reddy 59
@hanifa fatima

Simple trigger without using Map


Trigger NmbrofChldrecs on Account (After insert,After Update) {
list<contact> cons= new List<contact>();
list<contact> delcons= new List<contact>();
    If(trigger.Isinsert){
                    
        for(Account a:trigger.new){
             for(integer i=1;i<=a.Child_Contacts__c;i++){
             contact c = new contact();
             c.Lastname=a.Name+i;
             c.Phone = a.Phone;
             c.accountid=a.id;
             cons.add(c);
         }
        }        
    }
    if(trigger.isUpdate){
        //for(account a:trigger.new){}
            for(account acc : [select id, name, Child_Contacts__c, phone, (select id, lastname,Phone from contacts) from account where id in:trigger.new])

                    if(acc.contacts.size()<acc.Child_Contacts__c){
                        for(integer i=acc.contacts.size();i<acc.Child_Contacts__c;i++){
                            contact co = new contact();
                            co.lastname=acc.Name+(i+1);
                            co.Phone=acc.Phone;
                            co.accountid=acc.id;
                            cons.add(co);
                         }
                    }
                    else if(acc.contacts.size()>acc.Child_Contacts__c){
                    
                     delcons = [select id, lastname,Phone from contact  where accountid=:acc.id offset:integer.valueof(acc.Child_Contacts__c) ];
                     
                    }
            
            }
         }insert cons;
         delete delcons;
    
}