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
Denise CrosbyDenise Crosby 

need help with trigger to verify only one primary contractor for an opportunity

Hello. I have a custom object contractor__c child object under opportunity. If a contractor__c is created, I need to make sure one and only one contractor__c is marked as primary for the opportunity. I tried an Apex trigger like this but it's not working. If I set the first contractor as primary, it will also set the second contractor as primary. And if I turn the primary flag off for the first contractor, it does not turn on the primary flag for the second contractor. Any help is appreciated.
 
trigger VerifyOnlyOnePrimaryContractor on Contractor__c (before insert, before update) {
    
    for(Contractor__c c: trigger.new){
        string O = c.Opportunity__c;
        string thisContractor = c.ID;
        //if this contractor is marked primary, make all the others for the same opportunity not primary
        if(c.Primary__c){
            List<contractor__c> cList = [Select id from Contractor__c where Opportunity__c = :O and id <> :thisContractor];
            
            for(contractor__c con : cList){
                con.Primary__c = FALSE;
            }
            update cList;
        }
        
        else{
            //if no contractors are marked as primary, set one of them as primary
            string primary = 'no';
            List<contractor__c> cList1 = [Select id,primary__c from Contractor__c where Opportunity__c = :O];
            if(cList1.size() == 0){
                c.Primary__c = TRUE;
            }
            else
            {
                for(contractor__c con1 : cList1){
                    if(con1.Primary__c){
                        primary = 'yes';
                    }
                }
                if(primary == 'no'){
                    
                    c.Primary__c = TRUE;
                }
            }
        }
        
    }                                                                                                                                                                                                       
}

 
Best Answer chosen by Denise Crosby
Dayakar.DDayakar.D
Denise,

Please try below.
trigger VerifyOnlyOnePrimaryContractor on Anilji__Contractor__c (before insert,before Update) {
    Map<String,Contractor__c> contractorMap = New Map<String,Contractor__c>();
    for(Contractor__c contractorVar : trigger.New)
    {
        if(contractorVar.Primary__c)
        	contractorMap.put(contractorVar.opportunity__c, contractorVar);
    }
    Map<Object,Object> countMap = New Map<Object,Object>();
    AggregateResult[] groupedResults = [select Opportunity__c,count(id) from Contractor__c where Opportunity__c in : contractorMap.keySet() and Primary__c=true  group by Opportunity__c];
    if(!groupedResults.isEmpty()){
        for(AggregateResult ar : groupedResults)
        {
            countMap.put(ar.get('Anilji__Opportunity__c'), ar.get('expr0'));
        }
        for(Contractor__c conVar : contractorMap.values())
        {
            system.debug('countMap.get(conVar.opportunity__c)'+countMap.get(conVar.opportunity__c));   
            if(countMap.get(conVar.opportunity__c) !=0)
            {
                conVar.addError('Only one Primary contractor is allowed for one Opportunity');
            }
        }
    }
}

Please let me know, if you still face any issues.

Best Regards,
Dayakar.D

All Answers

Denise CrosbyDenise Crosby
Hi Dayakar,
This is really good and much better. Thank you! The only issue I'm facing now is it won't let me make any updates to the primary checkbox once there is a single contractor in place. I can't deselect the checkbox on one contractor and save. And I also can't select the checkbox on a different contractor to save. I'm not sure how to handle that. Any ideas? 
Thanks again.
Dayakar.DDayakar.D
Denise,

Please try below.
trigger VerifyOnlyOnePrimaryContractor on Anilji__Contractor__c (before insert,before Update) {
    Map<String,Contractor__c> contractorMap = New Map<String,Contractor__c>();
    for(Contractor__c contractorVar : trigger.New)
    {
        if(contractorVar.Primary__c)
        	contractorMap.put(contractorVar.opportunity__c, contractorVar);
    }
    Map<Object,Object> countMap = New Map<Object,Object>();
    AggregateResult[] groupedResults = [select Opportunity__c,count(id) from Contractor__c where Opportunity__c in : contractorMap.keySet() and Primary__c=true  group by Opportunity__c];
    if(!groupedResults.isEmpty()){
        for(AggregateResult ar : groupedResults)
        {
            countMap.put(ar.get('Anilji__Opportunity__c'), ar.get('expr0'));
        }
        for(Contractor__c conVar : contractorMap.values())
        {
            system.debug('countMap.get(conVar.opportunity__c)'+countMap.get(conVar.opportunity__c));   
            if(countMap.get(conVar.opportunity__c) !=0)
            {
                conVar.addError('Only one Primary contractor is allowed for one Opportunity');
            }
        }
    }
}

Please let me know, if you still face any issues.

Best Regards,
Dayakar.D
This was selected as the best answer
Denise CrosbyDenise Crosby
Thank you Dayakar.D