0

Please, Help. The trigger fires only for the first opportunity created and for editing. When creating subsequent opportunities, the trigger does not fire.

We need to support gift cards which allows users to reduce Opportunity price on fixed amount. If the name of the card matches the entered one and it is active, then we make a discount

What should I add?

trigger GiftCardStatusForOpprtn on Opportunity (before insert, before update) {

    List<Gift_Card__c> gitfCardList = [SELECT Name, Active__c, Amount__c
                                              FROM Gift_Card__c];
    
   Decimal amountResult;
 
    
    for(Opportunity op : Trigger.New) {
        
        for(Gift_Card__c gc : gitfCardList){
            
            if(op.Gift_Card_Name__c == gc.Name){
                if(gc.Active__c == true){
                    
                    amountResult = op.Amount - gc.Amount__c;
                    
                        op.Amount = amountResult;
                        
                    }
                }
            } 
            
        }
}

1 Answer 1

2

Your code has a lot of problems. You have an unnecessary nested loop, you're querying every record in the database every time you want to apply a gift card, your trigger will end up reducing the amount with every edit until your opportunity's amount goes so low you'll actually pay your customers to take your service/product off your hands, etc. You need to start with the Aggregate-Query-Update pattern in order to avoid the various Execution Governors and Limits.

Here's a refactored version for you to start from.

trigger applyGiftCard on Opportunity (before insert, before update) {
  Map<String, Decimal> giftDiscounts = new Map<String, Decimal>();
  // Aggregate
  for(Opportunity record: Trigger.new) {
    giftDiscounts.put(record.Gift_Card_Name__c, 0);
  }
  // Query
  // Note we query only for active cards and by name
  for(Gift_Card__c giftCard: [
         SELECT Name, Amount__c 
         FROM Gift_Card__c 
         WHERE Active__c = true AND 
               Name = :giftDiscounts.keySet()]) {
    giftDiscounts.put(giftCard.Name, giftCard.Amount__c);
  }
  // Update
  for(Opportunity record: Trigger.new) {
    record.Discounted_Amount__c = record.Amount - giftDiscounts.get(record.Gift_Card_Name__c);
   }
}
4
  • Thank you very much I understood it. But there is also a condition to overwrite the emount in the standard field (record.Amount - giftDiscounts.get (record.Gift_Card_Name__c)). change the standard Amount from Opportunity after calculation. Nov 13, 2021 at 16:08
  • Am sorry but its does not work. I have empty soql // Note we query only for active cards and by name Nov 14, 2021 at 17:31
  • @RomanSkrypnyk Make sure you have valid records to query? This code should definitely work. Maybe you could update your question with the latest version of your code?
    – sfdcfox
    Nov 14, 2021 at 21:09
  • Sorry, after rewriting in the map, giftDiscounts.put(giftCard.Name, giftCard.Amount__c); DEBUG|{C-0002=0} I get a name - a key, but the value is zero. does not overwrite the value after the cards are fetched. Nov 15, 2021 at 10:15

You must log in to answer this question.

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