Apex Trigger for Custom Validation in Salesforce

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. It’s lookup field name as “Quote__c”. On 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 to run before records get inserted (before insert).
  2. For each Payment__c record in the batch will insert and checks 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 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, we learned how to write an Apex Trigger for Custom Validation in this blog post.

Scroll to Top