Рабочий процесс: асинхронная обработка в режиме, близком к реальному времени
Итак, я некоторое время работал с Workflows (или SuiteFlow) и хотел задокументировать несколько вещей, чтобы через некоторое время они могли быть полезны другим и мне тоже :).
- Вы можете запускать рабочие процессы вручную, используя следующие 2 модуля,
N/задача и N/рабочий процесс, где модуль задач создает запись в очереди для указанного рабочего процесса и обрабатывается асинхронно, в то время как в модуле рабочего процесса он обрабатывается в в реальном времени. - Если вы использовали модуль задач для передачи значений в параметры скриптов, вы можете использовать его для передачи значений в рабочий процесс, при условии, что вы создали параметры в своем рабочем процессе :). Но вы не можете прочитать их (в пользовательском действии рабочего процесса), как в сценарии Map/Reduce или Scheduled Script.
Таким образом, чтобы прочитать значения из параметра рабочего процесса/состояния, вы должны сначала создать параметр сценария в своем пользовательский рабочий процесс и передать ему значение по умолчанию в действии из состояния рабочего процесса, а затем прочитать значение из параметра сценария действия рабочего процесса. - Если ваш рабочий процесс имеет несколько состояний/действий и вы хотите пропустить некоторые из них, вы можете использовать workflow.trigger.
например. У вас есть рабочий процесс с двумя состояниями, где State#1 добавляет кнопку в SalesOrder, а при ее нажатии вы хотите, чтобы она перешла в State#2, где у вас есть логика для выполнения какой-либо другой операции. В этом случае вы не хотите застревать в состоянии № 1 (где вы просто добавляете кнопку и ждете, пока пользователь нажмет кнопку, вместо этого вы хотите инициировать нажатие кнопки) при запуске рабочего процесса из скрипта, поэтому в этом случае вы можете используйте workflow.trigger и передайте ему ActionId, который является действием, которое добавляет кнопку в SalesOrder, как в нашем случае в State # 1, и это будет работать так, как если бы пользователь нажал кнопку из пользовательского интерфейса, и он будет переведен в наше State # 2 из рабочий процесс.
У нас был сценарий, в котором мы хотели обновить запись клиента после обновления пользовательской записи, теперь, когда пользователь был в пользовательской записи, и это можно было сделать в фоновом режиме асинхронно без вмешательства пользователя, поэтому вместо написания всего скрипта для обновления записи клиента в пользовательского события, мы запустили рабочий процесс с помощью модуля задач, который, в свою очередь, обновил запись о клиенте. Чтобы запустить рабочий процесс с помощью модуля задач, вы можете использовать следующее:
require(['N/task'], function (task) { var workflow = {}; /** * * @param {Object} args * @prop {Object} args.params * @prop {String} args.recordId * @prop {String} args.recordType * @prop {String} args.workflowId */ function trigger(args) { var taskId = task.create(util.extend({ taskType: task.TaskType.WORKFLOW_TRIGGER, }, args)) .submit(); log.debug({ title: 'Workflow Task Details', details: { taskId: taskId, taskStatus: workflow.getStatus({ taskId: taskId }) } } }); return taskId; } /** * * @param {String} taskId * * @return {String} TASK_STATUS */ function getStatus(taskId) { return task.checkStatus({ taskId: taskId }).status; } workflow.trigger = trigger; workflow.getStatus = getStatus; return workflow; } );
Теперь рассмотрим сценарий, в котором вы хотите обновить запись в пользовательском событии (suitelet, map/reduce, restlet и т. д.), для которого у вас уже есть логика в рабочем процессе, и вам нужны эти значения, прежде чем вы сможете двигаться дальше, вы может не захотеть снова копировать тот же сценарий, чтобы избежать избыточности кода. В этом случае вы можете использовать модуль рабочего процесса для запуска рабочего процесса в синхронном режиме, и после его завершения ваша текущая запись будет обновлена или будет отражать последние значения после выполнения рабочего процесса.
Если вы хотите запустить рабочий процесс из определенного состояния, например, ваш рабочий процесс сначала добавляет кнопку, а при нажатии кнопки вы хотите выполнить какую-либо операцию, вы можете использовать модуль рабочего процесса, как показано ниже, и передать stateId
require(['N/workflow'], function (workflow) { /** * @desc if stateId/actionId is passed, * calls `workflow.trigger` to take workflow at specific * state/action specified * * @param {Object} args * @prop {String} args.stateId * @prop {String} args.actionId * @prop {String} args.recordId * @prop {String} args.workflowId * @prop {String} args.recordType * @prop {Object} args.defaultValues */ function trigger(args) { return (args.stateId || args.actionId) ? workflow.trigger(args) : workflow.initiate(args); } return { trigger: trigger }; } );
Если вы хотите напрямую перейти в определенное состояние, вы можете передать ему stateId, а если вы хотите выполнить определенное действие в состоянии, вы можете передать actionId, например, если вы передадите actionId кнопки, NetSuite обработает его как если кнопка была нажата каким-либо пользователем.