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:
- We defined the trigger on the Payment__c object and set to run before records get inserted (before insert).
- 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.
- After this, it fetches the Final_Quote__c records related to the Payment__c records with the help of SOQL query.
- 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:
- 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.
- 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.