0
trigger OpportunityTrigger on Opportunity (after insert) {
    
    if (Trigger.isInsert) {
        List<User> lstUser = [Select Id,isActive From User Where isActive = true And (Profile.Name = 'System Administrator' OR Profile.Name = 'Standard User')];
        System.debug('lstUser:::>'+lstUser);        
        List<OpportunityShare> sharesToCreate = new List<OpportunityShare>();
        for (Opportunity oOpportunity : Trigger.new) { 
            if(lstUser != null && lstUser.size() > 0){
                for(User oUsers : lstUser){
                    OpportunityShare oOpportunityShare = new OpportunityShare();
                    System.debug('UserId:::>'+oUsers.Id);
                    oOpportunityShare.UserOrGroupId =  oUsers.Id;
                    System.debug('oOpportunityShare.UserOrGroupId :::>'+oOpportunityShare.UserOrGroupId);
                    oOpportunityShare.OpportunityAccessLevel = 'Edit';
                    System.debug('oOpportunityId :::>'+oOpportunity.Id);
                    oOpportunityShare.OpportunityId = oOpportunity.Id;
                    sharesToCreate.add(oOpportunityShare);
                }
            }
            
            
        }
        if (!sharesToCreate.isEmpty()){
            insert sharesToCreate;
        }
        
    }
}
7
  • Why are you sharing Opportunities to all users via Apex instead of using a Criteria-Based Sharing Rule or simply changing your Org-Wide Defaults?
    – David Reed
    Commented Nov 10, 2020 at 1:16
  • @DavidReed I have a requirement to share Opportunities to all users then revoking the access from the selected users in a custom object which is on Detail side of the Opportunity. Commented Nov 10, 2020 at 1:32
  • don't create a share for the Opportunity owner; also, by definition, lstUser will never be null or empty
    – cropredy
    Commented Nov 10, 2020 at 1:48
  • There are lots of reasons that this can happen, but I would guess that here it's because a user is creating an Opportunity on an Account to which they have only Read record-level access. Might that be the case? Can you edit to provide more reproduction details?
    – David Reed
    Commented Nov 10, 2020 at 2:04
  • I'm also really suspicious of that sharing architecture and I don't think it's going to work very well, but that's a topic too big for this format.
    – David Reed
    Commented Nov 10, 2020 at 2:04

1 Answer 1

2

So, this error occurs when you try an do an explicit share to the record's owner. So, you can rewrite your trigger to be ..

trigger OpportunityTrigger on Opportunity (after insert) {
    
    
  Map<Id,User> usersById= new Map<Id,User> (
                    [Select Id, IsActive 
                        From User 
                        Where isActive = true And 
                              Profile.Name IN ('System Administrator','Standard User')]);
  List<OpportunityShare> sharesToCreate = new List<OpportunityShare>();
  for (Opportunity oppo: Trigger.new) { 
    for(Id shareWithUserId: usersById.keySet()){
       if (oppo.Ownerid = UserInfo.getUserId()) {continue;} // don't share to owner
       sharesToCreate.add(new OpportunityShare(
               UserOrGroupId =  shareWithUserId,
               OpportunityAccessLevel = 'Edit',
               OpportunityId = oppo.Id));
     }
   }   
        
  insert sharesToCreate; // no need to test for empty as empty collection doesn't burn DML
        
}

Note: There is a possibility that you'll exceed # DML recs per Transaction (10,000). 200 Oppos and 50 eligible users = 10,000. If that is a realistic possibility, then you'll need to delegate work to a chained set of Queueables

You must log in to answer this question.

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