0

I'm converting all our validation rules to a trigger to free up a couple object references since we've reached the max. I seemed to have created the trigger okay, but now I'm having an issue of receiving an error (not related to what I should be seeing) when saving a case: Error: Invalid Data. Review all error messages below to correct your data.

code:

trigger CaseValidation on Case (before insert, before update) {
    for(Case c : trigger.new){
        if((c.Sub_Type__c == 'Account Transfer In' || c.Sub_Type__c == 'Journal' || c.Sub_Type__c == 'Deposit - ACH' || c.Sub_Type__c == 'Deposit - Check') && c.Funds_from_liquidating_last_60_days__c == '' && c.Status == 'Closed')
        {
            c.addError( 'For this type of case, "Funds from liquidating last 60 days" is a required field');
        }
        if((c.Sub_Type__c == 'Account Transfer In' || c.Sub_Type__c == 'Journal') && c.Funded_from_positions_trnsfr_in_kind__c == 'Yes' && c.Funded_from_a_Brokerage_Account__c == '')
        {
            c.addError( '"Funded from a commission based product" is a required field because the answer to "Funded from positions trnsfr in kind" is Yes');
        }
        if((c.Ad_Type__c == 'Blog Content' || c.Ad_Type__c== 'Website Content') && c.URL__c == '')
        {
            c.addError('For the Ad Type of "Blog Content" or "Website Content", the URL field is required');
        }
        if(c.Ad_Type__c == 'Other' && c.Ad_Type_Other__c == '')
        {
            c.addError('If the Ad Type of "Other" is selected, please describe it in the "Ad Type Other" field');
        }
        //Owner ID = Data Management Queue
        if(c.OwnerId == '00Gi00000021Cyf'&& c.Status != 'Pending Data Management Review*')
        {
            c.addError('Please update the status to "Pending Data Management Review*" and it will update the case to the data management team.');
        }
        if(c.Trades_Needed__c == True && c.Financial_Account__c == '')
        {
            c.addError('Cannot update the Trades Needed checkbox without a Financial Account.');
        }
        if(c.Cash_Needs_Amount__c > 0 && c.Explanation_for_Cash_Needs__c == '')
        {
            c.addError('If cash needs are greater than zero, the Trade Notes field must be filled in.');
        }
        if(c.Cash_Needs__c == 'Yes' && c.Cash_Needs_Amount__c == null)
        {
            c.addError('If Cash Needs = "Yes" then Cash Needs Amount and Explanation for Cash Needs is required.');
        }
        if(c.Type == 'New Account' && c.Cash_Needs__c == '')
        {
            c.addError('Cash Needs field is a required field for New Accounts');
        }
        if(c.Sub_Type__c == 'Trade Request' && c.Cash_Needs__c == '')
        {
            c.addError('For "Trade Request" case Sub-Types, "Cash Needs" feild is required.');
        }
        //Record Type = Cashiering
        if(c.RecordTypeId == '012i00000019qlt' && (c.Sub_Type__c == 'Deposit - Check' || c.Sub_Type__c == 'Account Transfer In' || c.Sub_Type__c == 'Deposit - ACH' || c.Sub_Type__c == 'Journal' || c.Sub_Type__c == 'Deposit - wire') && c.Funded_from_a_Brokerage_Account__c == '' && c.Status == 'Closed')
        {
            c.addError('For this type of case, "Funded from a Commission Based Product" is a required field.');
        }
        //Record Type = Cashiering
        if(c.RecordTypeId == '012i00000019qlt' && c.Sub_Type__c == 'Deposit - Check' && c.Check_Received_Date__c == null && c.Status == 'Closed')
        {
            c.addError('"Check Received Date" is required before you can save this record.');
        }
        //Record Type = Cashiering
        if(c.RecordTypeId =='012i00000019qlt' && (c.Sub_Type__c == 'Distribution-Qualified' || c.Sub_Type__c == 'Distribution-Non-Qualified') && c.Distribution_Amount__c == null)
        {
            c.addError('"Gross Distribution Amount" is required before you can save this record.');
        }
       if((c.Sub_Type__c == 'Account Transfer In' || c.Sub_Type__c == 'Journal') && c.Funded_from_positions_trnsfr_in_kind__c == '')
       {
           c.addError('For this type of Case, "Funded from positions trnsfr in kind" is a required field.');
       }
       if(c.Sub_Type__c == 'Change of Strategy' && (c.Strategy_1__c == '' || c.Reason_for_Strategy_Change__c == ''))
       {
           c.addError('If the Sub-Type of "Change in Strategy" is selected, the "Strategy" and "Reason for Strategy Change" fields are required.');
       }
       if(c.RecordTypeId == '012i00000019qlt' && c.Sub_Type__c == 'Deposit - Check' && c.Check_Submitted_Date__c == null && c.Status == 'Closed')
       {
           c.addError('When selecting "Deposit - Check" as a Sub-Type, the "Check Submitted Date" is a required field.');
       }
       if(c.Check_Received_Date__c > c.Check_Submitted_Date__c)
       {
           c.addError('"Check Received Date" must come after "Check Submitted Date".');
       }
       if(c.Ad_Type__c == 'Social Media Site Content' && c.Erado_Setup_Complete__c == '' && c.Cetera_Social_Media_Training_Complete__c == '')
       {
           c.addError('For Ad Type "Social Media Site Content", the "Erado Setup Complete" and "Cetera Social Media Training Complete" fields are required.');
       }
       if(c.Audience__c.contains('Other') && c.Audience_Other__c == '')
       {
           c.addError('if Audience is "other", the "Audience Other" field is required.');
       }
       if(c.Material_Distribution_Method__c.contains('Other') && c.Distribution_Other__c == '')
       {
           c.addError('Distribution Method contains "other", please specify using the "Distribution Other" field.');
       }
        //RecordType = New Account
       if(c.Status == 'Pending Data Management Review*' && c.RecordTypeId == '012i00000016TXa' && c.Data_Management_Notes__c == '' && c.From_Financial_Account__c != '')
       {
           c.addError('Please update the data management notes field with instructions for the Data Management Team.');
       }
       if(c.RecordTypeId == '012i00000019qlt' && c.Status == 'Closed' && 
           (
              (c.Sub_Type__c == 'Deposit - Check' || c.Sub_Type__c == 'Direct Business Deposit') && 
                (c.Remote_Deposit__c == '' 
                || c.Deposit_Amount__c == null 
                || c.Check_Received_Date__c == null
                || c.Contribution_Code__c == '' 
                || c.Check_Submitted_Date__c == null 
                || c.Check_Forwarded_To__c == '' 
                || c.Check_Number__c == '' 
                || c.How_Check_Was_Recieved__c == '' 
                || c.Check_Payable_To__c == ''
                )
                ||
                (c.Sub_Type__c == 'Deposit - Wire' &&
                (c.Remote_Deposit__c == '' 
                || c.Deposit_Amount__c == null 
                || c.Wire_Received_Date__c == null 
                || c.Contribution_Code__c == '')
              )
           )
         )
           c.addError('Complete the Deposit - Check/Wire section.');
       if(c.Sub_Type__c == 'Deposit - security' && c.Security_Submitted_To__c == '' && c.Tracking_Number__c == '' && c.Securities_Sent_Date__c == null && c.Status == 'Closed')
       {
           c.addError('Before closing this "Deposit - Securities" case, the following fields need to be filled out; "Security Submitted to", "Securities Sent Date" and "Tracking Number".');
       }
       if(c.Sub_Type__c == 'Deposit - Security' && c.Security_Received_Date__c == null && c.Security_Units__c == null)
       {
           c.addError('For the Sub-type Deposit-Security, "Security Received Date" and "Security Units" are required.');
       }
       if(c.Discontinued_use__c == True && c.Discontinued_Date__c == null)
       {
           c.addError('"Discontinuted Date" is required when "Discontinued Use" is selected.');
       }
        //Record Type = New Account
       if(c.RecordTypeId == '012i00000016TXa' && c.Status == 'Pending Data Management Review*' && c.From_Financial_Account__c == '')
       {
           c.addError('Cannot update status to "Pending Data Management Review" until "From Financial Account" field is filled out.');
       }
        if((c.AccountId == '001i0000017bNdv' || c.AccountId == '001i0000010P77f' || c.AccountId == '001i0000010P6zZ') && c.CIA_Partner__c == 'GAAM')
       {
           c.addError('"GAAM" cannot be selected as CIA Partner as it will allow everyone in GAAM to see it.');
       }
       if((c.Financial_Account__r.Business_Type__c == 'Advisory' && c.type != 'MANAGED VA - CWM') && c.CWM_Agreement__c == False && c.Status == 'Trades Needed')
       {
           c.addError('Our records show that a CWM Agreement has been received for this account.  In order for our Trading Department to trade on the account, we need to have it on file.  Please forward an executed copy to your CGP Service Team.');
       }
       if(c.Sub_Type__c == 'Morrocroft Capital Call' && c.Method_to_Deliver_Form_to_Client__c == '')
       {
           c.addError('"Method to Deliver form to Client" is required when the Sub-type is "Morrocroft Capital Call".');
       }
       if(c.Type == 'New Account' && c.Funded_from_positions_trnsfr_in_kind__c == '')
       {
           c.addError('"Funded from positions trnsfr in kind" is a required field for the New Account case type.');
       }
       if(c.Type == 'New Account' && c.Funds_from_liquidating_last_60_days__c == '')
       {
           c.addError('"Funds from liquidating last 60 days" is a required field for the New Account case type.');
       }  
       if(c.Type == 'New Account' && c.Funded_from_positions_trnsfr_in_kind__c == 'Yes' && c.Funded_from_a_Brokerage_Account__c == '')
       {
           c.addError('"Funded from a Commission Based Product" is required.');
       }
       if(c.Remote_Deposit__c == 'No' && c.Check_Forwarded_To__c == '')
       {
           c.addError('If Remote Deposit is No, then "Check Forwarded to" is required');
       }
       if(c.Funded_from_a_Brokerage_Account__c == 'Yes' && c.Commission_Product_s__c == '')
       {
           c.addError('If the account was funded from a Commission Based Product, please use the "Commission Product" field to indicate which type of products were used to fund the account.');
       }
       if(c.Funded_from_a_Brokerage_Account__c == 'Yes' && c.Funding_Details__c == '')
       {
          c.addError('If the account was funded from a Commission Based Product, please use the Funding Details field to provide information to compliance about the brokerage account.');
       }
       if(c.Funded_from_a_Brokerage_Account__c == 'Yes' && c.Commission_Amt_Collected_Last_2yrs__c == null)
       {
          c.addError('If the account was funded from a Commission Based Product, please update the "Commission Amt Collected Last 2 Yrs" field.');   
       }
       if(c.Funded_from_a_Brokerage_Account__c == 'Yes' && c.Selling_Rep__c == '')
       {
          c.addError('If "Funded from a Commission Based Product" is yes, then the "Selling Rep" field is required.');
       }
       if(c.Sub_Type__c == 'MODEL UPDATE' && c.Strategy_1__c == '')
       {
          c.addError('For the case Sub-Type "Model Update", the "Strategy" field is required.');
       }
       if(c.State__c == 'Trades Needed' && c.Financial_Account__c == '')
       {
          c.addError('The Financial Account is required when updating the status to "Trades Needed".');
       } 
       if(c.Status == 'Trades Needed' && c.Financial_Account__r.Business_Type__c == '')
       {
           c.addError('The account needs to be assigned to be an advisory account in the Business Type field.');
       }
       //Owner ID = Trading Queue
       if(c.OwnerId == '00Gi0000001JLiT' && c.Financial_Account__c == '')
       {
           c.addError('Financial Account is required before changing the owner to Trading');
       }
       //Owner ID = Trading Queue
       if(c.OwnerId == '00Gi0000001JLiT' && c.Status != 'Trades Needed')
       {
           c.addError('You cannot update the case owner to the Trading Team without using the status of "Trades Needed".');
       }
    }
}

