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
DeekDeek 

Contact Trigger Help

Hi All,

We have a custom check box field in contact as Potential Contact - "Pot_Contact__c".

The requirement is when we add or update a contact for an account and if there is an existing contact with the above check box field checked, it should throw error or otherwise continue saving the contact record.

Also there should be atleast one contact with the check box checked when creating a new or existing contact. 

Hope I am clear in my statement.

The trigger written so far is as below but for some reason its not working as expected. When trying to create a new contact or updating a existing contact I am getting both the error messages and not allowing me to save the contact.

I am sure I have made a  major mistake but cant rectify due to lack of coding expereince. Please help to fix.

trigger PotentialContactCheckbox on Contact (before insert,before update) {
   
set<id> conaccids=new set<id>();
    map<id,List<contact>> relcontactsmap=new map<id,List<contact>>();
    List<contact> cons=new List<contact>();
   
List<Account> accts=new List<Account>();
   
for(contact con:trigger.new){
        conaccids.add(con.AccountId);
    }
     accts=[select id,name from Account where id=:conaccids];
   
for(Account acc:accts){
        id accid=acc.id;
        if (Trigger.isUpdate)
        {
            cons=[select id,Pot_Contact__c from contact where AccountId=:accid  AND id not in :trigger.old];
        }
        else
        {
           cons=[select id,Pot_Contact__c from contact where AccountId=:accid];
        }
        if(cons.size()>0){
          relcontactsmap.put(accid,cons);
        }
    }
  
   
    for(contact con1:trigger.new){
        if((Trigger.isInsert) || (Trigger.isUpdate) ) {
          boolean checkCC=false;
          if(con1.Pot_Contact__c==true){
            if(relcontactsmap.containsKey(con1.AccountId)){
               con1.Pot_Contact__c.adderror('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');
            }
             checkCC=true;
             break;         
          }
             if(con1.Pot_Contact__c==false){
               if(relcontactsmap.containsKey(con1.AccountId)){
                 con1.Pot_Contact__c.adderror('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
                }
             }
            
       }
   
   
   
   
    }
Ramu_SFDCRamu_SFDC
Hi Deek, I see the exact same question of your's in the past at the link below. 

https://developer.salesforce.com/forums/?id=906F00000009n7SIAQ

please see if this helps 
DeekDeek
Hi Ramu,

I know but that didnt fix the problem completely. Also there is a new addition where I have mentioned that there needs to be atleast one potential contact when adding or updating contacts.

Could you please advise further Ramu?
Ramu_SFDCRamu_SFDC
Hi Deek, Regarding your second requirement, if there are 10 contacts being updated that refer to 10 different accounts. What if there are no existing contacts with the checkbox checked in about 5 accounts? should the system throw error? If Yes, then you would end up with 5 errors.

Please elaborate with an example on your second requirement so that I can modify the code that Chidambar has suggested you earlier.
Mikola SenykMikola Senyk
Hi Deek,

I have done refactoring of your code due to bad practice of using SOQL inside the loop.
The code for your task:
trigger PotentialContactCheckbox on Contact (before insert,before update) {
   
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }

    // find contacts with Pot_Contact__c equals to TRUE only for related Accounts
    List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];
    // build a map with key = AccountId and value = ContactId
    Map<Id,Id> relAccContMap = new Map<Id,Id>();
    for (Contact con: relContacts) {
        relAccContMap.put(con.AccountId, con.Id);
    }

    // check for correct set of Pot_Contact__c field
    for (Contact con: Trigger.new) {
        Id relContactId = relAccContMap.get(con.AccountId); // ID of Contact or null
        if ( con.Pot_Contact__c ) {
            if ( relContactId != null && relContactId != con.Id ) {
                con.Pot_Contact__c.addError('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');
            }
        } else {
            if ( relContactId == null && con.AccountId != null ) {
                con.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
            }
        }
    }

}

DeekDeek
Hi Mikola,

