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
Abhishek KhoslaAbhishek Khosla 

Not able to able to understand how to write this trigger

 My previous problem is not resolved I have a Custom filed in accounts which is name as No of contacts now i have to write trigger after update which follows the logic of if I put no of contacts more than the present value then the difference should create a contact( for ex Old value of contact = 8 new value 10 then 2 new contacts should be created ) if ( Old valve of contact = 10 and new value = 8 then 2 contact should be deleted ) how can I achieve this. I wrote the below trigger but it is not working correctly ( if old was 12 and new value 10 it is giving me an exception error ) ( if old value 12 and new value is 13 it creates 1 extra contact but if i update again the new value to 12 all contact gets deleted)

Ideal i want the same no of contacts should be there in the contact related list as per the No.of contacts mentioned in the account custom filed value

trigger trigger17 on Account (after update) {
    for(Account a:trigger.new){
        if(trigger.oldmap.get(a.id).Number_of_contacts__c <a.Number_of_contacts__c){
            System.debug(a.Number_of_contacts__c- trigger.oldmap.get(a.id).Number_of_contacts__c);
            for(Decimal i=1;i<=(a.Number_of_contacts__c- trigger.oldmap.get(a.id).Number_of_contacts__c);i++){
                contact c = new contact();
                c.AccountId =a.Id;
                c.LastName = a.Name;
                Insert c;
            }
        }
        if(trigger.oldmap.get(a.id).Number_of_contacts__c >a.Number_of_contacts__c){
            List<Contact> con = [Select id,name,accountid from contact where accountid =: a.id];
            System.debug(con);
            Decimal Diff = trigger.oldmap.get(a.id).Number_of_contacts__c - a.Number_of_contacts__c;
            System.debug(Diff);
            For(Contact c : Con){
                for(Integer i = 1 ; i<= Diff; i++){
                    Delete c;
                }
            }
        }
    }
     }

I also want the reverse if an contact related to that particular ID is deleted then in the No of Contact filed it should reduce if any new contact created on the same account then the no of contact field should increase 
Best Answer chosen by Abhishek Khosla
Ravi Dutt SharmaRavi Dutt Sharma
Try below, I have written this in sublime, so you might get some compile time errros, please correct accordingly.
 
trigger AccountTrigger on Account(after update){

    if(Trigger.isAfter && Trigger.isUpdate){
        Set<Id> accIds = new Set<Id>();
        // Map - Key: Account Id | Value: Number_of_contacts__c
        Map<Id, Integer> accIdToNumOfContacts = new Map<Id, Integer>();
        // check if value of Number_of_contacts__c has changed
        for(Account acc: Trigger.new){
            if(acc.Number_of_contacts__c != Trigger.oldMap.get(acc.Id).Number_of_contacts__c){
                accIds.add(acc.Id);
                accIdToNumOfContacts.put(acc.Id, acc.Number_of_contacts__c);
            }
        }

        List<Account> accounts = new List<Account>();
        if(accIds.size() > 0){
            accounts = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE Id IN:accIds];
        }

        for(Account acc: accounts){
            // check if value in Number_of_contacts__c does not match with number of contacts present under that account
            Integer fieldValue = accIdToNumOfContacts.get(acc.Id);
            List<Contact> contacts = acc.Contacts;
            Integer numberOfContacts = contacts.size();
            if(fieldValue == numberOfContacts){
                continue;
            }else if(fieldValue > numberOfContacts){
                // add contacts - implement logic here
            }else if(fieldValue < numberOfContacts){
                // delete contacts - implement logic here
                Integer diff = numberOfContacts - fieldValue; // diff contacts needs to be deleted
                List<Contact> contactsToBeDeleted = new List<Contact>();
                for(Integer i =0; i<diff; i++){
                    contactsToBeDeleted.add(contacts[i]);
                }
                if(contactsToBeDeleted.size() > 0){
                    Database.delete(contactsToBeDeleted, false);
                }
            }
        }
    }
}

Please mark this as closed if this solves your issue. Thanks

All Answers

