Skip to content
This repository has been archived by the owner on May 12, 2023. It is now read-only.

Only executing actions on one record in the report #78

Closed
priscilacclr opened this issue Apr 5, 2019 · 6 comments
Closed

Only executing actions on one record in the report #78

priscilacclr opened this issue Apr 5, 2019 · 6 comments
Assignees
Labels
discussion 💬 Discussing usage, best practices, questions, etc.

Comments

@priscilacclr
Copy link

Summary

Hi Doug, thanks for developing this tool, it's a life saver!

I'm encountering an issue where I have a source report with a list of Accounts with their IDs. The scheduler then triggers the Process Builder which runs an Apex class to send an email to contacts associated with that Account ID that meet a set of criteria. This is scheduled to run daily. However, even though I only have up to 3-4 Accounts on the report each day, it only works for one of them. So I know the scheduler is working, but it only picks one record out of the source report. I don't get any error messages and no logs are created. Any ideas of what could be causing this?

Many thanks!

@priscilacclr priscilacclr added the discussion 💬 Discussing usage, best practices, questions, etc. label Apr 5, 2019
@douglascayers
Copy link
Member

Hi @priscilacclr,

Glad you're enjoying Mass Action Scheduler :)

To help identify what might be the cause that you're only seeing some of the accounts in your report being processed, let's do some testing.

Screenshots

Could you provide some screenshots of your Mass Action Configuration record, the target process builder you invoke, and the filter criteria for the source report?

Testing

When testing, always prefer to do so in a sandbox instead of production. If you do test in production, make sure to work with records that won't affect your business users (aka, test/dummy data).

For your configuration, if your source is a report, and your target action is a process builder, then there's at least two places where records could be filtered out and not processed: the report or the process' criteria.

If your process builder has its own set of decision criteria, if the records in your source report to match the process' criteria, then that could be an explanation for records not being processed.

Similarly, if the Apex code that the process builder invokes has its own set of criteria and the source records from the report don't match, then that could be an explanation for records not being processed.

To rule out the process builder, create a new invocable process with one decision diamond that has no criteria (runs for all records) and has one immediate action to do something simple and visible (e.g. post a chatter message to the account or create a task or update a field). Create a new Mass Action Configuration that uses the same source report and uses this new invocable process as it's target action. Once saved, click the "Run" button to run the configuration. If all the records from your report were picked up, then each one will be able to show you the side effect of your process builder (e.g. chatter post, task created, field updated, etc).

@priscilacclr
Copy link
Author

Hi Doug,

Thank you for responding, I appreciate the help here!

For testing, I created a new Process Builder with no criteria and to create Task based on the Account ID from the report. For the record, the Process Builder Action we are trying to troubleshoot also has no criteria, it's one diamond set to always run.
I then created a new Mass Action Configuration with the same source report and the new Invocable Action and ran it. All Tasks were created. So the issue is not on the report or on the Process Builder Action I guess... which leaves the apex code that is being invoked (apex is really not my strong point!)... But this is also weird because if there is more than one record on the report on any given day, I wait for the scheduler to run at its defined time and go check, it only invokes the apex actions for one of records in the report. I then edit the report to remove that one record, and run the scheduler again - it then invokes the action for another single record. I repeat that until I have covered all records and reset the report so it's back to its original state for the next day. This is manageable at the moment because I only have like 1 conflict once or twice per week, but this volume is about to increase exponentially next quarter.

If it was an issue with the apex code, would it not prevent it from running when I run the scheduler manually?

I'm attaching screenshots of the Mass Action config record, the process invoked, the report criteria and the apex class. Thanks again, I'm stuck on this one :)
Report criteria
Builder
Mass Action Config
Apex class

@douglascayers
Copy link
Member

Hi @priscilacclr,

Thanks for the screen shots and the code. I see the problem is line 7 of customerEndDate30Days Apex class.

When Mass Action Scheduler runs, or when multiple records are updated to cause your process to fire in the same transaction (e.g. updating multiple records with Data Loader or something), then your invocable class (just like triggers) gets passed a list of up to 200 records that are being created/updated.

In your report example, when there's multiple accounts in the report then your invocable class is being called once with a list of up to 200 of those accounts at a time. If you had more than 200 accounts in the report then the invocable class would be called a second time, and again for every batch of 200 from the report.

The issue with line 7 is that the acc[0].Id gets the ID of the first account handed to the invocable class, and ignores the others. This is why you see that only one account from the report at a time is being processed because literally the invocable apex class is only processing one record from the list it's been given.

A couple suggestions:

Option A: Tweak the Code

  1. Remove line 7.
  2. Change line 13 to be AND AccountId IN :acc where acc refers to the list of accounts passed to your invocable method at line 5.

A neat feature of Apex Variables in SOQL is that ID field filters can match on either a single ID (e.g. = :myIdVariable) or a list/set of multiple IDs (e.g. IN :myListOrSetOfIds).

Option B: Eliminate the Code

It looks to me like you have some contacts that you want emailed periodically when the contacts meet some criteria.

With Mass Action Scheduler, this can be accomplished with using a Report, List View, or SOQL query as the source and then an Email Alert as your action. The email alert will let you pick the template you want to use, and if it should be sent by an organization-wide email address. The caveat I think is that it might not save the sent email as an activity on the contact as you're able to do with Apex, but that behavior might have changed, not sure.

@douglascayers
Copy link
Member

Another observation, line 27 hardcodes the organization wide email address to use. I suggest performing a SOQL query to determine the ID, just as you do to find the Email Template ID, to make the code a bit more environment agnostic (since the IDs may change from one sandbox to another).

Id orgEmailId = [ SELECT Id, Address, DisplayName FROM OrgWideEmailAddress WHERE Address = 'you@email.com' ].Id

@priscilacclr
Copy link
Author

Oh the relief! That worked! I used option A as we do need to record the email in the activity and we can see whether it was opened or not. Thank you so much for your help!

I did initially find an error saying "An Apex error occurred: System.UnexpectedException: Bad rightOperand type: got SObjectScriptRow: operator e dataType 1". Seems that this is due to the Process Builder that gets a SObjectScriptRow instead of a list of sObject, so I got around that by creating a Set with the Ids.

@douglascayers
Copy link
Member

Great! Thanks for the update

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion 💬 Discussing usage, best practices, questions, etc.
Development

No branches or pull requests

2 participants