Most of the code requirements worked like a charm.  The only thing thats not working is as below:

Say I have 3 contacts for an account with one of them as a Potential contact checbox checked. When i edit and uncheck the potential contact check box, it allows me to save the contact. Thats means now I have 3 contacts with the potential contact check box Unchecked.

Could you please help me with this so that at any point of time there should be a Potential contact for an Account.

Thanks for all the help in advance.
Mikola SenykMikola Senyk
Hi Deek,

Yes, you are completely right. Change the line 27 to the following code:
if ( (relContactId == null || relContactId == con.Id) && con.AccountId != null ) {
DeekDeek
Hi Mikola,

That's perfectly worked. A BIG Kudos to you.

Last but not the least. For making it scalable in future, if we want to allow more than 1 potential contact how do we achieve that.
Mikola SenykMikola Senyk
It is possible to allow multiple potential contact. First of all you shouldn't take care about records with con.Pot_Contact__c equals to true. So, the following piece of code doesn't need any more:
if ( con.Pot_Contact__c ) {
    ...
}
Also you have to collect all ID for contacts with Pot_Contact__c == true in set:
Map<Id,Set<Id>> relAccContMap = new Map<Id,Set<Id>>();
...
And finally code in the loop:
if ( ! con.Pot_Contact__c ) {
    Set<Id> relContactIds = relAccContMap.get(con.AccountId);
    if ( relContactIds != null ) {
        relContactIds.remove(con.Id);
        if ( ! relContactIds.isEmpty() ) {
            continue;
        }
    }
    con.Pot_Contact__c.addError('There has to be at least one Potential Contact ...');
}
DeekDeek
Hi Mikola,

You are a real genius in apex coding. Really appreciate your quick help.

Sorry, my bad, which I forgot to mention during testing yesterday.

Delete Operation:
When we delete a contact with Pot_Contact__c as True, thats fine--- but it should make the existing contact as TRUE which is recently created.
Otherwise if there is just 1 contact as True and we are deleting, create a new Contact record with Pot_Contact__c as True for that account.

Could you please help on this?

Below is the final code you have given so far.

trigger PotentialContactCheckbox on Contact (before insert,before update) {

// get set of ID for related Accounts

Set<id> accIds = new Set<id>();

for (Contact con: Trigger.new) {

     if ( con.AccountId != null ) {

         accIds.add(con.AccountId);

     }

}



// find contacts with Pot_Contact__c equals to TRUE only for related Accounts

List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];

// build a map with key = AccountId and value = ContactId

Map<Id,Id> relAccContMap = new Map<Id,Id>();

for (Contact con: relContacts) {

     relAccContMap.put(con.AccountId, con.Id);

}



// check for correct set of Pot_Contact__c field

for (Contact con: Trigger.new) {

     Id relContactId = relAccContMap.get(con.AccountId); // ID of Contact or null

     if ( con.Pot_Contact__c ) {

         if ( relContactId != null && relContactId != con.Id ) {

             con.Pot_Contact__c.addError('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');

         }

     } else {

         if ( (relContactId == null || relContactId == con.Id) && con.AccountId != null ) {

             con.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');

         }

     }

}



}


Mikola SenykMikola Senyk
Hi Deek,

Your logic for delete operation isn't clear for me. I accept with part where we set Pot_Contact__c as True for recently created contact. But I don't understand why should we create new Contact after deleting last contact for Account?
I think the better way is to prevent of deleting of Contact with Pot_Contact__c equals to true if there is another Contacts related to the Account. And you should allow to delete last Contact without checking state of Pot_Contact__c field.
DeekDeek
Hi Mikola,

Thats indeed a very good suggestion. Thanks.

Delete Operation:
1.When we delete a contact with Pot_Contact__c as True, thats fine--- but it should make the existing contact as TRUE which is recently created.
2.if there is another Contacts related to the Account  - allow to delete last Contact without checking state of Pot_Contact__c field.

