0

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');
            }
        }
    }
}
2
  • I got it. Thank you. Commented Nov 11, 2021 at 13:37
  • That's not true, just run this annonymous apex and you will see. "==" is the same as String.EqualsIgnoreCase , but runs faster and doesn't need validations against nulls. string g = 'test'; string t = 'test'; string h= 'Test'; System.debug(g==t); System.debug(g==h); As per stated on this thread : salesforce.stackexchange.com/questions/80456/… Commented Nov 11, 2021 at 15:03

1 Answer 1

1

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.

1
  • Thank you for your help! Commented Nov 11, 2021 at 13:38

You must log in to answer this question.

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