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
Deanna Aaron 11Deanna Aaron 11 

Error related to validation rule?

Hi. I created a validation rule that WORKS, but it appears to be causing an error in another area in Salesforce.
The validation rule:
Basically, if a donation (opportunity record) is entered, the “classification” multi-picklist field must CONTAIN more than 1 value if “Anonymous” is selected. (Hooray, it works!)
Because we’re a nonprofit, we enabled the native “matching gift” functionality. When trying to match gifts, the validation rule error appears.
I looked at 2 individual donations (opportunity records) and BOTH contain “anonymous AND individual”. They follow the validation rule criteria. When I look at the URL of the “Matching Gift” page, it contains…

visual.force.com/apex/

Which makes me think this has something to due with Visualforce or Apex? I’m not sure what to look at to fix this error altogether.
Thank you for your help!
 
Validation Rule for Reference:
AND( 
NOT(INCLUDES(Donation_Classification__c,"Corporate")), 
NOT(INCLUDES(Donation_Classification__c,"Foundation")), 
NOT(INCLUDES(Donation_Classification__c,"In-Direct Public Support")), 
NOT(INCLUDES(Donation_Classification__c,"Band Fees")), 
NOT(INCLUDES(Donation_Classification__c,"In-Kind Donations")), 
NOT(INCLUDES(Donation_Classification__c,"Board Contribution")), 
NOT(INCLUDES(Donation_Classification__c,"Individual")), 
INCLUDES(Donation_Classification__c,"Anonymous") 

Error Message: The "Donation Classification" must contain an additional selection. Example: Anonymous AND Individual

REPLY FROM SUCCESS COMMUNITY:

The reason Apex appear in the URL is because the Salesforce non-profit pack is not actually native functionality in the system - it is an application incorporated into Salesforce. All custom Visualforce pages have /apex/ in the URL.

With that being said, it is also the reason I doubt anyone here could help resolve the issue. This page likely tries to create a new record that breaks your validation, and seeing as it is impossible to modify (or even examine) it's code, we can't tell whether the page inserts some sort of value we can use to make the validation rule ignore operations from this page.

It may be possible to write a Before Insert Apex trigger that identifies the page the user is on, and fill in some field to make the validation rule skip it.

Thank you for your help!

Steven NsubugaSteven Nsubuga
Yes, a before trigger would solve the issue by examining each incoming record and supplying a second option if one were required.
I am sure folks here myself included can help you write such a trigger.
Steven NsubugaSteven Nsubuga
Something like this would work.

Trigger
trigger updateDonationClassification on Opportunity (before insert, before update) {
	
	for(Opportunity o : trigger.new){
		if(o.Donation_Classification__c.contains('Anonymous') &&
			!o.Donation_Classification__c.contains('Corporate') &&
			!o.Donation_Classification__c.contains('In-Direct Public Support') &&
			!o.Donation_Classification__c.contains('Band Fees') &&
			!o.Donation_Classification__c.contains('Foundation') &&
			!o.Donation_Classification__c.contains('Board Contribution') &&
			!o.Donation_Classification__c.contains('Individual') &&
			!o.Donation_Classification__c.contains('In-Kind Donations')) {                
                o.Donation_Classification__c = 'Anonymous;Individual';
		}
	}
}

Test class
@isTest
private class updateDonationClassificationTest {
	
	@isTest static void testTrigger() {
		
		Account testAccount = new Account(Name='Test Account');
        insert testAccount;
		
		Opportunity testOpportunity = new Opportunity(
            Name = 'Test Opportunity',
			AccountId = testAccount.Id,
			Donation_Classification__c = 'Anonymous',
            CloseDate = date.today().addDays(45),         
            StageName = 'Negotiating'
        );
		insert testOpportunity;

		Opportunity testOpp = [SELECT Donation_Classification__c from Opportunity where Id =:testOpportunity.Id LIMIT 1];
		System.assert(testOpp.Donation_Classification__c.contains('Anonymous'));
		System.assert(testOpp.Donation_Classification__c.contains('Individual'));
	}
}

 
Deanna Aaron 11Deanna Aaron 11
Thank you, Steven! Unfortunately, this issue is occuring with ALL record validation rules (on th opportunity object). Are you indicating that I need to create triggers everytime we create a validation rule? I'm also confused because BOTH opportunity records follow the validation rule criteria and it still triggers an errror on the gift matching page. I don't understand how the before trigger will resolve this?
Raj VakatiRaj Vakati
You can do it with workflow or orocess builder i guess .. no need of the trigger .. 

Cratete a worflow rule or process builder with rule entry and field update ...
Deanna Aaron 11Deanna Aaron 11
Thank you, Raj. My validation rule is simple. It won't allow an opportunity record to save IF the only value selected for the classification multi-picklist field is "Anonymous". IF a user makes this mistake, the error appears on the record and prevents it from saving. How would I recreate this with a workflow rule or process update? I'm not trying to do a field update.
Raj VakatiRaj Vakati
my mistake   Deanna Aaron 11..   


 
monsterloomismonsterloomis
Hi Deanna, what Steven and the community contributor are suggesting is that for whatever reason, the code behind that page is attempting to insert a record that violates that rule. While the original record shows the values there when you inspect them, at the moment of that insert - the validation rule is violated. My guess would be that it's cloning the opportunity using custom Apex, and the controller (code) behind the page doesn't have access to that field because it isn't specifically querying it. If a record is retrieved that way, it only attempts to clone the record based on the retrieved values, not on every field value of the record. A "before" trigger could fix that IF (to your point), you could always alter it to stay ahead of the validation rules with fixed values. 

Since you can't: is there any field set, custom setting, or custom metadata that lets you define the fields that appear in that matching gift UI? (Sorry, not terribly familiar with the nonprofit kit). Adding your custom field to that configuration MIGHT enable the controller for the page to see your field value and insert a valid cloned record.
Deanna Aaron 11Deanna Aaron 11
Thank you for your reply, Dave. I appreciate how thorough your answer is. It's not a proper page with a page layout. On the opportunity record, a user clicks a button that says "find matching gift". And it opens this page (see below). You'll notice that the page contains the validation rule error because a user tried to match the opportunity in this example. Both opportunity records that are being referenced in this process follow the validation rule criteria, so I'm puzzled as to why this is happening?User-added image
monsterloomismonsterloomis
Hmm... I know from your earlier comments that it's not a standard page ("/apex/etc") - but it's a common practice for the contents of that kind of table to be configurable. Is that UI static - meaning the columns have no configurability? If you're not positive, it might be worth checking any documentation to see if there is a way to change that. If you could get your multiselect field - and any others that feature in your validation rules - to display in this page as table columns in that list of opportunities, there's a decent chance that you'd be able to get this working. (Full disclosure: it doesn't make sense to me that "match" would cause the insert that is clearly creating this error.)

Still, I'd guess that's your best bet. If you have no control over that page - even the columns - I'm not sure what I would suggest next, except to raise it with Salesforce. One thing I'll say: if you can't configure this such that you can create a validation rule, the feature isn't written using best practices for defensive coding (meaning: it's too easy to break via very reasonable extension/configuration, so it's worth raising the issue).