Hope you concur as well. Where do we put in place this new piece of code. 
DeekDeek
Hi Mikola,

Could you please send me the delete logic when you get time? I am really stuck up at this point.

Thanks in Advance.
Mikola SenykMikola Senyk
Hi Deek,

Logic for delete operation we will put on after delete event of trigger.
if ( Trigger.isAfter && Trigger.isDelete ) {
    // get set of ID for related Accounts for OLD (deleted records) with Pot_Contact__c == true
    Set<id> aIds = new Set<id>();
    for (Contact con: Trigger.old) {
        if ( con.AccountId != null && con.Pot_Contact__c ) {
            aIds.add(con.AccountId);
        }
    }

    // find contacts for related Accounts
    List<Contact> lastContacts = [SELECT AccountId FROM Contact WHERE AccountId IN :aIds];
    // build a map with key = AccountId and value = recently created Contact
    Map<Id,Contact> accContMap = new Map<Id,Contact>();
    for (Contact con: lastContacts) {
        Contact c = accContMap.get(con.AccountId);
        if ( c == null || con.CreatedDate > c.CreatedDate ) {
            accContMap.put(con.AccountId, con);
        }
    }

    // set Pot_Contact__c field equals to true for recently created Contacts
    for (Contact con: accContMap.values()) {
        con.Pot_Contact__c = true;
    }
    update accContMap.values();
}
Of course, deletion logic when multiple potential contacts are allowed will be slightly different.
DeekDeek
Hi Milano,

Sorry to say but the delete logic is not firing at all.

I tested with 2 contacts for an Account with one of them as a Pot Contact. When I deleted the contact with the check marked its not making the other one as Pot ential contact. I believe we are on the same page with the delete logic.
 
Please help.

trigger PotentialContactCheckbox on Contact (before insert,before update) {
  
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }

    // find contacts with Pot_Contact__c equals to TRUE only for related Accounts
    List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];
   
    // build a map with key = AccountId and value = ContactId
    Map<Id,Id> relAccContMap = new Map<Id,Id>();
   
   
    for (Contact con: relContacts) { //WHERE Pot_Contact__c = true
        relAccContMap.put(con.AccountId, con.Id);
       
    }

    // check for correct set of Pot_Contact__c field
    for (Contact newcon: Trigger.new) {
       
        Id relContactId = relAccContMap.get(newcon.AccountId); // ID of existing Contact or null
       
        if((Trigger.isInsert) || (Trigger.isUpdate) ) {
       
          if ( newcon.Pot_Contact__c ) {
            if ( relContactId != null && relContactId != newcon.Id ) {
                newcon.Pot_Contact__c.addError('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');
            }
        }  else {
             if ( (relContactId == null || relContactId == newcon.Id) && newcon.AccountId != null ) {
                newcon.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
            }
        }
    }  
    }
// DELETE LOGIC

if ( Trigger.isAfter && Trigger.isDelete ) {
    // get set of ID for related Accounts for OLD (deleted records) with Pot_Contact__c == true
    Set<id> aIds = new Set<id>();
    for (Contact con: Trigger.old) {
        if ( con.AccountId != null && con.Pot_Contact__c ) {
            aIds.add(con.AccountId);
        }
    }
    // find contacts for related Accounts
    List<Contact> lastContacts = [SELECT AccountId FROM Contact WHERE AccountId IN :aIds];
    // build a map with key = AccountId and value = recently created Contact
    Map<Id,Contact> accContMap = new Map<Id,Contact>();
    for (Contact con: lastContacts) {
        Contact c = accContMap.get(con.AccountId);
        if ( c == null || con.CreatedDate > c.CreatedDate ) {
            accContMap.put(con.AccountId, con);
        }
    }
    // set Pot_Contact__c field equals to true for recently created Contacts
    for (Contact con: accContMap.values()) {
        con.Pot_Contact__c = true;
    }
    update accContMap.values();
}


}