Any help would be appreciated!

Apex trigger CaseValidation caused an unexpected exception, contact your administrator: CaseValidation: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: ()

1
  • 2
    It's hard to help without the line number but my guess is that the error comes from one of your line using the contains method. If the value is null, it will raise an exception. Before calling contains, you should check that your value is not null. Oct 30 '18 at 13:59
3

You have at least four main problems.

First, text fields coming from the database are always null, never "empty string". You'll need to fix all your =='' with ==null.

Second, relationship fields (__r) are not automatically populated, so you need to do queries to get the related records.

Third, your main problem, .contains(...) will throw the NullPointerException if the field is null, so check for null first.

Forth, c.Check_Received_Date__c > c.Check_Submitted_Date__c and c.Cash_Needs_Amount__c > 0 will return false if any field involved is null; check for null first to avoid potentially incorrect results.

Note: addError can only show one record-level error and one error per field. You should prefer the c.Ad_Type_Other__c.addError(...) over c.addError. This makes the UI more intuitive, since the field will be highlighted, and you can return multiple errors at once.

6
  • 2
    I think you meant c.Check_Received_Date__c > c.Check_Submitted_Date__c will throw NPE if the variable c is null. Because even if the values are null, the comparison itself will not throw a NPE.
    – Jayant Das
    Oct 30 '18 at 14:11
  • @JayantDas I think that's "new" behavior? Last time I checked, it threw a NPE. Granted, it appears to always return false, so that's still probably not the correct intent. Thanks for letting me know.
    – sfdcfox
    Oct 30 '18 at 14:13
  • I added: if(c.Audience__c != null && c.Audience__c.contains('Other') && c.Audience_Other__c == null) as well as: if(c.Material_Distribution_Method__c != null && c.Material_Distribution_Method__c.contains('Other') && c.Distribution_Other__c == null) as well as replaced all my empty strings with null, and it appears to have fixed it! Thank you! I have a separate issue regarding the test class, but I need to do a bit more research before posting that.
    – tDactyl
    Oct 30 '18 at 15:00
  • @TravisDvorak You're welcome! Always glad to help.
    – sfdcfox
    Oct 30 '18 at 15:44
  • Another issue I just ran into: when validation rules are used, it will show all the available errors on the page. With my trigger, it will show 1, then another when that error is fixed, then another if there's another, etc. Is there a way to list all available errors on the top of the page, rather than in order as they happen in the trigger?
    – tDactyl
    Oct 30 '18 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.