Рабочий процесс: асинхронная обработка в режиме, близком к реальному времени

Итак, я некоторое время работал с Workflows (или SuiteFlow) и хотел задокументировать несколько вещей, чтобы через некоторое время они могли быть полезны другим и мне тоже :).

  1. Вы можете запускать рабочие процессы вручную, используя следующие 2 модуля,
    N/задача и N/рабочий процесс, где модуль задач создает запись в очереди для указанного рабочего процесса и обрабатывается асинхронно, в то время как в модуле рабочего процесса он обрабатывается в в реальном времени.
  2. Если вы использовали модуль задач для передачи значений в параметры скриптов, вы можете использовать его для передачи значений в рабочий процесс, при условии, что вы создали параметры в своем рабочем процессе :). Но вы не можете прочитать их (в пользовательском действии рабочего процесса), как в сценарии Map/Reduce или Scheduled Script.
    Таким образом, чтобы прочитать значения из параметра рабочего процесса/состояния, вы должны сначала создать параметр сценария в своем пользовательский рабочий процесс и передать ему значение по умолчанию в действии из состояния рабочего процесса, а затем прочитать значение из параметра сценария действия рабочего процесса.
  3. Если ваш рабочий процесс имеет несколько состояний/действий и вы хотите пропустить некоторые из них, вы можете использовать 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 обработает его как если кнопка была нажата каким-либо пользователем.