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
Palmira AngelovaPalmira 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!
Best Answer chosen by Palmira Angelova
jigarshahjigarshah
Palmira,

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.
Order Field Integrity Exception


Additionally, there is workaround to your situation.
  • Within Setup > Contract Settings uncheck the checkbox for Auto calculate Contract End Date. This will provide you with the ability to manually set the End Date for every Contract and the end dates will NOT be automatically calculated based on the Contract Term.
Contract Settings
This may help you move forward.

All Answers

jigarshahjigarshah
Palmira,
  • 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.
Palmira AngelovaPalmira Angelova
Hi Jigarshah,

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? 
jigarshahjigarshah
Palmira,

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.
Palmira AngelovaPalmira Angelova

Hi Jigarshah,
Thank you for the suggestions again. This is what I was indeed thinking as well. Feedback below:

  • There are no validation rules for the Order or Contract objects in our org
  • There are no relevant duplicate rules that would affect orders (we only have these in place affecting Lead and Contact Objects)
  • Yes, the first thing I did was check Triggers. There are no triggers on Contracts, but there is one Trigger for Order. I am somewhat new to Salesforce development, but as far as I can tell there is nothing in this trigger that specifies the "Order Start Date can't be later than its contract's end date.: Order Start Date" error. No adderror function or anything similar. There are only two mentions of error in the Trigger (they are at the bottom as part of a try function), but neither of them has to do with the Contract End Date field. 
I have pasted the Trigger below, perhaps there is something you are able to see that I have missed? If there is indeed something I have missed due to being a novice developer, I do apologize. 
  • I checked the debug logs as well, thank you for this tip! They did not yield any useful information (even with the most detailed settings for Debug Levels, there is no debug line item being recorded for the Order Trigger. This kind of makes sense because the Order Trigger fires on After Insert, and the validation rule is preventing the record from being saved altogether, and therefore the Order Trigger is never triggered.)

Please let me know your thoughts on the additional information I provided regarding the Order Trigger and Debug logs. 

Palmira AngelovaPalmira Angelova

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);
       }  
     }
  }
    
}

jigarshahjigarshah
Palmira, I will have a look at this code. Meanwhile, can you also share the code for an Apex Trigger on the Order object. The code that you have shared would be invoked from the Apex Trigger.

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.
Palmira AngelovaPalmira Angelova
Thanks Jigarshah.

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);
    }
      
}
Palmira AngelovaPalmira Angelova
I'm pretty confident that this trigger is not relevant, and given that there are no validation rules created in the admin panel for this, I'm starting to think that (despite what Salesforce support told me and the fact that I can find no documentation on it) this is a standard Salesforce rule that admins can not remove :\  Is there a way to know for sure if this is the case? 

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. 
jigarshahjigarshah
Palmira,

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.
Order Field Integrity Exception


Additionally, there is workaround to your situation.
  • Within Setup > Contract Settings uncheck the checkbox for Auto calculate Contract End Date. This will provide you with the ability to manually set the End Date for every Contract and the end dates will NOT be automatically calculated based on the Contract Term.
Contract Settings
This may help you move forward.
This was selected as the best answer
Palmira AngelovaPalmira Angelova
Thanks you Jigarshah! I am glad to know I wasn't going crazy..

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 : )
jigarshahjigarshah
Palmira, I am glad I could help.