SuiteScript Design - The (Good) Man-in-the-Middle
Created: November 13, 2020
One of the more frustrating limitations when building SuiteScript systems is that User Event scripts do not trigger each other. Take an exceedingly common use case where there is a User Event on the Sales Order which automatically transforms the Sales Order into an Invoice. Chances are, there are also User Events deployed to the Invoice, but none of those will be triggered by our Sales Order User Event.
RAWR! This can be extremely frustrating when building complex systems involving chains of records. The limitation exists for good reason: it would be incredibly easy to - either accidentally or intentionally - create an infinite loop of User Events going back and forth triggering each other, essentially locking out any other processing.
There is, however, a design pattern you can use to work around this limitation. I call it the "Suitelet Man-in-the-Middle", although I should probably come up with something else to call it given the baggage that phrase carries in our space. (I'm open to suggestions, email me with yours!)
Update: A helpful reader wrote in and said their team calls these "Jumplets", and I have since lovingly adopted this name for the pattern described here. You can also find example code here.
User Events do not chain together, but record actions performed by Suitelets do trigger User Events. Thus, instead of our Sales Order User Event creating the Invoice directly, we can instead create a back-end Suitelet (i.e. a Suitelet with no UI components) that will do our Invoice creation for us.
The Sales Order User Event sends a request to the Suitelet with any relevant data (usually a record ID will suffice), the Suitelet receives the data from the Sales Order, transforms it into an Invoice, and saves the Invoice. When the Suitelet saves the Invoice, any User Events and Workflows deployed to the Invoice will trigger as well.
Wherever you want to trigger sequential User Events, you can insert a back-end Suitelet in between each pair of User Events (hence the pattern's name), and the chain of User Events will happily go on as long as you want them to.