function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Olga ShyliukOlga Shyliuk 

trigger opportunity

Hi, everyone!

Here I need to create trigger that support gift cards which allows users to reduce Opportunity price on fixed amount. Opportunity and Gift Card has no relationship. User has write name of gift card in opportunity then its reduce amount opportunity for the amount of gift card.

public with sharing class GiftCardTriggerHandler {
    public void afterUpdate(List<Gift_Card__c> newGiftCards) {
        Set<String> opportunityNames = new Set<String>();
        for (Gift_Card__c giftCardItem : newGiftCards) {
            opportunityNames.add(giftCardItem.Name);
        }
        Map<ID, Opportunity> opportunitiesToUpdate = new Map<ID, Opportunity>([SELECT Id, Gift_Card__c, Amount FROM Opportunity WHERE Gift_Card__c IN: opportunityNames]);
        List<Gift_Card__c> giftCardToInsert = [SELECT Id, Name, Amount__c, Active__c FROM Gift_Card__c WHERE Name IN: opportunityNames];    

        for(String opportunityName : opportunityNames) {
            Decimal Amount = 0;
            Opportunity currentOpportunity = opportunitiesToUpdate.get(opportunityName);
            System.debug('Null' + currentOpportunity.Amount);
            for(Gift_Card__c giftCardItem : giftCardToInsert) {            
                if(giftCardItem.Name == opportunityName) {
                    if(giftCardItem.Active__c == true) {
                        Amount = currentOpportunity.Amount - giftCardItem.Amount__c;
                        giftCardItem.Active__c = false;
                    } 
                    else if(giftCardItem.Active__c == false) {
                           opportunityName.addError('Please, choose active Gift Card!'); 
                    }            
                } 
            }
            if (currentOpportunity.Amount < Amount) {
                currentOpportunity.Amount = Amount;
                opportunitiesToUpdate.put(opportunityName, currentOpportunity);
            }
        } 
        update opportunitiesToUpdate.values();
    }
}

Vijay NagellaVijay Nagella
Hi Olga Shyliuk,

As a best practice you should avoid writing Nested Loops.Please find the optimized code.Hope it helps you.
 
public with sharing class GiftCardTriggerHandler {

    public void afterUpdate(List<Gift_Card__c> newGiftCards) {
	
        Map<String,Account> GiftCardNames = new Map<String,Account>();
		
		Map<String,Account> OpportunityNames = new Map<String,Account>();
		
        for (Gift_Card__c giftCardItem : newGiftCards) {
		
            GiftCardNames.put(giftCardItem.Name,Gift_Card__c);
			
        }
		
        List<Opportunity> opportunitiesToUpdate = [SELECT Id, Gift_Card__c, Amount FROM Opportunity WHERE Gift_Card__c IN: GiftCardNames.keyset()];
		
		for(Opportunity opp : opportunitiesToUpdate){
			OpportunityNames.put(opp.Gift_Card__c,opp);
		}
		
        List<Gift_Card__c> giftCardToInsert = [SELECT Id, Name, Amount__c, Active__c FROM Gift_Card__c WHERE Name IN: GiftCardNames.keyset()];    

      
	    for(Gift_Card__c gc: giftCardToInsert){
		
			Decimal Amount = 0;
			
            Opportunity currentOpportunity = OpportunityNames.get(gc.name);

			if(GiftCardNames.containsKey(gc.name) && gc.Active__c == true) {
			
				Amount = currentOpportunity.Amount - gc.Amount__c;
						
                gc.Active__c = false;
						
            }       
					
            else if(GiftCardNames.containsKey(gc.name) && gc.Active__c == false) {
					
                gc.addError('Please choose active Gift Card!'); 
						
            }
			
			if (currentOpportunity.Amount < Amount) {
                currentOpportunity.Amount = Amount;
                OpportunityNames.put(gc.name, currentOpportunity);
            }
            
        } 
		
		if(!OpportunityNames.isEmpty() && OpportunityNames.size() > 0 ){
			update OpportunityNames.Values();
		}
		
		
		
    }

}

Thanks,
Vijay,
Solution Architect
Steadfast Consultancy Services.
ravi soniravi soni
Hi olga,
try follwoing code in different way.
public with sharing class GiftCardTriggerHandler {
    
    public void afterUpdate(List<Gift_Card__c> newGiftCards) {
        
        Set<String> setOfGiftsName = new Set<String>();
        list<Opportunity> lstOpp = new list<Opportunity>();
        /* store Gifts card name into set */
        for (Gift_Card__c giftCardItem : newGiftCards) {
            setOfGiftsName.add(giftCardItem.Name);
        }
        /*Store Opportunities whose gift card name contains setOfGiftsName */
        Map<Gift_Card__c, Opportunity> storeOppForUpdateInMap = new Map<Gift_Card__c, Opportunity>();
        for(Opportunity opp : [SELECT Id, Gift_Card__c, Amount FROM Opportunity 
                               WHERE Gift_Card__c IN: setOfGiftsName]){
                                storeOppForUpdateInMap.put(opp.Gift_Card__c,opp);   
                              }
        
                                            
        
       /* fetch all gift card records where name equal to  setOfGiftsName's records */
        List<Gift_Card__c> lstGift_card = [SELECT Id, Name, Amount__c, Active__c FROM Gift_Card__c 
                                           WHERE Name IN: setOfGiftsName];    

            Decimal Amount = 0;
               
            for(Gift_Card__c giftCardItem : lstGift_card) {            
                if(setOfGiftsName.contains(giftCardItem.Name)) {
                
                    if(giftCardItem.Active__c == true) {
                        Amount = storeOppForUpdateInMap.get(giftCardItem.Name).Amount - giftCardItem.Amount__c;
                        giftCardItem.Active__c = false;
                    } 
                    else if(giftCardItem.Active__c == false) {
                           giftCardItem.Active__c.addError('Please, choose active Gift Card!'); 
                    }            
                } 
                if (storeOppForUpdateInMap.get(giftCardItem.Name).Amount < Amount) {
                    opportunity objOpp = new opportunity();
                    objOpp.Id =storeOppForUpdateInMap.get(giftCardItem.Name).Id;
                    objOpp.Amount = Amount;
                    lstOpp.add(objOpp);
                
            }
            }
            
        if(lstOpp.size() > 0){
            update lstOpp;
        }
        }
}
let me know if it hleps you by marking it as best answer.
Thank you