Mikola SenykMikola Senyk
I think you forget to add "after delete" to the trigger's parameters:
trigger PotentialContactCheckbox on Contact (before insert,before update, after delete) {
...
And one more thing. It is better to put logic for insert and update into "if" block. It prevents potential errors and unnecessary SQOL queries.
if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
    // Insert and update logic
    ...
}
DeekDeek
Hi Milano,

As advised I have added the necessary code. Now the I am getting error message when I am deleteing contact with the check box true as well as for contact with check box as false.

Validation Errors While Saving Record(s)
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger PotentialContactCheckbox caused an unexpected exception, contact your administrator: PotentialContactCheckbox: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.PotentialContactCheckbox: line 5, column 1".

Please advise.

Below is the last version of the code.

trigger PotentialContactCheckbox on Contact (before insert,before update, after delete) {
  
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }

    // find contacts with Pot_Contact__c equals to TRUE only for related Accounts
    List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];
   
    // build a map with key = AccountId and value = ContactId
    Map<Id,Id> relAccContMap = new Map<Id,Id>();
   
   
    for (Contact con: relContacts) { //WHERE Pot_Contact__c = true
        relAccContMap.put(con.AccountId, con.Id);
       
    }

    // check for correct set of Pot_Contact__c field
    for (Contact newcon: Trigger.new) {
       
        Id relContactId = relAccContMap.get(newcon.AccountId); // ID of existing Contact or null
       
        if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
       
          if ( newcon.Pot_Contact__c ) {
            if ( relContactId != null && relContactId != newcon.Id ) {
                newcon.Pot_Contact__c.addError('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');
            }
        }  else {
             if ( (relContactId == null || relContactId == newcon.Id) && newcon.AccountId != null ) {
                newcon.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
            }
        }
    }  
    }
// DELETE LOGIC

if ( Trigger.isAfter && Trigger.isDelete ) {
    // get set of ID for related Accounts for OLD (deleted records) with Pot_Contact__c == true
    Set<id> aIds = new Set<id>();
    for (Contact con: Trigger.old) {
        if ( con.AccountId != null && con.Pot_Contact__c ) {
            aIds.add(con.AccountId);
        }
    }
    // find contacts for related Accounts
    List<Contact> lastContacts = [SELECT AccountId FROM Contact WHERE AccountId IN :aIds];
    // build a map with key = AccountId and value = recently created Contact
    Map<Id,Contact> accContMap = new Map<Id,Contact>();
    for (Contact con: lastContacts) {
        Contact c = accContMap.get(con.AccountId);
        if ( c == null || con.CreatedDate > c.CreatedDate ) {
            accContMap.put(con.AccountId, con);
        }
    }
    // set Pot_Contact__c field equals to true for recently created Contacts
    for (Contact con: accContMap.values()) {
        con.Pot_Contact__c = true;
    }
    update accContMap.values();
}


}
Mikola SenykMikola Senyk
You put "if" block in the wrong place. You have to cover all code as Insert and Update logic except of Delete logic. I mean:
if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
    // UPDATE & INSERT LOGIC
}
if ( Trigger.isAfter && Trigger.isDelete ) {
    // DELETE LOGIC
}
DeekDeek
Hi Milano,

You are too too good. Thanks once agin for all your help so far. The delete logic is now perfectly working fine.

In the insert update logic there is a help required. A logic change in the error message:"There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact."

--When user creates a new contact with check box ticked, the trigger should allow to save but make the check box Unchecked for the existing contact rather than throwing the above error message.

For my learning I was trying to modify the code but not successfull. Got the error message at line34:-  relContactId.Campaign_Contact__c=false --: 

Error: Compile Error: Initial term of field expression must be a concrete SObject: Id at line 34 column 17

Below is the overall code:

trigger PotentialContactCheckbox on Contact (before insert,before update, after delete) {
  
// START UPDATE and INSERT LOGIC 

   if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }

    // find contacts with Pot_Contact__c equals to TRUE only for related Accounts
    List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];
   
    // build a map with key = AccountId and value = ContactId
    Map<Id,Id> relAccContMap = new Map<Id,Id>();
   
   
    for (Contact con: relContacts) { //WHERE Pot_Contact__c = true
        relAccContMap.put(con.AccountId, con.Id);
       
    }

    // check for correct set of Pot_Contact__c field
    for (Contact newcon: Trigger.new) {
       
        Id relContactId = relAccContMap.get(newcon.AccountId); // ID of existing Contact or null
       
           
          if ( newcon.Pot_Contact__c ) {
            if ( relContactId != null){                // && relContactId != newcon.Id ) {
               
             // newcon.Pot_Contact__c.addError('There is already a Potential Contact associated to this Account. Please uncheck and try saving the Contact.');
             
             relContactId.Pot_Contact__c=false;
  
            }
        }  else {
             if ( (relContactId == null || relContactId == newcon.Id) && newcon.AccountId != null ) {
                newcon.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
            }
        }
   // }  
    }
} // END UPDATE and INSERT LOGIC

// START DELETE LOGIC

if ( Trigger.isAfter && Trigger.isDelete ) {
    // get set of ID for related Accounts for OLD (deleted records) with Pot_Contact__c == true
    Set<id> aIds = new Set<id>();
    for (Contact con: Trigger.old) {
        if ( con.AccountId != null && con.Pot_Contact__c ) {
            aIds.add(con.AccountId);
        }
    }
    // find contacts for related Accounts
    List<Contact> lastContacts = [SELECT AccountId,CreatedDate FROM Contact WHERE AccountId IN :aIds];
    // build a map with key = AccountId and value = recently created Contact
    Map<Id,Contact> accContMap = new Map<Id,Contact>();
    for (Contact con: lastContacts) {
        Contact c = accContMap.get(con.AccountId);
        if ( c == null || con.CreatedDate > c.CreatedDate ) {
            accContMap.put(con.AccountId, con);
        }
    }
    // set Pot_Contact__c field equals to true for recently created Contacts
    for (Contact con: accContMap.values()) {
        con.Pot_Contact__c = true;
    }
    update accContMap.values();
}  // END DELETE LOGIC

}
Mikola SenykMikola Senyk
It is possible to clear Pot_Contact__c for existing contact. You have to use the following logic:
// check for correct set of Pot_Contact__c field
List<Contact> clearList = new List<Contact>();
for (Contact newcon: Trigger.new) {
    Id relContactId = relAccContMap.get(newcon.AccountId); // ID of existing Contact or null
    if ( newcon.Pot_Contact__c ) {
        if ( relContactId != null) && relContactId != newcon.Id ) {
            clearList.add(new Contact(id=relContactId, Pot_Contact__c=false));
        }
    }  else {
        if ( (relContactId == null || relContactId == newcon.Id) && newcon.AccountId != null ) {
            newcon.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
        }
    }
}
update clearList;
Before for loop we declare empty list of Contact. If there is another contact with Pot_Contact__c == true we will add it to list. After that list will be updated.
Mikola SenykMikola Senyk
Sorry, line number 6 should be:
if ( relContactId != null && relContactId != newcon.Id ) {
Without extra bracket ")" in the middle.
DeekDeek
HI Milano,

Thx for the quick response.

Below is the error message I am getting when I am adding a contact with the check box checked. 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger PotentialContactCheckbox caused an unexpected exception, contact your administrator: PotentialContactCheckbox: execution of BeforeInsert caused by: System.DmlException: Update failed. First exception on row 0 with id 003M000000SpFgmIAF; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.: [Campaign_Contact__c]: Trigger.PotentialContactCheckbox: line 40, column 1

below is the code so far:

trigger PotentialContactCheckbox on Contact (before insert,before update, after delete) {
  
   // START UPDATE and INSERT LOGIC
   if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }

    // find contacts with Pot_Contact__c equals to TRUE only for related Accounts
    List<Contact> relContacts = [SELECT AccountId FROM Contact WHERE Pot_Contact__c = true AND AccountId IN :accIds];
   
    // build a map with key = AccountId and value = ContactId
    Map<Id,Id> relAccContMap = new Map<Id,Id>();
   
   
    for (Contact con: relContacts) { //WHERE Pot_Contact__c = true
        relAccContMap.put(con.AccountId, con.Id);
       
    }

    // check for correct set of Pot_Contact__c field

List<Contact> clearList = new List<Contact>();
for (Contact newcon: Trigger.new) {
    Id relContactId = relAccContMap.get(newcon.AccountId); // ID of existing Contact or null
    if ( newcon.Pot_Contact__c) {
        if ( relContactId != null && relContactId != newcon.Id ) {
            clearList.add(new Contact(id=relContactId, Pot_Contact__c=false));
        }
    }  else {
        if ( (relContactId == null || relContactId == newcon.Id) && newcon.AccountId != null ) {
            newcon.Pot_Contact__c.addError('There has to be one Potential Contact associated to this Account. Please check the check box and try saving the Contact.');
        }
    }
}
update clearList;

     
} // END UPDATE and INSERT LOGIC   

