You need to sign in to do that
Don't have an account?
Don Pierce
Trigger error when attempting to delete a quote item
The error returned upon a delete of a Quote Line Item is:
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
<pre>
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.isDelete ? trigger.old : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
</pre>
All Answers
<pre>
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.isDelete ? trigger.old : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
</pre>