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
Learning Apex (OOP)Learning Apex (OOP) 

Error: List must not have two identically equal elements

Hello,

I am getting the following error message when detonating this trigger below:
Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger OpportunityTeamMembers caused an unexpected exception, contact your administrator: OpportunityTeamMembers: execution of BeforeInsert caused by: System.ListException: Before Insert or Upsert list must not have two identically equal elements: Trigger.OpportunityTeamMembers: line 28, column 1​
 
trigger OpportunityTeamMembers on Opportunity (before insert) {
    List<OpportunityTeamMember> myOpptyTeamMembers = new List <OpportunityTeamMember>();
    for(Opportunity myOpp : Trigger.new){
        //Create an Oppty Team Member
        OpportunityTeamMember otm = new OpportunityTeamMember();
        otm.opportunityId = myOpp.Id;
        // If a Manager exist, add it to the list of myOpptyTeamMembers
        if(myOpp.Owner.ManagerId != null){
            otm.userId = myOpp.owner.ManagerId;
            otm.TeamMemberRole = 'Sales Manager';
            myOpptyTeamMembers.add(otm);
        }
        // If Dependents exist, add it/them to the list of myOpptyTeamMembers
        List<User> dependentUsers = [SELECT Id
                                     FROM User
                                     WHERE ManagerId = :myopp.OwnerId];
        if(dependentUsers.size()>0){
            // Loop on dependentUsers List
            OpportunityTeamMember otm2 = new OpportunityTeamMember();
            for(User myDependentUser : dependentUsers){
                otm2.UserId         = myDependentUser.Id;
                otm2.TeamMemberRole = 'Sales Rep';
                myOpptyTeamMembers.add(otm2);
            }
        }
    }
    // Add/Insert Team Members to the myOpp
    insert myOpptyTeamMembers;
}

According to the error message, it sounds like I am trying to insert a List (myOpptyTeamMembers) with two identical items (?).
I guess that, to Salesforce, two identical items would be identicals if their Id were the same, right? This would mean that, in myOpptyTeamMembers (which is the list I am inserting at the end of the code), there are 2 records Opportunity Team Members with the same Id?
How could this be possible?
Any clue?
(Thank you very much)
Learning Apex (OOP)Learning Apex (OOP)
Perhaps, it will help if I explain what the above Trigger is meant to do. This trigger on the Opportunity object will add Team Members to the Oppties entering this trigger. The Team Members can be, if they exist, the following type of users:
- The Opportunity Owner's Manager (the Manager is a field on the User Object);
- If the above mentioned Manager has "Dependents" (i.e. he/she is the Manager of other Users), these "dependents" will also be added as Team Members to the Opportunity(ies) entering the trigger.
(Thanks)

 
Salesforce DeveloperSalesforce Developer
Please try as below: 
trigger OpportunityTeamMembers on Opportunity (after insert,after update) {
    List<OpportunityTeamMember> myOpptyTeamMembers = new List <OpportunityTeamMember>();
    Set<Id> userIdSet = new set<Id>();
    
    for(Opportunity myOpp : Trigger.new){
        userIdSet.add(myOpp.OwnerId);
    }
    Map<Id,Id> managerIdMap = new Map<Id,Id>();
    For(User tempId: [SELECT Id, ManagerId FROM User WHERE Id = :userIdSet]){
        managerIdMap.put(tempId.id,tempId.ManagerId);
    }
    Map<Id,List<Id>> dependentUsers = new Map<Id,List<Id>>();
    for(User u:[SELECT Id, ManagerId FROM User WHERE ManagerId IN :managerIdMap.values()]){
        if(dependentUsers.containsKey(u.ManagerId)){
            dependentUsers.get(u.ManagerId).add(u.Id);
        }else
            dependentUsers.put(u.ManagerId, New List<Id>{u.Id});
    }
    
    for(Opportunity myOpp : Trigger.new){
        //Create an Oppty Team Member
        OpportunityTeamMember otm = new OpportunityTeamMember();
        otm.opportunityId = myOpp.Id;
        // If a Manager exist, add it to the list of myOpptyTeamMembers
        if(managerIdMap.containsKey(myOpp.OwnerId) && managerIdMap.get(myOpp.OwnerId) != null){
            otm.userId = managerIdMap.get(myOpp.ownerId);
            otm.TeamMemberRole = 'Sales Manager';
            myOpptyTeamMembers.add(otm);
            system.debug('###'+myOpptyTeamMembers);
        }
        // If Dependents exist, add it/them to the list of myOpptyTeamMembers
        if(dependentUsers!=NULL && dependentUsers.containsKey(managerIdMap.get(myOpp.OwnerId))){
            For(Id tempId: dependentUsers.get(managerIdMap.get(myOpp.OwnerId))){
				OpportunityTeamMember otm2 = new OpportunityTeamMember();
                otm2.OpportunityId = myOpp.Id;
                otm2.UserId         = tempId;
                otm2.TeamMemberRole = 'Sales Rep';
                myOpptyTeamMembers.add(otm2);
            }
            	
        }
        
    }
    // Add/Insert Team Members to the myOpp
    insert myOpptyTeamMembers;
}

 
Learning Apex (OOP)Learning Apex (OOP)
Hello my Friend, and thank you very much for your code.
I am new to programming and your code is still a bit overwhelming to me; could you possibly explain (with baby steps and in plane English) your rational (high level logical line of thoughs or process)?

