You need to sign in to do that
Don't have an account?
Developer.mikie.Apex.Student
Validation Rule to Prevent more than one Child record with certain Picklist Option
Hey there,
I have Accounts and Accounts has a custom child object named Services__c. Services__c, are added to the account. I was wondering if it is possible to write a validation rule which would prevent the same service (which is picked through a picklist, which auto-updates a hidden lookup field) from getting added twice to an account.
If more explanation is neededd, please do not hesitate to ask.
Thankyou
I have Accounts and Accounts has a custom child object named Services__c. Services__c, are added to the account. I was wondering if it is possible to write a validation rule which would prevent the same service (which is picked through a picklist, which auto-updates a hidden lookup field) from getting added twice to an account.
If more explanation is neededd, please do not hesitate to ask.
Thankyou
All Answers
When I say hidden, I mean that it does not appear on page layouts, it is used as a way of creating a relationship between service__c and destiny_products_and_services__c which is sort of like a collection of records.
The user will select the service name and service type, this will auto-fill the lookup field as such:
As some services can be added more than once,w here as others have a limit of 1. The goal is to make it so that if an account already has a servie named 'X' attached, then another service 'X' cannot be added.
I hope I explained it well.
Thank you in advance for any help you can give me!
1. Create a before trigger on service__c object
2. Create a set variable to get the list of all account id's entered in these service records.
3. Create another set variable and fetch all the Account id's that correspond to the service records that match the following crtieriasomething like "select accountid from service__c where accountid=<set variable> and picklistfield=<the option that you are checking>"
4. now loop through trigger.new records and check if the account id mentioned in the service record exist in the above set variable(declared in point 3). This means that the account record already has one service record with that picklist value selected. Throw the error accordingly.
Else, go ahead and create the record.
Hope this helps.
Would Something like this, but refering service rather than account status work: Is there anyway to do this using a validation rules? Perhaps with $object.<Service__c.ServiceName>. I ask because Service__c already has three triggers and I have heard that you can have too many triggers on an object. especially cosnidering that I would have to make one for each service.
Regarding your trigger, it would definately work. If there are any errors let me know.
You might have to tweak it further as it is not adviced to use soql query within for loop for it might hit governor limits during bulk transactions. To fix this, please move the soql query out of for loop by using map variables and you can then loop through the results
Here's a way to rewrite your validation logic so it is properly 'bulkified'.
Based on your earlier statement, I replace the Account_Status__c object with the Service__c object.
Like you mentioned, it's not good design to write a trigger for each one of these Services if there are varying business rules on which ones restricted to only a single entry. Without knowing more about your data model, here is one idea of how to solve it.
Create a custom object (for the sake the conversation we'll call it ServiceRules) and add one custom number field called MaximumRecords.
Add a record in this new object for each service that is included in the picklist on the Account object and if there is a maximum number of records enter it in MaximumRecords. If there is no limit, just leave MaximumRecords empty.
Here's how you could write the validation rule leveraging that new object.
This allows you to set a different maximum for each Service and validate all of them with this single validation rule.
I didn't build out the data model to compile or test this example so there might be a couple corrections needed. Just let me know.
i jsut had two quick questions: Would it be difficult to add other rules, other than maximum records later on?
Does every service record need a service rules attached? or is it just like a database of records (only one record for each service) and multiple services from multiple accounts would apply to the one serviceRules record?
If the answer is the latter, as I have a database of the records already, which the service object lookups to autofill fields. Could I add the service rules to each record there. Then when I add the service, it not only accesses the information of the service, but the rules aswell.
Thank you for your time
Thank you so much for your help
I have tried to implement the code, I have changed it a bit as I do not need the Account_Status__c date field check if I already have the maximumcount field.
I keep default information on all my services in an object called destiny_Products_and_services__c. Basically, when a user adds a service to the account, they click new service - and pickthe service from a picklist (using a trigger the picklist autofills a lookup to destiny_Products_and_services__c which in turn autofills formula fields. I have added the maximumCount field to the destiny_Products_and_services__c object for every record and upon saving I got this error:
Error: Compile Error: unexpected token: '{' at line 35 column 55
This is the code after slightly changing it:
Error Error: Compile Error: Incompatible key type Object for MAP<String,MAP<String,Decimal>> at line 26 column 7
To answer your other questions, no it would not be difficult to add other requirements to this validation. The actual test of the business rule in this case is this section
You could simply insert additional tests immediately following this. Just be sure to include the additional business rule fields from Destiny_Products_and_Services__c in the initial query.
This is the error:
rror: Compile Error: Initial term of field expression must be a concrete SObject: Boolean at line 37 column 121.
Thank you so much for your reply and continued correspondence.
Obviously it is one step at a time and I am focused on deploying this current, brlliant trigger. But, on the topic of further validation. Hypothetically, would it be a possibility of say adding a text field which lists required services to be completed before adding a certain service or is that not possible?
Sorry to write back again, but the way I see it is. The less of your time I waste the better. So I am constantly just trying things to see if it will solve things. I hope it does not detriment your code, but I changed the call on line 37 column 121 from
mapServiceRules.containsKey(objService.Name).MaximumRecords__c
to
mapServiceRules.get(objService.Name).MaximumRecords__c
It allowed me to save, however upon testing the rule I received this error:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger ServiceValidation2 caused an unexpected exception, contact your administrator: ServiceValidation2: execution of BeforeInsert caused by: System.UnexpectedException: field 'Name' can not be grouped in a query call: Trigger.ServiceValidation2: line 19, column 1
Therefore, as destiny_products_and_services__c has the fields service_name__c and service_type__c in order to make the records unique and to supply the ability to SOQL request them in a trigger which sets the lookup via the two picklist choices I attempted swapping name for service_name__c, but received this error:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger ServiceValidation2 caused an unexpected exception, contact your administrator: ServiceValidation2: execution of BeforeInsert caused by: System.SObjectException: Invalid field Name for AggregateResult: Trigger.ServiceValidation2: line 28, column 1
I changed all the mentions of name to service_name__c and it started working.
It works to the point where it prevents me from adding two services with the same service_name__c. Is there any way to make it run off the exact service. Whether it be through name or service_name__c and service_type__c?
Thank you sooo much for your time. I appreciate it to no end.
Excuse the constantly changing problems and errors, I left this open as I was trying random things and it eventually worked. Like I said, I would have thought that it wold be best to waste as little time as possible of yours.
Thank you,
Mikie
When you say the 'exact service' are you saying that it's the combination of service_name__c and service_type__c that identifies a unique record?
and as such all formula fields are also filled. So there may be 4 records with service_name__c = Advantage program (in destiny_products_and_services__c), each one of these records will have a different service_type__c (e.g. New client, Upgrade EPE, etc).....then the record name will appear as Advantage program (new client).
So, from account a user will select service_name__c ='Advantage Program' and service_type__c =' New client' and the trigger will select from object 'destiny_products_and_services__c' ----- Advantage Program (Newclient) and there fore all formula fields such as price and inclusions, etc will be added to relevent formula fields.
Thank you for your time.