+ Start a Discussion
Florin WFlorin W 

Apex Trigger to prevent child record to be saved

Hello Apex Masters!
 
I'm new on Apex and I'm trying to create a trigger that prevents Salesforce from saving child records.

Parent record: "Account"
Custom child record: "Budget" --> Fields: "Year"(picklist) and "Amount" (picklist, four values)

Conditions for saving related child records:

- Maximum of 3 "Budget" child records per related account and "Year" (e.g. "2016")
- Sum(Amount) of related "Budget" child records must be <= $500 per year

Can you help me with this?
It seems not to be working with validation rules.
AshlekhAshlekh
Hi,

First Thing - You have to write a trigger on Budget object.

When ever a Budget object record has been created than your trigger will fire and get the value of parent which is of Accont.

Now you have account Id, Find out all the child reocrds of Budget which are belong to this Account, And check the account is having how many budget records and put your condition.

-Thanks
Ashlekh Gera
Derhyk Doggett -Derhyk Doggett -

Hi Florin,
+1 to AKG's suggestions. I would also suggest throwing a nice to read error when the condition is met not to create another budget record so your users stay informed and know why it's preventing them from creating the record.
Information on adding errors can be found here:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm

-derhyk

Ravi Dutt SharmaRavi Dutt Sharma
Hey Florin,

You can try below code sample. Let me know if it works.
 
trigger BudgetTrigger on Budget__c(before insert, before update){
    
    Set<Id> accountIdSet = new Set<Id>();
    Set<String> yearSet = new Set<String>();
    for(Budget__c bud : Trigger.new){
        accountIdSet.add(bud.Account__c);
        yearSet.add(bud.Year__c);
    }
    
    List<Budget__c> budList = [SELECT Amount__c,Year__c,Account__c FROM Budget__c WHERE Account__c IN :accountIdSet AND Year__c IN:yearSet];
    
    // key - year , value is a map with key as account id and value as list of associated budget records
    Map<String,Map<Id,List<Budget__c>>> yearMap = new Map<String,Map<Id,List<Budget__c>>>();
    BudgetTriggerHelper.buildBudgetMap(budList,yearMap);
    BudgetTriggerHelper.checkForErrorConditions(Trigger.new,yearMap);
    
}
 
public class BudgetTriggerHelper {
    
    public static void buildBudgetMap(List<Budget__c> budList,Map<String,Map<Id,List<Budget__c>>> yearMap){
        for(Budget__c bud : budList){
            if(yearMap.containsKey(bud.Year__c)){
                Map<Id,List<Budget__c>> tempMap = yearMap.get(bud.Year__c);
                if(tempMap.containsKey(bud.Account__c)){
                    List<Budget__c> tempList = tempMap.get(bud.Account__c);
                    tempList.add(bud);
                    tempMap.put(bud.Account__c, tempList);
                }else{
                    List<Budget__c> tempList = new List<Budget__c>();
                    tempList.add(bud);
                    tempMap.put(bud.Account__c, tempList);
                }
                
            }else{
                Map<Id,List<Budget__c>> tempMap = new Map<Id,List<Budget__c>>();
                List<Budget__c> tempList = new List<Budget__c>();
                tempList.add(bud);
                tempMap.put(bud.Account__c, tempList);
                yearMap.put(bud.Year__c, tempMap);
            }
        }
    }
    
    public static void checkForErrorConditions(List<Budget__c> budList,Map<String,Map<Id,List<Budget__c>>> yearMap){
        for(Budget__c bud : budList){
            if(yearMap.containsKey(bud.Year__c)){
                Map<Id,List<Budget__c>> tempMap = yearMap.get(bud.Year__c);
                
                if(tempMap.containsKey(bud.Account__c)){
                    List<Budget__c> tempList = tempMap.get(bud.Account__c);
                    // check for 3 budget records per account
                    if(tempList.size() >=3){
                        bud.addError('Maximum of 3 Budget child records per related account and Year');
                    }
                    // check for sum >= 500
                    Integer amount = 0;
                    for(Budget__c Ibud : tempList){
                        amount = amount + Integer.valueOf(Ibud.Amount__c);
                    }
                    if(amount >= 500){
                        bud.addError('Sum(Amount) of related "Budget" child records must be <= $500 per year');
                    }
                }
            }
        }
    }
}