It would be great to understand each logical step and why you have decided to design the solution in that way.

Thank you very much.

Ted
Learning Apex (OOP)Learning Apex (OOP)
For your information, I have tried your code but it does the following:
  • It adds the following records as OpportunityTeamMembers (on the Oppty):
    • The Opportunity Owner;
    • The Opportunity Owner's Manager
instead of adding (as per the requirement):
  • The Opportunity Owner's Manager and...
  • The Manager's dependent users (children of users of the Manager of the Owner of the Oppty entering the trigger)
Salesforce DeveloperSalesforce Developer
The code can be divided in differnet blocks, so in these 3 blocks I'm collecting data:
 
1.  Get ownerIds of the Opportunities:

   
for(Opportunity myOpp : Trigger.new){
        userIdSet.add(myOpp.OwnerId);
    }


    
2.  Get Opportunity owner's Manager:

   
Map<Id,Id> managerIdMap = new Map<Id,Id>();
    For(User tempId: [SELECT Id, ManagerId FROM User WHERE Id = :userIdSet]){
        managerIdMap.put(tempId.id,tempId.ManagerId);
    }


3. Get Managers dependents:

   
Map<Id,List<Id>> dependentUsers = new Map<Id,List<Id>>();
    for(User u:[SELECT Id, ManagerId FROM User WHERE ManagerId IN :managerIdMap.values()]){
        if(dependentUsers.containsKey(u.ManagerId)){
            dependentUsers.get(u.ManagerId).add(u.Id);
        }else
            dependentUsers.put(u.ManagerId, New List<Id>{u.Id});
    }



Now, started loop for the new Opportunities and added first Opportunity owner's Manager in the Opportunity Team Member, as below:

1. For Opp Owner's Manager :
    
for(Opportunity myOpp : Trigger.new){
        //Create an Oppty Team Member
        OpportunityTeamMember otm = new OpportunityTeamMember();
        otm.opportunityId = myOpp.Id;
        // If a Manager exist, add it to the list of myOpptyTeamMembers
        if(managerIdMap.containsKey(myOpp.OwnerId) && managerIdMap.get(myOpp.OwnerId) != null){
            otm.userId = managerIdMap.get(myOpp.ownerId);
            otm.TeamMemberRole = 'Sales Manager';
            myOpptyTeamMembers.add(otm);
            system.debug('###'+myOpptyTeamMembers);
        }


2. And then checked if the Manager has any dependents then add them in the Opportunity team as below:

     
// If Dependents exist, add it/them to the list of myOpptyTeamMembers
        if(dependentUsers!=NULL && dependentUsers.containsKey(managerIdMap.get(myOpp.OwnerId))){
            For(Id tempId: dependentUsers.get(managerIdMap.get(myOpp.OwnerId))){
                if(tempId != myOpp.ownerId){  //skip Opp Team member creation for Opportunity Owner
                   OpportunityTeamMember otm2 = new OpportunityTeamMember();
                    otm2.OpportunityId = myOpp.Id;
                    otm2.UserId         = tempId;
                    otm2.TeamMemberRole = 'Sales Rep';
                    myOpptyTeamMembers.add(otm2); 
                }
                
            }
                
        }
        
    }

Also, please note added a new condition to not add the Opportunity Owner in the Team.  
if(tempId != myOpp.ownerId){  //skip Opp Team member creation for Opportunity Owner
This code is working fine for me. It is adding Opp owner's Manager in the Opportunity Team and adding the users who have same Manager as opp owner. Your code was not following the best practices like it has Query inside the loop, which is not recommended. 

Thanks
Learning Apex (OOP)Learning Apex (OOP)
Hello my Friend,

Here are 3 questions below (Q1, Q2 and Q3)

Regarding your first block #2: Get Opportunity owner's Manager:
Map<Id,Id> managerIdMap = new Map<Id,Id>();
    For(User tempId: [SELECT Id, ManagerId FROM User WHERE Id = :userIdSet]){
        managerIdMap.put(tempId.id,tempId.ManagerId);
    }
Q1: Why are we using a Map<> here? Could we have just used a List<> instead? (with the code below, I would also get a list of managerIds, right?); what is the point in using a Map?:
List<User> managerIds = [SELECT Id,
                                ManagerId
                           FROM User
                          WHERE Id = :myOpp.OwnerId
]
The reason I am asking is because, I have never used Map before and even after reviewing SFDC's API information about Map<>, I find your piece of code a bit more complex than mine. There must be a good reason for choosing Map (instead of a simple List<>).
Why do you need to leverage Map<> here instead of just a List<> ?

Re. first block #3: Get Manager's dependents:
Map<Id,List<Id>> dependentUsers = new Map<Id,List<Id>>();
    for(User u:[SELECT Id, ManagerId FROM User WHERE ManagerId IN :managerIdMap.values()]){
        if(dependentUsers.containsKey(u.ManagerId)){
            dependentUsers.get(u.ManagerId).add(u.Id);
        }else
            dependentUsers.put(u.ManagerId, New List<Id>{u.Id});
    }
Here again, I am finding this piece of code a bit more complex than what I think I could write myself (I am a beginner, so I would tend to use a simple List<> for now) in order to get a list of dependent users:
List<User> dependentUsers = [SELECT Id,
                                    ManagerId
                               FROM User
                              WHERE ManagerId = :myOpp.Owner.ManagerId ];
Q2: could the above code (with a List) be used instead of a Map?

Re. your second block #1: Adding the Owner's Manager as an Oppty Team Member
for(Opportunity myOpp : Trigger.new){
        //Create an Oppty Team Member
        OpportunityTeamMember otm = new OpportunityTeamMember();
        otm.opportunityId = myOpp.Id;
        // If a Manager exist, add it to the list of myOpptyTeamMembers
  here-> if(managerIdMap.containsKey(myOpp.OwnerId) && managerIdMap.get(myOpp.OwnerId) != null){
            otm.userId = managerIdMap.get(myOpp.ownerId);
            otm.TeamMemberRole = 'Sales Manager';
            myOpptyTeamMembers.add(otm);
            system.debug('###'+myOpptyTeamMembers);
        }
The following line seem to verify the IF condition: // If a Manager exist, add it to the list of myOpptyTeamMembers​
But, I struggle understanding this piece of code below:
if(managerIdMap.containsKey(myOpp.OwnerId) && managerIdMap.get(myOpp.OwnerId) != null)
The first condition says: IF the managerIdMap contains the Key myOpp.OwnerId

AND

the second condition says IF the item myOpp.OwnerId in managerIdMap is different to Null...

Q3: Doesn't this second condition overlap the first condition? I mean, if the item myOpp.OwnerId in the Map is differen to Null, it must be because the first condition is true as well (the item has to contain a Key because it is in a Map, it has to contain a Key, right?). So, is the firs condition really necessary?

Thank you very much.
Learning Apex (OOP)Learning Apex (OOP)
Hello,
As mentioned above, the Dependents are not being added to the Opportunity Team Members:
User-added image

At the moment, the code you have sent me only adds the Manager (and it also adds the Opportunity Owner instead of the Dependents).

Thank you.
Learning Apex (OOP)Learning Apex (OOP)
Question: In my original code, why was I getting the error?
What was really the cause of the error?

Thank you very much.