2

I have an issue where my batch job seems to be choosing a random amount of records to not update/create. There is no error thrown from what ive seen, and I do not have a try/catch that would allow for silent failures. If I run the job multiple times it will eventually touch all records. Also the number being left off is not consistent. ive confirmed that all the expected accountIds are being passed in, and the scope contains all expected records. Code below:

public class AccountTeamAssignmentBatch implements Database.Batchable<sObject>, Database.Stateful {

public List<Id> ACCLIST = new List<Id>();
public List<AccountTeamMember> PARENTTEAMLIST = new List<AccountTeamMember>();
public AccountTeamMember TEAMOWNER;
Public String TEAMOWNEREMAIL;
Public Set<String> Emails = new Set<String>();



public AccountTeamAssignmentBatch(List<Id> acclist, List<AccountTeamMember> ParentTeamList, AccountTeamMember TeamOwner, String TeamOwnerEmail)
    
{
    
    this.ACCLIST = acclist;
    this.PARENTTEAMLIST = ParentTeamList;
    this.TEAMOWNER = TeamOwner;
    This.TEAMOWNEREMAIL = TeamOwnerEmail;
    
}

public class FlowInputs {
    // parameters passed in from flow
    @InvocableVariable public List<Id> AccId;
    @invocableVariable public List<AccountTeamMember> ParentTeam;
    @invocableVariable public AccountTeamMember TeamOwner;
    
}

@invocablemethod

public static void assignTeams(List<FlowInputs> requests)
    
{
    
    List<Id> acclist = new List<Id>();
    List<AccountTeamMember> ParentTeamList = new List<AccountTeamMember>();
    AccountTeamMember TeamOwner;
    
    for(FlowInputs req : requests)   
        
    {
        ParentTeamList.addAll(req.ParentTeam);
        acclist.addAll(req.accId);
        TeamOwner = req.TeamOwner;
        
    }
    System.debug(acclist.size());
    //get team owner email
    User TeamownerFields = [Select Email from User Where Id =: TeamOwner.UserId Limit 1];
    String TeamOwnerEmail = TeamownerFields.Email; 
    
    Id jobId = Database.executeBatch(new AccountTeamAssignmentBatch(acclist, ParentTeamList, TeamOwner, TeamOwnerEmail));
    
}

public Database.QueryLocator start(Database.BatchableContext BC){
    
    String query = 'SELECT ID, (Select TeamMemberRole, Status__c, Id, UserId, User.Email, End_Date__c FROM AccountTeamMembers) FROM ACCOUNT WHERE ID IN : ACCLIST';
    
    return Database.getQueryLocator(query);
    
}

public void execute(Database.BatchableContext BC , List<Sobject> scope){
    
    List<AccountTeamMember> memstoUpdate = new List<AccountTeamMember>();
    List<AccountTeamMember> memstoCreate = new List<AccountTeamMember>();
    List<Id> ParentTeamIds = new List<Id>();
    
    For(AccountTeamMember ptI : ParentTeamList){
        ParentTeamIds.Add(ptI.UserId);
    }
    System.debug(scope.size());
    //loop through Child account team members
    for(Account a : (List<Account>)scope) {
        List<Id> ChildTeamIds = new List<Id>();
        
        for(AccountTeamMember atm: a.AccountTeamMembers){
            ChildTeamIds.Add(atm.UserId);
            //update existing team members that match
            if(ParentTeamIds.contains(atm.UserId)){
                atm.Status__c = 'Current';
                atm.End_Date__c = null;
                atm.TeamMemberRole = 'Team Member';
                Emails.add(atm.User.Email);
                memstoUpdate.add(atm);
                //update existing team owner that matches
            }else if(Teamowner.UserId == atm.UserId){
                atm.Status__c = 'Current';
                atm.End_Date__c = null;
                atm.TeamMemberRole = 'Owner';
                Emails.add(TeamOwnerEmail);
                memstoUpdate.add(atm);
                //Set non matching team members to former
            }else{
                atm.Status__c = 'former';
                atm.End_Date__c = Date.Today();
                memstoUpdate.add(atm);                    
            }
        }
        //add new team members to child account 
        for(AccountTeamMember Ptm : ParentTeamList){
            if(!ChildTeamIds.Contains(ptm.UserId)){
                AccountTeamMember newmem = new AccountTeamMember();
                newmem.UserId = ptm.UserId;
                newmem.CaseAccessLevel = 'Edit';
                newmem.ContactAccessLevel = 'Edit';
                newmem.AccountId = a.Id;
                newmem.TeamMemberRole = 'Team Member';
                newmem.AccountAccessLevel = 'Edit';
                newmem.OpportunityAccessLevel = 'Edit';
                newmem.Status__c = 'Current';
                newmem.Start_Date__c = Date.today();
                Emails.add(ptm.User.Email);
                memstoCreate.add(newmem);
                
            }
        }
        // add new team owner to child account
        If(!ChildTeamIds.Contains(TeamOwner.UserId)){
            AccountTeamMember newmem = new AccountTeamMember();
            newmem.UserId = TeamOwner.UserId;
            newmem.CaseAccessLevel = 'Edit';
            newmem.ContactAccessLevel = 'Edit';
            newmem.AccountId = a.Id;
            newmem.TeamMemberRole = 'Owner';
            newmem.AccountAccessLevel = 'Edit';
            newmem.OpportunityAccessLevel = 'Edit';
            newmem.Status__c = 'Current';
            newmem.Start_Date__c = Date.today();
            emails.add(TeamOwnerEmail);                
            memstoCreate.add(newmem);                
        }
        
    }
    Insert memstoCreate;
    update memstoUpdate;
           
}
2
  • 1
    Based on the way TeamOwner is assigned, you assume Invocable is always invoked with a single FlowInput. Correct? As for the updates: It's a Salesforce bug, if not all AccountTeamMembers on processed Accounts get a new LastModifiedDate here (and no Exception happens). Nevertheless it's worthwhile to move most of the Account query into execute (see sfdcfox here). Commented Apr 4 at 9:43
  • @FelixvanHove Yes this is run from a screenflow so there is only ever a single flow input.
    – Trace
    Commented Apr 4 at 14:54

1 Answer 1

1

@felixvanHove was correct in his comment. I changed the scope query to target AccountTeamMember and then moved the account query into the execute method. Made some small tweaks to the execute method to handle the changes and it now runs for all records.

You must log in to answer this question.

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