Ravi Dutt SharmaRavi Dutt Sharma
Hi Abhishek,

You can follow below piece of code to acheive your requirement. Let me know if you need further help.
 
trigger AccountTrigger on Account(after update){

    if(Trigger.isAfter && Trigger.isUpdate){
        Set<Id> accIds = new Set<Id>();
        // Map - Key: Account Id | Value: Number_of_contacts__c
        Map<Id, Integer> accIdToNumOfContacts = new Map<Id, Integer>();
        // check if value of Number_of_contacts__c has changed
        for(Account acc: Trigger.new){
            if(acc.Number_of_contacts__c != Trigger.oldMap.get(acc.Id).Number_of_contacts__c){
                accIds.add(acc.Id);
                accIdToNumOfContacts.put(acc.Id, acc.Number_of_contacts__c);
            }
        }

        List<Account> accounts = new List<Account>();
        if(accIds.size() > 0){
            accounts = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE Id IN:accIds];
        }

        for(Account acc: accounts){
            // check if value in Number_of_contacts__c does not match with number of contacts present under that account
            Integer fieldValue = accIdToNumOfContacts.get(acc.Id);
            Integer numberOfContacts = acc.Contacts.size();
            if(fieldValue == numberOfContacts){
                continue;
            }else if(fieldValue > numberOfContacts){
                // add contacts - implement logic here
            }else if(fieldValue < numberOfContacts){
                // delete contacts - implement logic here
            }
        }
    }
}



 
Abhishek KhoslaAbhishek Khosla
Can you please help me with delete contacts logic I am not able to understand how should i do it ; below is what i am trying to do 
if(fieldValue < numberOfContacts){

                // delete contacts - implement logic here
                Decimal diff = numberofcontacts - fieldValue;
                System.debug(Diff);
                for(Integer i =1; i<=diff;i++){
                    Contact c = new Contact();
                    c.id = acc.contacts.id;
                    Delete c;

Error : A non foreign key field cannot be referenced in a path expression: Contacts
Ravi Dutt SharmaRavi Dutt Sharma
Try below, I have written this in sublime, so you might get some compile time errros, please correct accordingly.
 
trigger AccountTrigger on Account(after update){

    if(Trigger.isAfter && Trigger.isUpdate){
        Set<Id> accIds = new Set<Id>();
        // Map - Key: Account Id | Value: Number_of_contacts__c
        Map<Id, Integer> accIdToNumOfContacts = new Map<Id, Integer>();
        // check if value of Number_of_contacts__c has changed
        for(Account acc: Trigger.new){
            if(acc.Number_of_contacts__c != Trigger.oldMap.get(acc.Id).Number_of_contacts__c){
                accIds.add(acc.Id);
                accIdToNumOfContacts.put(acc.Id, acc.Number_of_contacts__c);
            }
        }

        List<Account> accounts = new List<Account>();
        if(accIds.size() > 0){
            accounts = [SELECT Id,(SELECT Id FROM Contacts) FROM Account WHERE Id IN:accIds];
        }

        for(Account acc: accounts){
            // check if value in Number_of_contacts__c does not match with number of contacts present under that account
            Integer fieldValue = accIdToNumOfContacts.get(acc.Id);
            List<Contact> contacts = acc.Contacts;
            Integer numberOfContacts = contacts.size();
            if(fieldValue == numberOfContacts){
                continue;
            }else if(fieldValue > numberOfContacts){
                // add contacts - implement logic here
            }else if(fieldValue < numberOfContacts){
                // delete contacts - implement logic here
                Integer diff = numberOfContacts - fieldValue; // diff contacts needs to be deleted
                List<Contact> contactsToBeDeleted = new List<Contact>();
                for(Integer i =0; i<diff; i++){
                    contactsToBeDeleted.add(contacts[i]);
                }
                if(contactsToBeDeleted.size() > 0){
                    Database.delete(contactsToBeDeleted, false);
                }
            }
        }
    }
}

Please mark this as closed if this solves your issue. Thanks
This was selected as the best answer
Abhishek KhoslaAbhishek Khosla
Thanks it is done