TransWikia.com

Trigger to Find all Realed Opportunity of Account will Closed Lost

Salesforce Asked by Bablu Kumar on November 28, 2021

i have a custom filed on Account Name(AssignCheckBox) ,write a Trigger on Opportunity when i update Stage of Opportunity is closed Lost and AccountId not Null and if Selected Account Might be possible selected Account have more than one Opportunity then i have to check all related Opportunity will be Closed Lost then Account CheckBox will be true other wise trigger will not be fire

please guide me how to do

public class OppPrintCampaign{
public static void InsertOpp(List<Opportunity> lstopp ,Map<Id,Opportunity> mapIdToSatge){
    Map<Id,Id> mapAccIdToOppId = new Map<Id,Id>();
    Set<Id> setOfAccId = New Set<Id>();
    Set<Id> setOfOppId = New Set<Id>();
    List<Account> lstacc = New List<Account>();
    Boolean check = false;
    //Campaign objcamp = [Select Id,name from campaign where Id = '7012v000002KBp9'];
    for(Opportunity objopp:lstopp){
        if(objopp.accountId !=null && objopp.stageName == 'Closed Lost' && objopp.stageName != mapIdToSatge.get(objopp.Id).stageName){
            setOfAccId.add(objopp.accountId);
        }
    }
    System.debug('-----setOfAccId-----'+setOfAccId);
    System.debug('----setOfOppId----'+setOfOppId);
     for(Opportunity objopp :[Select Id,Name ,Stagename ,AccountId from Opportunity where AccountId IN:setOfAccId]){        
         if(objopp.StageName == 'Closed Lost'){
             check = true;
         }
    }
    System.debug('----check----'+check);
     for(Account objacc:[Select Id,Name from Account where Id IN:setOfAccId]){
         if(check == true){
         objacc.Assign_Engments__c = true;
         lstacc.add(objacc);
         }
    }
    System.debug('-----lstacc-----'+lstacc);
    update lstacc;
}

}

above is my code but didn’t work in above scenario if account has more than one opportunity and stage of opportunity is not closed then account checkbox becomes true that should not be true

so please guide where i change my code

One Answer

Your logic here:

     if(objopp.StageName == 'Closed Lost'){
         check = true;
     }

is incorrect for two reasons.

  1. This is an "any" operation, rather than an "all". That is, your check variable will be true if any Opportunity is Closed Lost, but you've stated that you want it to be true only if all Opportunities are Closed Lost.

    If you want to track whether all Opportunities are Closed Lost, you'd want to start whatever variable you're using to track with the value true and set it to false if you locate any Opportunity that is not Closed Lost. However, making that change here is not enough to solve your problem; see the next item.

  2. You are iterating over all of the Opportunities associated with all Accounts that have Opportunities in the trigger set, and you are not distinguishing between Opportunities associated with different Accounts.

    There are multiple ways to solve this, but what they all have in common is building the right data structure to track these Opportunities. One approach would be to iterate over the Opportunities and sort them into a Map<Id, List<Opportunity>> keyed on the AccountId, then iterating over that map's keySet() (the set of Account Ids) and in an inner loop iterating over the corresponding List<Opportunity> to find the total for each Account. In loose pseudocode,

     create a Map<Id, List<Opportunity>>
     for (each Opportunity in query) {
         if (map does not contain Opportunity's Account Id) {
             add a new List<Opportunity> with that key
         }
         add this Opportunity to the list keyed under its Account Id
    }
    for (each AccountId in map's keySet()) {
        Boolean check = true;

        for (each Opportunity in this Account's list from the Map) {
           if (this Opportunity is not Closed Lost) {
               check = false;
               break;
            }
        }
        add this Account and check value to a list to be updated
    }
    update all Accounts

Obviously you will need to do some adaptation to fit into your code and translate into actual Apex.

The final observation I have is that it's not clear that what looks like an after insert trigger is the right place, or the only right place, to run this kind of code. You probably also need an update trigger.

Answered by David Reed on November 28, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP