Situation: I am trying to build a custom validation rule via apex that will stop users from saving a charge item to a quote if the charge item exceeds the available product quantity. The charge item being saved is a child of (and has a lookup relationship to) a "Rate Plan", which is the object that carries the available product quantity field.
Object that triggers apex: zqu__QuoteCharge__c
Relationship field on QuoteCharge: zqu__ProductRatePlanCharge__c
The trigger is currently in the BEFORE INSERT context, to block users from saving new records. I pass Trigger.new as a parameter to my class/method: z_QuoteChargeTriggerHandler.customValidation(Trigger.new);
In my for() loop, I've added a bunch of System debugs since my if statement wasn't being triggered.
When I System.debug(zqu__ProductRatePlanCharge__c) it returns an Id, so I know the relationship is there.
However, when I System.debug(zqu__ProductRatePlanCharge__r.Ascent_Quantity__c) I return null. Expected: 0.
Ultimate Question: Since I cannot SOQL query this record during BEFORE INSERT (At least, I think so, since the record hasn't been inserted yet?) How can I reference related objects using the __r relationship before insert of a new record in the context of Trigger.new?
Code:
public void customValidation(List<zqu__QuoteCharge__c> newList){
if (newList != null && newList.size() > 0){
List<zqu__ProductRatePlanCharge__c> rpc = new List<zqu__ProductRatePlanCharge__c>(); // create a list per other Stack suggestion
for(zqu__QuoteCharge__c quoteCharge: newList){
if(quoteCharge.Name != 'Discount'){
rpc.add(quoteCharge.zqu__ProductRatePlanCharge__r); // add to that list?
System.debug('MM++++ rpc: ' +rpc); // rpc returns null but shouldnt?
System.debug('MM++++ Charge Name: ' +quoteCharge.Name);
System.debug('MM++++ Charge Quantity: ' +quoteCharge.zqu__Quantity__c);
System.debug('MM++++ RatePlan Link: ' +quoteCharge.zqu__ProductRatePlanCharge__c); // returns ID (Lookup, expected)
System.debug('MM++++ RatePlan Name: ' +quoteCharge.zqu__ProductRatePlanCharge__r.Name); // returns null (expect name)
System.debug('MM++++ Ascent Quantity: ' +quoteCharge.zqu__ProductRatePlanCharge__r.Ascent_Quantity__c); // returns null (expect: 0)
if(quoteCharge.zqu__ProductRatePlanCharge__r.Ascent_Quantity__c == 0 || quoteCharge.zqu__ProductRatePlanCharge__r.Ascent_Quantity__c < quoteCharge.zqu__Quantity__c){
quoteCharge.addError('The Product: ' +quoteCharge.Name + ' only has ' +quoteCharge.zqu__ProductRatePlanCharge__r.Ascent_Quantity__c + ' in stock but you are trying to sell ' +quoteCharge.zqu__Quantity__c);
}
}
}
}
}
zqu__ProductRatePlanCharge__r
is null, and we expect this: you need to loop through Trigger.new, put the ID values fromzqu__ProductRatePlanCharge__c
into a collection of some sort, and query the parent records directly. Something likeMap<Id, zqu__ProductRatePlanCharge__c> charges = new Map<Id, zqu__ProductRatePlanChange__c>(); for(zqu__QuoteCharge__c quoteCharge: newList) { charges.put(quoteCharge.zqu__ProductRatePlanChange__c, null); } charges.putAll([SELECT ... FROM zqu__ProductRatePlanChange__c WHERE Id IN :charges.keySet()]); ...
See linked q's.