Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mikemurray
Last active December 18, 2015 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikemurray/1111c0635ef73037ace7 to your computer and use it in GitHub Desktop.
Save mikemurray/1111c0635ef73037ace7 to your computer and use it in GitHub Desktop.
Proposed steps to setting and validation a workflow status using collection hooks

Somewhere in reaction...

STEP 1: meteor call to push a new workflow

NOTE: coreOrderWorkflow, processing will be combined into coreOrderWorkflow/processing and set as the status.

Meteor.call("workflow/pushOrderWorkflow", "coreOrderWorkflow", "processing", order);

On the server...

STEP 2: workflow/pushOrderWorkflow tries to update the current status

Meteor.methods({
  /**
   * workflow/pushOrderWorkflow
   * Push the status as the current workflow step,
   * move the current status to completed worflow steps
   * @summary Update the order workflow
   * @param  {String} workflow workflow to push to
   * @param  {String} status - Workflow status
   * @param  {Order} order - ReactionCore.Schemas.Order, an order object
   * @return {Boolean} true if update was successful
   */
  "workflow/pushOrderWorkflow": function (workflow, status, order) {
    check(workflow, String);
    check(status, String);
    check(order, Object); // TODO: Validatate as ReactionCore.Schemas.Order
    this.unblock();

    const result = ReactionCore.Collections.Orders.update({
      _id: order._id
    }, {
      $set: {

        // Combine (workflow) "coreOrderWorkflow", (status) "processing" into "coreOrderWorkflow/processing".
        // This combo will be used to call the method "workflow/coreOrderWorkflow/processing", if it exists.
        "workflow.status": `${workflow}/${status}`
      },
      $addToSet: {
        "workflow.workflow": order.workflow.status
      }
    });

    return result;
  }
});

Somewhere common (client and server)...

STEP 3: Order update before hook runs and calls a method named after the status (coreOrderWorkflow/processing) to verify that it's allowed to be set on this order.

ReactionCore.Collections.Orders.before.update(function (userId, order, fieldNames, modifier) {
  // if we're setting something on the order
  if (modifier.$set) {
    // Updating status of order e.g. "coreOrderWorkflow/processing"
    if (modifier.$set["workflow.status"]) {
      let status = modifier.$set["workflow.status"];
      let workflowMethod = `workflow/${status}`;

      if (Meteor.isServer) {
        if (Meteor.server.method_handlers[workflowMethod]) {
          const result = Meteor.call(workflowMethod, {
            userId,
            order,
            modifier
          });

          // Result should be true / false to all or disallow updating the status
          return result;
        }
      }
    }
  }
});

On The server...

Step 4: workflow/coreOrderWorkflow/coreOrderProcessing is called from the Orders.before.update Hook

Checks if the user has dashboard/orders access, return true or false

false in this situation will stop the Orders.before.update HOOK from updating the order document.

Meteor.methods({
  /**
   * workflow/coreOrderWorkflow/coreOrderProcessing
   * Workflow method that checks permissions for a given user to allow them to
   * move an order into the processing phase.
   * @param  {Object} options An object containing arbitary data
   * @return {Boolean} true to allow action, false to cancel execution of hook
   */
  "workflow/coreOrderWorkflow/coreOrderProcessing": function (options) {
    check(options, Match.OrderHookOptions());
    const userId = options.userId;

    return ReactionCore.hasPermission(["dashboard/orders"], userId);
  }
});

Other modifications

// reaction-core/server/register.js
...
{
  template: "coreOrderProcessing",
  label: "Order Processing",
  // Added status so the template name is no longer tied to the status
  // This would allow you to use multiple templates for a given workflow status
  status: "processing",
  workflow: "coreOrderWorkflow",
  audience: ["dashboard/orders"]
}
...
// reaction-schemas/common/schemas.js
...
status: {
  type: String,
  optional: true
},
...
@aaronjudd
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment