1

I have an Apex helper class called by a trigger which is to setup Apex sharing for Customer Community Plus users by sharing to their GroupId.

The class loops through the custom object records to setup sharing using a List for the custom object share and adding to it each time the for loop executes, however it seems to end up with only the last set of values multiple times in the list which causes an exception when I try to insert the share records.

Trigger code

if(trigger.isBefore && trigger.isUpdate){
    WSC_SPID_Trigger_Methods.updatePidShare(trigger.New, trigger.OldMap);
}

Trigger Handler code

public static void updatePidShare(List<PID__c> changedPid, Map<Id,PID__c>oldPid){
         System.debug('Pids to change '+changedPid.size());
         List<PID__Share> pidShares = new List<PID__Share>();
         if(changedPid.size()>0&&changedPid!=Null){
            PID__Share retailerRecord = new PID__Share();
            //Need to compare if Retailer on PID changed
             for(PID__c workPid :changedPid){
                 if(workPid.Current_Retailer__c!=oldPid.get(workPid.Id).Current_Retailer__c
                   &&workPid.Initial_Share__c==true){
                     System.debug('Old and new retailer'+workpid.Current_Retailer__c+''+oldpid.get(workpid.id).Current_retailer__c);
                     Id AccountId = workPid.Current_Retailer__c;
                     List<UserRole> retailerRoles = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId];
                     if(retailerRoles.size()>0){
                          Id RoleId = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId AND PortalRole ='Worker' LIMIT 1].Id;
                          Id GroupId = [SELECT Id FROM Group WHERE RelatedId = :RoleId LIMIT 1].Id;
                          System.debug('PID, role and group Id '+workpid.Id+' '+RoleId+''+GroupId);
                          System.assert(GroupId!=Null);
                          retailerRecord.ParentId = workPid.Id;
                          retailerRecord.UserOrGroupId = GroupId;
                          retailerRecord.AccessLevel = 'Read';
                          retailerRecord.RowCause = Schema.PID__Share.RowCause.Access_SPID_Retailer__c;           
                          pidShares.add(retailerRecord);
                          System.debug('Share Record '+retailerRecord.ParentId+' '+retailerRecord.UserOrGroupId);

                     }                

                 }
                 else if(workPid.Initial_Share__c==false&&workPid.Current_Retailer__c!=Null){
                     System.debug('Old and new retailer'+workpid.Current_Retailer__c+''+oldpid.get(workpid.id).Current_retailer__c);
                     Id AccountId = workPid.Current_Retailer__c;
                     List<UserRole> retailerRoles = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId];
                     if(retailerRoles.size()>0){
                          Id RoleId = [SELECT Id FROM UserRole WHERE PortalAccountId = :AccountId AND PortalRole ='Worker' LIMIT 1].Id;
                          Id GroupId = [SELECT Id FROM Group WHERE RelatedId = :RoleId LIMIT 1].Id;
                          System.debug('SPID, Role and group Id '+workPid.Id+' '+RoleId+''+GroupId);
                          System.assert(GroupId!=Null);
                          retailerRecord.ParentId = workPid.Id;
                          retailerRecord.UserOrGroupId = GroupId;
                          retailerRecord.AccessLevel = 'Read';
                          retailerRecord.RowCause = Schema.PID__Share.RowCause.Access_SPID_Retailer__c;           
                          pidShares.add(retailerRecord);
                          System.debug('Share Record '+retailerRecord.ParentId+' '+retailerRecord.UserOrGroupId);
                         }
                 }

             }
             //testing error - show all records to be inserted
             for(PID__Share p1 :pidshares){
                 System.debug('Share records'+p1.Id+' '+p1.ParentId+' '+P1.UserOrGroupId+' '+p1.AccessLevel+' '+p1.RowCause);
             }

            //insert new records
             if(pidShares.size()>0){
                  System.debug('No of rows to add'+pidShares.size());
                  Database.SaveResult[] pidSharesInsertResult = Database.insert(pidShares, false);
             }
         }
    }

Debug log

Debug log showing where overwritten data occurs

enter image description here

  • 2
    FYI, if(changedPid.size()>0&&changedPid!=Null){ would crash if changedPid was null; you always need to check for null first. However, Trigger.new will never be null nor empty on insert or update, so this is superfluous anyways. – sfdcfox Feb 9 '17 at 12:21
  • Thanks, this is where I am having to learn Apex in an 'accelerated' fashion - no devs so DIY when I'd not done much coding in SF before. I will correct any little errors like that as well as hopefully the main issue that is causing the update to fail. – Dave Humm Feb 9 '17 at 12:24
  • 1
    Welcome to the world of Salesforce Development. It's easy enough to get started, but tricky enough that it takes a while to get good. Just keep on reading enough here on SFSE, you'll be an expert in no time. Also, have you considered taking the Developer Trail on the Trailhead? It doesn't get much more accelerated than that. – sfdcfox Feb 9 '17 at 12:33
2

I have now found the answer with reference to this existing question.

The variable for the custom object share PID__Share needed to be moved to within the loop so that it would get recreated each time, so at the start of the for loop it how has the working record created.

 public static void updatePidShare(List<PID__c> changedPid, Map<Id,PID__c>oldPid){
     System.debug('Pids to change '+changedPid.size());
     List<PID__Share> pidShares = new List<PID__Share>();
     if(changedPid.size()>0&&changedPid!=Null){
     //Need to compare if Retailer on PID changed
         for(PID__c workPid :changedPid){

            //Creation of working record for the PID__Share moved into the for loop
             PID__Share retailerRecord = new PID__Share();
  • 1
    Can you add a comment to your code fragment here to highlight the fact that you moved the PID__Share retailerRecord = new PID__Share(); line to the inside of the loop? I know that your answer does say that you did this (and maybe it's just me suffering from Wall-of-Text syndrome from your question), but I completely glossed over that. – Derek F Feb 9 '17 at 14:44
  • @DerekF - will to - I can see that it is a bit dense if you don't know it. – Dave Humm Feb 9 '17 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.