Apex trigger addError() always shows error-msg

adderrorapextrigger

Good day, everyone.
I have started learning Apex. And need help with triggers. The problem is:
I have custom object Gift Card, which is not related to any other objects. On Opportunity I have custom text field Gift Card. While inserting name of gift card I need to check if this card is active, if not I should show some error. If card is active I need to substract amount of card from amount of Opportunity. But using this code I always see only error message, it doesn't matter if card is active or not.

trigger cardFromOpportunity on Opportunity (before insert, before update) {
    for(Opportunity opp : Trigger.new){
        for(Gift_Card__c card:[SELECT Name,Amount__c,Active__c FROM Gift_Card__c]){
            if(opp.Gift_Card__c == card.Name && card.Active__c == true){
                opp.Amount -= card.Amount__c;
                card.Active__c = false;
                update card;
            }else if(opp.Gift_Card__c == card.Name && card.Active__c == false){
                opp.Gift_Card__c.addError('Error');
            }
        }
    }
}

Best Answer

There are several malpractices within your code, this may not be the answer to the issue why you're seeing the add error every time, but still should be some improvement to avoid running into Dml/Soql limits (which you can find here).

trigger cardFromOpportunity on Opportunity (before insert, before update) {
    Set<String> gcNames = new Set<String>();
    
    for(Opportunity opp : Trigger.new){
        gcNames.add(opp.Gift_Card__c)
    }
    Map<String,Gift_Card__c> giftCards = new Map<String,Gift_Card__c> ();
    for (Gift_Card__c gift: [SELECT Name,Amount__c FROM Gift_Card__c WHERE Name in: gcNames]){
        giftCards.put(gift.Name,gift);
    }
    for(Opportunity opp : Trigger.new){     
        if(giftCards.containsKey(opp.Gift_Card__c)){
            Gift_Card__c card = giftCards.get(opp.Gift_Card__c);
            if(card.Active__c){
                opp.Amount -= giftCards.get(opp.Gift_Card__c).Amount__c;
                giftCards.get(opp.Gift_Card__c).Active__c = false;
            }
            else{
                opp.Gift_Card__c.addError('Error');
            }
        }  
    }
    update giftCards.values();
}

Just to clarify , this code isn't meant to be a guide to solve the functional requirements of yours , but just a quick help on how to think in terms of bulkification of code and making queries selective.

Also probably you shouldn't be storing the Name as a String on the obect GiftCard but rather create a Lookup relationship towards Opportunity Object, or a Master-Detail relationship if it fits requirements.

Related Topic