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
Mandapaka Raghu 9Mandapaka Raghu 9 

one account record should not contain more than three opportunity records

Hi 

i have a scenario like one account record does not contain more than three opportunity records, and i wrote a following trigger, but it is  not working for inserting the records one by one , but this trigger is working for inserting the bulk records through list.

trigger Opportunity_Validation_Trigger2 on Opportunity (before insert) {
    list<Opportunity> opportunities=trigger.new;
    
    map<id,list<Opportunity>> AccOppMap=new map<id,list<Opportunity>>();
    for(Opportunity opps:opportunities){
        if(opps.AccountId!=null){
            if(AccOppMap.containsKey(opps.AccountId)){
                list<Opportunity> oppslist= AccOppMap.get(opps.AccountId);
                oppslist.add(opps);
            }
            else
            {
                list<Opportunity> oppslist=new list<Opportunity>();
                oppslist.add(opps);
                AccOppMap.put(opps.AccountId, oppslist);
            }
        }
    }
    
    for(opportunity op:trigger.new){
        if(op.AccountId!=null){
            integer count=AccOppMap.get(op.AccountId).size();
            if(count>=3){
                op.addError('an account should not contain more than 3 opportunities');
            }
        }
        
    }
}


can any one please help me, the scenerio is it should work for inserting the records one after one and through list using execute anonomous window.
Best Answer chosen by Mandapaka Raghu 9
Mandapaka Raghu 9Mandapaka Raghu 9
Hi

I solved this scenerio, The below code is working properly.

trigger Opportunity_Validation_Trigger2 on Opportunity (before insert) {    
    Map<ID,Integer> dbAccountIdToCountOfOpps = new Map<id,integer>();    
    for(Opportunity opp:trigger.new){
        if(opp.AccountId!=null){
            dbAccountIdToCountOfOpps.put( opp.AccountId, NULL );
        }
    }    
    for( Account dbAccount : [SELECT ID, ( SELECT ID FROM Opportunities ) FROM Account WHERE ID IN :  dbAccountIdToCountOfOpps.keySet() ] )
    {
        dbAccountIdToCountOfOpps.put( dbAccount.Id, dbAccount.Opportunities.size() );
    }        
    for( opportunity op:trigger.new ) {        
        if(op.AccountId!=null){
            integer existingCount = dbAccountIdToCountOfOpps.get(op.AccountId); // 3                      
            if( existingCount > 2 ) {
                op.addError('an account should not contain more than 3 opportunities');
            }
            else {
                dbAccountIdToCountOfOpps.put( op.AccountId, existingCount + 1  );
            }
        }  
    }      
}

Thanks and Regards,
Raghu M

All Answers

Khan AnasKhan Anas (Salesforce Developers) 
Hi Mandapaka,

Greetings to you!

Please try the below code, I have tested in my org and it is working fine. Kindly modify the code as per your requirement.
trigger Max3Childs on Opportunity (before insert) {
    
    List<id> accId = new List<id>();
    for(Opportunity opp : trigger.new){
        if(opp.AccountId != null){
            accId.add(opp.AccountId);    
        }
    }
    
    List<Opportunity> oppList = new List<Opportunity> ();
    
    List<Account> accLst = [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN : accId] ;
    for(Account accObj : accLst ){
        for(Opportunity o : accObj.Opportunities){     
            oppList.add(o);
        }
    }
    
    for(Opportunity opp : trigger.new){ 
        if(oppList.size() > 2 ){  // Use oppList.size() > 0 for max 1 Opportunity per Account
            opp.addError('You can not add more then three Opportunities for this Account'); 
            
        }
    }
}

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Mandapaka Raghu 9Mandapaka Raghu 9
Hi Anas,

Thnaks for your reponse, but it is not working for bulk of records.
i inserted list of records for same account. it is  not working in that case.

List<Opportunity> opps=new List<Opportunity>();
for (integer i=0;i<10;i++){
    Opportunity op=new Opportunity();
    op.Name='Testing nov 22'+i;
    op.accountId='0012v00002RGlhtAAD';
    op.stageName='Prospecting';
    op.closeDate= system.today()+15;
    opps.add(op);
        }
insert opps; 

i inserted this list of records for the same account through execute anonomous window. just check it one you get an idea.

Regards,
Raghu M.
 
Ajay K DubediAjay K Dubedi
Hi Mandapaka,

I have gone through your question as well as your code and created a trigger. Please give it a try - 
 
