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
SFDC 2017SFDC 2017 

There are multiple Contact Records and one is primary among them. User is trying to un-select Primary

Hi All,

I am working on one scenario where there are Multiple Child Records for eg:Account is a parent and Under Account multiple child Objects Records will be there.In that child Object i have created one checkbox field called Primary and first record should be primary and if users adding another record as primary it has to thrwo error Message there is already one primary Record please unselect the existing record and add new record as primary marked
Eg:Let say under account 3 child records are there and 1 is primary already and user is trying to add the 3 rd record as primary it should throw error Message
NEXT There are 3 Multiple Child Records and one is primary among them and user is trying to delete the primary record without marking any other records as primary then it should throw error Message as User is trying to Delete primary Record without making another primary
If there is only one primary and user is trying to delete then it should allow the user to delete.
Note :Child Record Refers to Contact 
Any one please guide me to help to implement this scenarios.
Akhil AnilAkhil Anil
Hi Archu,

You can refer the below blog that explains how to achieve this.

https://force-base.com/2016/09/24/build-a-validation-by-shaking-hands-with-workflow-rules/

Hope that helps !

If it works kindly mark as an answer so that we can close this thread.
Agustina GarciaAgustina Garcia
You can also make it via a ApexCode if it is what you are looking for. Find below trigger that covers ONLY the insert side. You would have to do something similar for Update and Delete
 
trigger CTrigger on C__c (after insert)
{
    Set<Id> cIds = new Set<Id>();
    Set<Id> accIds = new Set<Id>();
    
    //Look for account Ids related to new records
	for(SObject so : Trigger.new)
    {
        C__c c = (C__c)so;
        
        cIds.add(c.Id);
        accIds.add((Id)c.Account__c);
    }
    
    //Look for all C__c recods that have this Account already
    List<C__c> cRecords = [Select Id,Primary__c,Account__c From C__c Where Account__c In :accIds];
    
    //Create a map with AccountId and the Primary__c field
    //but only if primery is true
	Map<Id, Boolean> accAndPrimaryMap = new Map<Id,Boolean>();
    for(C__c c : cRecords)
    {
        //Create a map with c Id and AccountId if this is not 
        //the element I want to create
        if(!cIds.contains(c.Id))
        {
        	//I will only check if the primary key is not true
            if(!accAndPrimaryMap.containsKey(c.Account__c))
            {
                accAndPrimaryMap.put(c.Account__c, c.Primary__c);
            }
            else
            {
                Boolean val = accAndPrimaryMap.get(c.Account__c);
                if(!val && c.Primary__c)
                {
                    accAndPrimaryMap.put(c.Account__c, c.Primary__c);
                }   
            }
        }
	}
    
    //Once I have the information
    //Iterate over the list of new C records
    for(SObject so : Trigger.new)
    {
        C__c c = (C__c)so;
        Id accId = (Id)c.Account__c;
		
        if(Trigger.isInsert)
        {
            if(c.Primary__c)
            {
                if(accAndPrimaryMap.containsKey(accId))
                {
                    Boolean primaryValue = accAndPrimaryMap.get(accId);
                    if(primaryValue)
                    {
                        //show error
                        so.addError('There is already a Primary');
                    }
                }
            }
        }
    }
}

 
SFDC 2017SFDC 2017
Thanks @Agustina Garcia.But the requirement is different let say for one account whatever the first contact record i am inserting it will be default primary=true and if the user added one more contact under that account and mark that as primary then it should automatically uncheck the previous one .And if user is trying to unselect the primary without selecting any other record as primary that time only this error should throw like select another record as primary 
Agustina GarciaAgustina Garcia
Archu, sorry for the late response.

I would set checked as default value for Primary field, so any time a new Contact is created, it would be Primary by default. Then below trigger will modify previous records to false if the latest is true.
 
trigger CTrigger on C__c (after insert)
{
    Set<Id> cIds = new Set<Id>();
    Set<Id> accIds = new Set<Id>();
    
    //Look for account Ids related to new records
    //If they have Primary__c equal to true
    for(SObject so : Trigger.new)
    {
        C__c c = (C__c)so;
        
        cIds.add(c.Id);
        
        if(c.Primary__c)
        {
            accIds.add((Id)c.Account__c);
        }
    }
    
    //Look for all C__c recods that have this Account already
    List<C__c> cRecords = [Select Id,Primary__c,Account__c From C__c Where Account__c In :accIds];
    
    List<C__c> cToUpdate = new List<C__c>();
    if(Trigger.isInsert)
    {
        for(C__c c : cRecords)
        {
            //If c has Primary equal to true and
            //if this is not 
            //the element I want to create
            //set Primary value to false
            if(!cIds.contains(c.Id))
            {
                if(c.Primary__c)
                {
                    c.Primary__c = false;
                    cToUpdate.add(c);
                }
            }
        }
        update cToUpdate;
    }
}

 
Dhilip DussaDhilip Dussa
Hi Agustina Garcia,

Can please explain how to use this code in before update/ after update trigger

Thanks
Agustina GarciaAgustina Garcia
Hi, the trigger is developed to be used only after inserts. If you need to add any logict on the update, you need to specify it as an argument 
 
trigger CTrigger on C__c (after insert, after update)

and then add the logic on its own piece of code
 
if(Trigger.isUpdate)

Regarding before, I would not advice to add logic or validations on "before" because un after can change anything you checked before and make it fails.