// START DELETE LOGIC
   
    if ( Trigger.isAfter && Trigger.isDelete ) {
    // get set of ID for related Accounts for OLD (deleted records) with Pot_Contact__c == true
    Set<id> aIds = new Set<id>();
    for (Contact con: Trigger.old) {
        if ( con.AccountId != null && con.Pot_Contact__c ) {
            aIds.add(con.AccountId);
        }
    }
    // find contacts for related Accounts
    List<Contact> lastContacts = [SELECT AccountId,CreatedDate FROM Contact WHERE AccountId IN :aIds];
    // build a map with key = AccountId and value = recently created Contact
    Map<Id,Contact> accContMap = new Map<Id,Contact>();
    for (Contact con: lastContacts) {
        Contact c = accContMap.get(con.AccountId);
        if ( c == null || con.CreatedDate > c.CreatedDate ) {
            accContMap.put(con.AccountId, con);
        }
    }
    // set Pot_Contact__c field equals to true for recently created Contacts
    for (Contact con: accContMap.values()) {
        con.Pot_Contact__c = true;
    }
    update accContMap.values();
}  // END DELETE LOGIC


}
Mikola SenykMikola Senyk
Yes, It happens because your trigger is firing twice:
  • First when you create new Contact with Pot_Contact__c = true.
  • Second when your trigger try to update existing Contact and set Pot_Contact__c = false.
You can hotfix this situation with boolean static variable. There are a lot of examples how to do this.
In brief, you have to declare boolean property somewhere in Apex class (not in trigger!):
public static boolean firstRun = true;
And at the top of trigger put code of check:
if ( NAME_OF_APEX_CLASS.firstRun ) {
	NAME_OF_APEX_CLASS.firstRun = false;
} else {
	System.debug('Already ran!');
	return;
}
Use name of your Apex class instead of NAME_OF_APEX_CLASS.
DeekDeek
Hi Milano,

Sorry for the late response.

I have declared a class as below and added your given code in the trigger as advised. 

Is it correct now please?

public class pc {
public static boolean firstRun = true;
}

trigger PotentialContactCheckbox on Contact (before insert,before update, after delete) {

if ( pc.firstRun ) {
    pc.firstRun = false;
} else {
    System.debug('Already ran!');
    return;
}

// START UPDATE and INSERT LOGIC
   if ( Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate) ) {
    // get set of ID for related Accounts
    Set<id> accIds = new Set<id>();
    for (Contact con: Trigger.new) {
        if ( con.AccountId != null ) {
            accIds.add(con.AccountId);
        }
    }..................................
Mikola SenykMikola Senyk
Yes. It looks correct.