trigger LimitOpportunity on Opportunity (before insert, before update) {
    if(Trigger.isBefore) {
        if(Trigger.isInsert || Trigger.isUpdate) {
            list<Opportunity> oppList = new list<Opportunity>([Select Id, AccountId From Opportunity]);
            oppList.addAll([Select Id, AccountId From Opportunity Where Id In :Trigger.new]);         
            for(Opportunity oppN: Trigger.new) {                
                for(Opportunity opp: oppList) {  
                    Integer count = 0;                       
                    if(oppN.AccountId ==  opp.AccountId && oppN.Id !=  opp.Id ) {                        
                        count ++;
                    }                    
                }
                if(count > 3) {                   
                    oppN.addError('One Account can only have three opportunities!');
                }
            }        
        }
    }
}

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Ajay Dubedi
www.ajaydubedi.com
Deepali KulshresthaDeepali Kulshrestha
Hi Mandapaka,

Greetings to you!

I have gone through your query please try below code:
trigger Opportunity_Validation_Trigger2 on Opportunity (before insert) {
    
    List<Opportunity> opportunities=trigger.new;
    Set<Id> accIds=new Set<Id>();
    for(Opportunity opp: opportunities)
    {
        accIds.add(opp.AccountId); 
    }
    System.debug('Account Ids List is ::::'+accIds);
    
    List<Opportunity> oppList1=new List<Opportunity>();
    oppList1=[Select Id,AccountId,StageName from Opportunity where AccountId in : accIds];
    System.debug('Account contact List is ::::'+oppList1);
    
    Map<Id , List<Opportunity>> accOppMap=new Map<Id , List<Opportunity>>();
    for(Opportunity accOpp: oppList1)
    { 
        if(accOppMap.ContainsKey(accOpp.AccountId)){
            List<Opportunity> accOpplist1 = accOppMap.get(accOpp.AccountId);
            accOpplist1.add(accOpp);
            accOppMap.put(accOpp.AccountId, accOpplist1);
        }
        else{
            accOppMap.put(accOpp.AccountId,new List<Opportunity>());
            List<Opportunity> accOpplist1 = accOppMap.get(accOpp.AccountId);
            accOpplist1.add(accOpp);
            accOppMap.put(accOpp.AccountId, accOpplist1);
        }
    }
    System.debug('Account Opportunity Map is ::::'+accOppMap);
    
    for(Id acc1 :accOppMap.keySet())
    {
        Integer count = 0;
        List<Opportunity>  newoppList = accOppMap.get(acc1);
        
        for(Opportunity o: newoppList)
        { 
            count++;
        }
        if(count >= 3)
        {
            for(Opportunity o1: opportunities)
            {
                if(o1.AccountId == acc1)
                {
                    o1.adderror('Opps!!!! You can not create or update Opportunity');
                }
            }
        }
    }      
}


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Deepali Kulshrestha
www.kdeepali.com
Mandapaka Raghu 9Mandapaka Raghu 9
Hi Deepali,


Thanks for your reponse, but it is not working for bulk of records.
Please check it once by inserting a list of opportinities for new account record.


Thanks and Regards,
Raghu M.

 
Mandapaka Raghu 9Mandapaka Raghu 9
Hi

I solved this scenerio, The below code is working properly.

trigger Opportunity_Validation_Trigger2 on Opportunity (before insert) {    
    Map<ID,Integer> dbAccountIdToCountOfOpps = new Map<id,integer>();    
    for(Opportunity opp:trigger.new){
        if(opp.AccountId!=null){
            dbAccountIdToCountOfOpps.put( opp.AccountId, NULL );
        }
    }    
    for( Account dbAccount : [SELECT ID, ( SELECT ID FROM Opportunities ) FROM Account WHERE ID IN :  dbAccountIdToCountOfOpps.keySet() ] )
    {
        dbAccountIdToCountOfOpps.put( dbAccount.Id, dbAccount.Opportunities.size() );
    }        
    for( opportunity op:trigger.new ) {        
        if(op.AccountId!=null){
            integer existingCount = dbAccountIdToCountOfOpps.get(op.AccountId); // 3                      
            if( existingCount > 2 ) {
                op.addError('an account should not contain more than 3 opportunities');
            }
            else {
                dbAccountIdToCountOfOpps.put( op.AccountId, existingCount + 1  );
            }
        }  
    }      
}

Thanks and Regards,
Raghu M
This was selected as the best answer