+ Start a Discussion
WikWik 

Trigger for a Validation

Hi,
I have a Custom Object named preferred rate. It is related to the account in a Master detail relation ship with the account being the Master.

There are two record types in Account named Customer and SIte with the Customer Record type being the Parent of the Site Account record type. A Preferred Rate record can be created on Customer as well as Site account.

I am looking for a validation rule such that When the Expiration Date entered on the Preferred Rate record on Site Account is greater than that on the Customer Account, it should throw an error.
The Site Account record type is the child of the Customer Record Type.
Best Answer chosen by Wik
ShashForceShashForce
Hi,

I have modified the trigger, tested it in my test org as well. It is working perfectly now.

trigger ExpirationDateValidator on Preferred_Rate__c (before insert, before update) {
    set<Id> accIds = new set<Id>();
    set<Id> parentIds = new set<Id>();
    for(preferred_rate__c p:trigger.new){
        accIds.add(p.account__c);
    }
    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012900000015ct7']); //add Site record type Id here.
    for(account a:parentAccmap.values()){
        parentIds.add(a.parentId);
    }
    map<Id,preferred_rate__c> parentPrMap = new map<Id,preferred_rate__c>();
    list<preferred_rate__c> prParentlist = [select expiration_date__c, account__c, account__r.recordtypeId from preferred_rate__c where account__c IN :parentIds and account__r.recordtypeId='012900000015REy']; //add Customer record type Id here.
    for(preferred_rate__c pr:prParentlist){
        parentPrMap.put(pr.account__c, pr);
    }
    for(preferred_rate__c prr:trigger.new){
        if(prr.expiration_date__c!=null && parentAccmap.containsKey(prr.account__c) && parentPrMap.containsKey(parentAccmap.get(prr.account__c).ParentId)){
            if(prr.expiration_date__c > parentPrMap.get(parentAccmap.get(prr.account__c).ParentId).expiration_date__c){
                prr.addError('Expiration Date cannot be greater than the expiration date on the Parent Customer account preferred rate expiration date');
            }
        }
    }
}

If you want the validation error to appear under the field instead of on the top of the page, replace prr.addError with prr.expiration_date__c.addError

If this answers your question, please mark this as the Best Answer for this post, so that others can benefit from this post.

Thanks,
Shashank

All Answers

Ramu_SFDCRamu_SFDC
Can you plz help me out with the below questions

1. Does the expiration date field exist ONLY on Preferred rate object or does that also exist on Account?
2. As per your question I assume that you would like to check the expiration date entered on preferred rate record related to site if greater than expiration date entered on preferred rate record related to customer then throw an error? or is it that expiration date on preferred rate related to site greater than customer account expiration date? please confirm
WikWik
Yes the xpiration date fiels exists only on Preferred Rate Object

I would like to check the expiration date entered on preferred rate record related to site if greater than expiration date entered on preferred rate record related to customer then throw an error
ShashForceShashForce
Hi,

This should help. Please note that this will work only if there is only one preferred rate record on the parent customer record type account.

trigger ExpirationDateValidator on Preferred_Rate__c (after insert, after update) {
    set<Id> accIds = new set<Id>();
    set<Id> parentIds = new set<Id>();
    for(preferred_rate__c p:trigger.new){
        accIds.add(p.account__c);
    }
    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId from account where Id IN :accIds]);
    for(account a:parentAccmap.values()){
        parentIds.add(a.parentId);
    }
    map<Id,preferred_rate__c> parentPrMap = new map<Id,preferred_rate__c>();
    list<preferred_rate__c> prParentlist = [select expiration_date__c, account__c, account__r.recordtypeId from preferred_rate__c where account__c IN :parentIds and account__r.recordtypeId='012900000015REy']; //add Customer record type Id here.
    for(preferred_rate__c pr:prParentlist){
        parentPrMap.put(pr.account__c, pr);
    }
    for(preferred_rate__c prr:trigger.new){
        if(prr.expiration_date__c!=null){
            if(prr.expiration_date__c > parentPrMap.get(parentAccmap.get(prr.account__c).Id).expiration_date__c){
                prr.addError('Expiration Date cannot be greater than the expiration date on the Parent Customer account preferred rate expiration date');
            }
        }
    }
}

If this answers your question, please mark this as the Best Answer for this post, so that others can benefit from this post.

Thanks,
Shashank
WikWik

Thanks shashank

Apex trigger ExpirationDateValidator caused an unexpected exception, contact your administrator: ExpirationDateValidator: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.ExpirationDateValidator: line 18, column 1

getting the above error while creating a new record

ShashForceShashForce
Please try replacing

if(prr.expiration_date__c!=null){

with

if(prr.expiration_date__c!=null && prr.account__c!=null){

Also, please ensure that you are modifying the object names and field names as per your setup.
WikWik

I did modify as per my setup

the same error persists even after the modification suggested by you

ShashForceShashForce
Hi,

I have modified the trigger, tested it in my test org as well. It is working perfectly now.

trigger ExpirationDateValidator on Preferred_Rate__c (before insert, before update) {
    set<Id> accIds = new set<Id>();
    set<Id> parentIds = new set<Id>();
    for(preferred_rate__c p:trigger.new){
        accIds.add(p.account__c);
    }
    map<Id,account> parentAccmap = new map<Id,account>([select Id,parentId,recordtypeId from account where Id IN :accIds and parentId!=NULL and recordtypeId='012900000015ct7']); //add Site record type Id here.
    for(account a:parentAccmap.values()){
        parentIds.add(a.parentId);
    }
    map<Id,preferred_rate__c> parentPrMap = new map<Id,preferred_rate__c>();
    list<preferred_rate__c> prParentlist = [select expiration_date__c, account__c, account__r.recordtypeId from preferred_rate__c where account__c IN :parentIds and account__r.recordtypeId='012900000015REy']; //add Customer record type Id here.
    for(preferred_rate__c pr:prParentlist){
        parentPrMap.put(pr.account__c, pr);
    }
    for(preferred_rate__c prr:trigger.new){
        if(prr.expiration_date__c!=null && parentAccmap.containsKey(prr.account__c) && parentPrMap.containsKey(parentAccmap.get(prr.account__c).ParentId)){
            if(prr.expiration_date__c > parentPrMap.get(parentAccmap.get(prr.account__c).ParentId).expiration_date__c){
                prr.addError('Expiration Date cannot be greater than the expiration date on the Parent Customer account preferred rate expiration date');
            }
        }
    }
}

If you want the validation error to appear under the field instead of on the top of the page, replace prr.addError with prr.expiration_date__c.addError

If this answers your question, please mark this as the Best Answer for this post, so that others can benefit from this post.

Thanks,
Shashank
This was selected as the best answer
WikWik
Thanx  a ton shashank. 
Can you guide me with the test class
ShashForceShashForce
I would recommend you to try it out yourself and let me know if you have any specific questions/issues. Here is where you can start: https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods