You need to sign in to do that
Don't have an account?
Palmira Angelova
Field Integrity Exception / rogue validation rule is firing??
Hi friends,
I feel kind of silly posting this, but here goes. In our org, Orders are created on Opportunities and have a start and end date. Orders must also be associated with Contracts, which also have a start and end date. Pretty standard stuff.
Recently, Date = Today surpassed the Contract End Date for one of our contracts (this is ok and was designed this way - the continuation of the contract is actually recorded in a new "renewal" Opportunity that is tied to the originating Opportunity and the original Contract. We're attempting to create an order on the associated (renewal) Opportunity but getting the following error: "Malformed request https://na34.salesforce.com/services/data/v38.0/sobjects/Order/. Response content: [{'fields': ['EffectiveDate'], 'message': "Order Start Date can't be later than its contract's end date.: Order Start Date", 'errorCode': 'FIELD_INTEGRITY_EXCEPTION'"
This totally looks like a custom validation or error message to me (but please correct me if I'm wrong?? Maybe there's a chance Salesforce built in validation rules for these Standard Salesforce fields and that's what I'm missing here?), but the weird thing is that I can't find mention of the "Order Start Date can't be later than its contract's end date" error ANYWHERE in the org. I've combed through every line of code and validation rule like 3 times and it's nowhere to be found. Is there some other obscure way to create data validation that I'm not aware of?
Or any other ideas that could point me in the right direction? I need to find the culprit and disable / modify this rule. Thanks so much!
I feel kind of silly posting this, but here goes. In our org, Orders are created on Opportunities and have a start and end date. Orders must also be associated with Contracts, which also have a start and end date. Pretty standard stuff.
Recently, Date = Today surpassed the Contract End Date for one of our contracts (this is ok and was designed this way - the continuation of the contract is actually recorded in a new "renewal" Opportunity that is tied to the originating Opportunity and the original Contract. We're attempting to create an order on the associated (renewal) Opportunity but getting the following error: "Malformed request https://na34.salesforce.com/services/data/v38.0/sobjects/Order/. Response content: [{'fields': ['EffectiveDate'], 'message': "Order Start Date can't be later than its contract's end date.: Order Start Date", 'errorCode': 'FIELD_INTEGRITY_EXCEPTION'"
This totally looks like a custom validation or error message to me (but please correct me if I'm wrong?? Maybe there's a chance Salesforce built in validation rules for these Standard Salesforce fields and that's what I'm missing here?), but the weird thing is that I can't find mention of the "Order Start Date can't be later than its contract's end date" error ANYWHERE in the org. I've combed through every line of code and validation rule like 3 times and it's nowhere to be found. Is there some other obscure way to create data validation that I'm not aware of?
Or any other ideas that could point me in the right direction? I need to find the culprit and disable / modify this rule. Thanks so much!
You are correct that the Trigger has no role to play in the validation. This is a standard validation enforced by Salesforce to ensure data integrity between Orders and their associated with Contracts. Although I am surprised that the standard Salesforce documentation has nothing mentioning about this!
Just to verify this behaviour, I created a Contract and attempted creating an Order whose Start and End Dates do not comply with the Start and End Date ranges for the associated Contract and I recieved the same error. Also, my org does not have any custom validations or triggers written on it. The snapshot below showcases the error.
Additionally, there is workaround to your situation.
This may help you move forward.
All Answers
- You may want to check the format for the date value that is being set for the Order Start Date (EffectiveDate) field, complies with the date formats permissible within Salesforce. Refer the following url to udnerstand the list of acceptable date formats within Salesforce - https://help.salesforce.com/articleView?id=supported_data_types.htm&type=5
- Also, it seems from the error message, that the Order's start date should go beyond the end date of the associated Contract. Though I do not see anything explicitly specified around this validation in the documentation, I believe you may want to try creating a new Contract and create an Order in association with that.
- Contract End Date on Order is a read only field is calculated on Contracts by adding the ContractTerm to the StartDate. Refer the following url for the complete list of Order fields - https://help.salesforce.com/articleView?id=order_fields.htm&type=5
- Morevoer, are you attempting to create Orders and then attempting to activate them? Orders have a Status field which is a picklist on them which could have one of the either values
- Draft
- Activated
- I would recommend creating a Draft Order first and then Activating it. Please ensure your User has the following permissions for activating an Order which is in Draft mode.
- Activate Order.
- Edit Activated Orders
Hope this helps.Thanks for your answer and ideas!
- Good idea, but we're just using the standard Salesforce field via the front end UI, so there's no way to get it wrong. The date formats are compatible and we are able to save orders on every other opportunity except the one where today's date is later than the contract end date
- I have not found anything about this kind of standard validation either, and it would also be strange for Salesforce to enforce cross-object validation by default, which is why I was thinking that someone else built this into our instance and perhaps I'm just not looking in the right places. Seems like a pointless question but is there anywhere else I should look besides Apex classes/triggers and validation rules? Unfortunately, creating a new contract for each of these is not an ideal flow for our organization, which is why I'm trying to just locate the validation and turn it off or modify it
- Yep, and this is being calculated as expected. It's just that the validation based off this field was something we were not expecting and it's causing problems
- We leave all Orders as drafts / don't need or use the concept of Order activation in our org, so this part is not relevant.
What do you think are the chances that this is validation Salesforce enforces? Is there anywhere else in the admin panel that I should search for the culprit?You can check for the following.
- Custom Validation Rules on Order / Contract
- Apex Triggers on Order / Contract
- Duplicate Rules
I would recommend you use the Debug Logs to investigate and identify the exact reason which causes the exception to be raised. This will give you a better handle to understand the cause of the validation.Hi Jigarshah,
Thank you for the suggestions again. This is what I was indeed thinking as well. Feedback below:
Please let me know your thoughts on the additional information I provided regarding the Order Trigger and Debug logs.
The Order Trigger is below. Thank you very much again for your help!
public class OrderTriggerHelper {
public static void handleAfterInsert(List<Order> OrderLst){
List<Opportunity> Opplst =new List<Opportunity>();
List<Id> Oppids =new List<Id>();
Map<Id,Id> oMap=new Map<Id,Id>();
List<Order> orlst=new List<Order>();
List<Id> contractids=new List<Id>();
List<OpportunityLineItem> opitemlst=new List<OpportunityLineItem>();
for(Order ord:OrderLst){
if(ord.OpportunityId!=null){
Oppids.add(ord.OpportunityId);
contractids.add(ord.contractId);
}
}
Map<Id,String> opptyTypeMap=new Map<Id,String>();
Map<Id,Id> OpptyContractMap=new Map<Id,Id>();
Map<Id,List<Order>> OpptyOrderMap=new Map<Id,List<Order>>();
List<Order> Olst=[SELECT Id,ContractId,OpportunityId,Opportunity.ContractId,Opportunity.Type,Opportunity.Primary_Opportunity__c,
Opportunity.Product_Schedules_Calculation__c,Primary_Order__c,Type from Order
where (OpportunityId in:Oppids or Opportunity.Primary_Opportunity__c in:Oppids)];
for(Order ord:Olst){
if(ord.Opportunity.Primary_Opportunity__c!=null && ord.Opportunity.Type=='Renewal')
oMap.put(ord.Opportunity.Primary_Opportunity__c,ord.OpportunityId);
List<order> templst =new List<Order>();
if(OpptyOrderMap.containsKey(ord.OpportunityId)){
OpptyOrderMap.get(ord.OpportunityId).add(ord);
} else{
OpptyOrderMap.put(ord.OpportunityId,new List<Order>());
}
opptyTypeMap.put(ord.OpportunityId,ord.Opportunity.Type);
OpptyContractMap.put(ord.OpportunityId,ord.Opportunity.ContractId);
}
system.debug('oMap==>'+oMap);
system.debug('OpptyOrderMap==>'+OpptyOrderMap);
for(Order ord:OrderLst){
system.debug('ord.Id===>'+ord.Id);
if(!oMap.isEmpty() && oMap.get(ord.OpportunityId)!=null){
Order neworder = new Order();
neworder.Primary_Order__c= ord.id;
neworder.AccountId=ord.AccountId;
neworder.EffectiveDate=ord.EffectiveDate;
neworder.Type=ord.Type;
neworder.Pricebook2Id=ord.Pricebook2Id;
neworder.OpportunityId=oMap.get(ord.OpportunityId);
neworder.Status='Draft';
neworder.ContractId=ord.ContractId;
neworder.type='Renewal';
orlst.add(neworder);
}
//system.debug('OpptyOrderMap.get(ord.OpportunityId).Opportunity.Type'+OpptyOrderMap.get(ord.OpportunityId).Opportunity.Type);
Opportunity oppty=new Opportunity(Id=ord.OpportunityId);
if(OpptyContractMap.get(ord.contractId)==null )
oppty.contractId=ord.contractId;
if(OpptyOrderMap.get(ord.OpportunityId).size()==0 && opptyTypeMap.get(ord.OpportunityId)!='Renewal'){
oppty.StageName='6 - Deployed';
oppty.Renewal_Start_Date__c =System.today();
}
Opplst.add(oppty);
}
system.debug('orderlst===>'+orderlst);
if(Opplst.size()>0){
try{
system.debug('Opplst==>'+Opplst);
update Opplst;
}catch(DmlException ex){
system.debug('Error on Update'+ex);
}
}
if(orlst.size()>0){
try{
system.debug('orlst==>'+orlst);
insert orlst;
}catch(DmlException ex){
system.debug('Error on Update'+ex);
}
}
}
}
You can get to the trigger by by navigating to Setup > Apex Triggers within your Salesforce instance.
Also, please check if the respective Apex Trigger on Order is Active.
Sure, I didn't share this because there's not much going on here besides the After Insert. Order Trigger is below. Yes, this Trigger is Active
trigger OrderTrigger on Order (after insert) {
if(trigger.isAfter && trigger.isInsert){
OrderTriggerHelper.handleAfterInsert(trigger.new);
}
}
This user seems to have a related validation rule that fired and it doesn't sound like his org created it either. https://developer.salesforce.com/forums/?id=9060G000000UbagQAC
Thanks again for your help and let me know your thoughts on the above.
You are correct that the Trigger has no role to play in the validation. This is a standard validation enforced by Salesforce to ensure data integrity between Orders and their associated with Contracts. Although I am surprised that the standard Salesforce documentation has nothing mentioning about this!
Just to verify this behaviour, I created a Contract and attempted creating an Order whose Start and End Dates do not comply with the Start and End Date ranges for the associated Contract and I recieved the same error. Also, my org does not have any custom validations or triggers written on it. The snapshot below showcases the error.
Additionally, there is workaround to your situation.
This may help you move forward.
The workaround is really helpful as well, I wouldn't have known about this setting / option. Thank you! I'll move forward with this solution : )