[SalesForce] Trigger Validation on QuoteLineItem Based on Quote Status

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".

Best Answer

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");
        }
    }
}
Related Topic