1

I've made a research, try a few things...but I don't really see a good example where to understand how to do this.

I want an error messaget to be shown when I try to update or delete a QuoteLineItem from the Related List within the Quote detail page.

In a "before insert" and "before delete" trigger for the QuoteLineItem object I would like to access to the Status field from the Quote parent object and if the Status is "Approved" interrupt the insert/delete process.

I've come to this piece of code:

    trigger blockDelete on QuoteLineItem(before delete, before update) {

    QuoteLineItem myVar = [SELECT Quote.Id, Quote.Status from QuoteLineItem where Id IN: trigger.old];

    if (Trigger.isUpdate){
        for (QuoteLineItem q : Trigger.old){
                if(myVar.Quote.Status == 'Aprobado') {
                    // Adding the error to the new object
                    Trigger.newMap.get(q.Id).addError('Quote approved  --> QuoteLineItem can not be modified');
                }
            } 
    } else {
        for (QuoteLineItem q : Trigger.old){
                if(myVar.Quote.Status == 'Aprobado') {
                    // Adding the error to the new object
                    myVar.Quote.Id.addError('Quote approved  --> QuoteLineItem can not be deleted');
                }
            } 
    }

}

But I'm still not able to make it work completely...

UPDATE

I've accomplish to avoid the edition of a QuoteLineItem by using a Validation Rule like suggested in on of the answers:

             ISPICKVAL(Quote.Status, 'Approved')

But this isn't working when it comes to avoid deletion.

So, I've also tried with a trigger (I've updated the code based on other answer) and it also works fine for avoiding the edition but for the deletion doesn't work neither. It redirects me to a error page:

There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger blockDelete caused an unexpected exception, contact your administrator: blockDelete: execution of BeforeDelete caused by: System.FinalException: SObject row does not allow errors: Trigger.blockDelete: line 16, column 1".

2 Answers 2

3

The reason you are not seeing the error is because the addError needs to be on one of the QuoteLineItem records from the trigger context, which are the records that the save is been done on.

See below for a working example.

trigger myAccountTrigger on QuoteLineItem(before delete, before update) {
    for (QuoteLineItem q : Trigger.old){
        if(q.Status == 'Approved') {
            // Adding the error to the new object
            Trigger.newMap.get(q.Id).addError("Quote approved  --> QuoteLineItem's can't be modified");
        }
    }
}
2
  • 1
    That won't work. trigger.newMap is null before delete.
    – Adrian Larson
    May 28, 2015 at 6:07
  • Good solution for the before update. But, @AdrianLarson you were also right, for the delete was necessary to use trigger.oldMap, but still not working as expected. See updated question. May 28, 2015 at 9:06
1

You can do this with just a Validation Rule on QuoteLineItem. Your only criterion would be:

ISPICKVAL(Quote.Status, 'Approved')

You can then have just call the below from your delete trigger:

public static void validateDeletion(List<QuoteLineItem> lineItems)
{
    Set<Id> quoteIds = new Set<Id>();
    for (QuoteLineItem lineItem : lineItems)
        quoteIds.add(lineItem.QuoteId);
    Map<Id, Quote> quotes = new Map<Id, Quote>([
        SELECT Status FROM Quote WHERE Id IN :quoteIds
    ]);

    for (QuoteLineItem lineItem : lineItems) {
        if(Quotes.get(lineItem.QuoteId).Status == 'Approved') {
            lineItem.addError('message');
        }
    }
}

like so:

trigger myAccountTrigger on QuoteLineItem(before delete) {
{
    if (trigger.isBefore)
    {
        if (trigger.isDelete)
        {
            QuoteLineItemServices.validateDeletion(trigger.old);
        }
    }
}
3
  • Now you mention that the process is "kind of backwards". My intention is to show the error message when you try to update or delete a QuoteLineItem from the RelatedList within the Quote detail page. In case that changes anything. May 28, 2015 at 5:57
  • I understand your intention, you were adding the error to Quote in your code. Just use a validation rule on QuoteLineItem. You don't need a trigger at all for this validation.
    – Adrian Larson
    May 28, 2015 at 6:08
  • It works fine with the update of a QuoteLineItem, but it isn't working for the deleting. If I click "Delete" on a QuoteLineItem in the Realted List, it is deleted. May 28, 2015 at 6:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .