Skip to main content

Salesforce

Apex Trigger for Custom Validation in Salesforce

Closeup Of Program Developer Writing Software On Multiple Computer Screens At Home Office

Hello, Trailblazers. In this blog post, we will learn how to write an Apex Trigger for Custom Validations.

Acceptance Criteria:  Write an Apex Trigger to restrict the Payment until the Final Quote is “Approved”.

To solve this, we have custom objects named Payment__c and Final_Quote__c in a lookup relationship with each other. Its lookup field name is “Quote__c”. On the Final_Quote__c object, there is a custom picklist field named Status__c. If the quote’s status is not “Approved”, then the user should not make payment.

So, let’s get started…

Apex Trigger for Custom Validation:

trigger paymentRestrictionTrigger on Payment__c (before insert, after insert) {

    if(trigger.isInsert && trigger.isBefore){
       
        for(Payment__c pay : trigger.new){
            if(pay. Quote__c!= null){
                Final_Quote__c quo = [SELECT Id, Status__c FROM Final_Quote__c WHERE Id = :pay. Quote__c];
                if(quo.Status__c != 'APPROVED'){
                    pay.addError('You can not create payment, because this Quote is not Approved yet.  Thank You !!');
                }
            }
        }
    }
}

In this example:

  1. We defined the trigger on the Payment__c object and set it to run before records get inserted (before insert).
  2. Each Payment__c record in the batch will be inserted and checked if the Quote__c field on the Payment__c record is not null.
  3. After this, it fetches the Final_Quote__c records related to the Payment__c records with the help of SOQL query.
  4. It checks whether the quote’s status is “Approved” or not. If not, it throws an error.

Test Class for Apex Trigger:

Let’s write a test class for the above Apex Trigger. In this test class, we’ll cover both positive and negative scenarios.

@isTest
public class PaymentRestrictionTriggerTest {

    @isTest
    static void testPaymentCreationNotAllowed() {
        // Create a test Final Quote with a non-approved status
        Final_Quote__c testQuote = new Final_Quote__c(Status__c = 'Pending');
        insert testQuote;

        // Create a test Payment related to the non-approved Final Quote
        Payment__c testPayment = new Payment__c(Quote__c = testQuote.Id);
        
        Test.startTest();

        try {
            // Insert the Payment
            insert testPayment;

            // If the trigger logic is correct, the payment insert should throw an exception
            System.assert(false, 'Exception should have been thrown');
        } catch (Exception e) {
            // Ensure that the expected exception message is thrown
            System.assertEquals('You can not create payment, because this Quote is not Approved yet.  Thank You !!', e.getMessage());
        }

        Test.stopTest();
    }

    @isTest
    static void testPaymentCreationAllowed() {
        // Create a test Final Quote with an approved status
        Final_Quote__c testQuote = new Final_Quote__c(Status__c = 'APPROVED');
        insert testQuote;

        // Create a test Payment related to the approved Final Quote
        Payment__c testPayment = new Payment__c(Quote__c = testQuote.Id);

        Test.startTest();

        try {
            // Insert the Payment
            insert testPayment;

            // If the trigger logic is correct, no exception should be thrown
            System.assert(true, 'No exception should have been thrown');
        } catch (Exception e) {
            // If an exception is thrown, fail the test
            System.assert(false, 'Unexpected exception: ' + e.getMessage());
        }

        Test.stopTest();
    }
}

The above test class covers two scenarios:

  1. testPaymentCreationNotAllowed: It tests that attempting to create a Payment__c record related to a non-approved Final_Quote__c record will throw the expected exception.
  2. testPaymentCreationAllowed: It tests that creating a Payment__c record related to an approved Final_Quote__c record will not throw any exceptions.

Conclusion:

Thus, this blog post taught us how to write an Apex Trigger for Custom Validation.

References:

  1. Batch Apex in Salesforce

  2. Asynchronous Apex in Salesforce

You can also read :

  1. An Introduction to Salesforce CPQ
  2. Salesforce CPQ and its Key Features
  3. Unlocking the Power of AI: Einstein for Developers
  4. Revolutionizing Customer Engagement: The Salesforce Einstein Chatbot

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Abhinav Masane

Abhinav Masane is an Associate Technical Consultant at Perficient based in Nagpur. He is a Salesforce Certified Associate and Developer. Abhinav is always keen to learn and explore new technologies.

More from this Author

Follow Us
TwitterLinkedinFacebookYoutubeInstagram