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
Maf_007Maf_007 

Trigger throws error on valid condition

Hi,

 

I have a trigger on a custom object called service__c which is a child of account. Trigger prevents users to have more than one open service for an account at the same time (pick list status__c field). My problem here is It does not allow me to update picklist value for the open account eventhough this is the only open account. My code is below:

public with sharing class ServiceTriggerHandler {
	private boolean m_isExecuting = false;
	private integer BatchSize = 0;
	
	/*public ServiceTriggerHandler(boolean isExecuting, integer size){
		m_isExecuting = isExecuting;
		BatchSize = size;
	}*/
	
	public void servicestatusvalidationmethod(List<Service__c> services){
        Set<id>serviceids = new Set<id>{};
        
        for(Service__c service:services){
            //if(service.Status__c != 'Closed'){
				serviceids.add(service.Account__c);
           // }
        }
        List<Service__c> allactiveservices = [select id, Status__c,Account__c from Service__c where Account__c IN: serviceids and Status__c != 'Closed'];
        System.debug(allactiveservices);
        
        for(Service__c newservice:services){
            for(Service__c servicesvalidation:allactiveservices){
                if(newservice.status__c != 'Closed'){
                	newservice.addError('There is already one Active Service For this Account');
            	}
            }
        }
    }
}

 

 

Any help would be highly appreciated.

 

Thanks,

Best Answer chosen by Admin (Salesforce Developers) 
Maf_007Maf_007

Hi,

 

In my scenario I can not use a roll up summary field. But I was ablo to fix the issue by checking the id of the current record with ids in soql. Thanks for your response anyway.

 

 

All Answers

magicforce9magicforce9

Hi,

 

Does your picklist field(Status__c) field only has two values or more ?

 

Here is another way that you can organise your code for your handler method ...

public void servicestatusvalidationmethod(List<Service__c> services){
        Set<id>serviceids = new Set<id>{};
        
        for(Service__c service:services){
            //if(service.Status__c != 'Closed'){
				serviceids.add(service.Account__c);
           // }
        }

        /* I can see that you are only querying for records that are not Closed, but there cloud be Service__c records with status other than closed or open or some thing else or do you only have two values in the Status__c picklist. This cloud be the reason of your problem, What if the change the query to some thing below
        List<Service__c> allactiveservices = [select id, Status__c,Account__c from Service__c where Account__c IN: serviceids and Status__c != 'Closed'];
        */

        List<Service__c> allactiveservices = [select id, Status__c,Account__c from Service__c where Account__c IN: serviceids and Status__c == 'Open'];

        System.debug(allactiveservices);

        //Since Account -> Service__c has one to many relationship, organising them in Map.

        Map<Id, List<Service__c>> allactiveservicesMap = new Map<Id, List<Service__c>>();
        for(Service__c serv : allactiveservices)
        {

            if(allactiveservicesMap.contacinsKey(serv.Account__c))
                allactiveservicesMap.get(serv.Account__c).add(serv);
            else
                allactiveservicesMap.put(serv.Account__c, new List<Service__c>{serv});
        }

        //Checking for Active Services
        for(Service__c newservice : services){

            if(allactiveservicesMap.get(newservice.Account__c).size() > 0)
            	newservice.addError('There is already one Active Service For this Account');
            	
            }
        }
    }

 

Maf_007Maf_007

Hi MagicForce,

 

Thanks for your reply. I have 5 different values for picklist. Could you please explain a bit more about using the map since this is not my strongest area. as far as I can I understand, I need a Map when I need the key as well as the value for that. In this case I need to know if there's more that one services other than closed status(that's why used Set for IDs). But my trigger does not allow me to change status for the only open account eventhough it satisfies the query criteria. Your code seems much organized, Could you please explain the use case for Map in this scecrio?

 

Thanks,

Maf 

Daniel Zeidler (DZ)Daniel Zeidler (DZ)

Is the relationship between account and service__c is a master-detail? If so, you may be able to do this validation declaratively by creating a role-up summary field and a custom validation rule. The basic idea is put a roll-up summary field on the account which "counts" the children that are open. Then add a validation rule to the account which enforces that this field be <= 1.

Maf_007Maf_007

Hi,

 

In my scenario I can not use a roll up summary field. But I was ablo to fix the issue by checking the id of the current record with ids in soql. Thanks for your response anyway.

 

 

This was selected as the best answer
magicforce9magicforce9

The usage of map depends on how you decide to approach solving the user story. For me I found it easier to replicate the one to many relationship that is there between Account & Service__c object.

 

Ok I think I figured out the problem.....


Your query down below is querying for all the Service__c records who's Status is not 'Closed', so even if you have 1 record that has a different status besides 'Closed' will be picked by query, so I'll always endup with atleast 1 record for trigger.isUpdate. And later in the map we are checking if there is atleast 1 record with not closed status and you'll always endup getting an error for update(however it will work for insert)

List<Service__c> allactiveservices = [select id, Status__c,Account__c from Service__c where Account__c IN: serviceids and Status__c != 'Closed'];

You can try the possible change in query below and see if that helps.

    Set<id> serviceids = new Set<id>();
Set<id> services = new Set<id>();
for(Service__c service:services){ //if(service.Status__c != 'Closed'){ serviceids.add(service.Account__c); /*I'm picking the service record id's to exclude them in query as Id will only be in the records that are comming from update context and I hope your triggers is on before update & before insert*/ if(service.id != null) services.add(service.id); // } } List<Service__c> allactiveservices = [select id, Status__c,Account__c from Service__c where id NOT IN :services and Account__c IN: serviceids and Status__c != 'Closed'];

 

magicforce9magicforce9

Ok, I didn't saw you solved it as I just refreshed my page..I'm gald the issue is resolved

Maf_007Maf_007

Hi MagicForce,

 

Thanks for your time and recommendation. This is exactly how solved the problem did not have to use the map. Just checked if the id in new trigger context existed in the list if it did not then throw an error.