FactoryFour Learn Center Index

Last updated September 8, 2019


Add Multiple Workflows from Product Selections

Add multiple workflows to an order when product selections are made.


Description:

Some order types are designed to let users select multiple single products for a single order. Fulfilling each product typically requires a unique workflow, and usually this mapping follows some consistent logic.

How to Use:

  1. Create a Custom Order Status Rule where the Scope is triggered when an Order moves from ‘Pending’ to ‘Progress’ state, a.k.a when the order is released for production
  2. For the rule action, use the below snippet
  3. Make sure you have loaded axios

  4. In the below part of the snippet, modify the GetWorkflows function to return a list of workflows that should be added.
  5. Make sure you save the code in the editor, and turn the rule on

Snippet:

const axios = require('axios');

const URL_BASE = 'https://api.factoryfour.com';

/*
* Return an array of workflows that should be added
* entries [{
* 	type: string, Product manifest type of selection
* 	options: object, Options selected in manifest
* 	stage_id: string, ID of the stage that was added
* 	model: object, Options selected in the stage
* 	title: string Title assigned to the manifest
* }]
* */
const getWorkflows = (entries) => {
	const workflows = [];
	entries.forEach((entry) => {
		if (entry.type === 'Tw') {
			workflows.push({
				name: entry.title,
				code: 'workflow_a',
			});
		} else {
			workflows.push({
				name: entry.title,
				code: 'workflow_b',
			});
		}
	});
	return workflows;
};

// ======================================================================================================================

/*
 * Retrieve a valid FactoryFour token from the headers in the context
 */
const getToken = (ctx) => {
	const token = ctx.headers['x-factoryfour-token'];
	if (!token) {
		throw new Error('Unable to find token in context');
	}
	return token;
};

/*
 * Fetch the order this form was submitted on from the context
 */
const getOrderId = (ctx) => {
	const orderId = ctx.body.order.id;
	if (!orderId) {
		throw new Error('Could not find an order for this form');
	}
	return orderId;
};

/*
 * Make calls to the FactoryFour API using the token passed to this rule and the workflowCode specified
 */
const addAndInitWorkflow = (data, token) => {
	// Format the headers for the request
	const headers = {
		Authorization: `Bearer ${token}`,
	};

	// Create a new workflow object
	return axios({
		method: 'POST',
		url: `${URL_BASE}/workflows/`,
		headers,
		data,
	})
		.then((res) => {
			const workflowId = res.data.data.workflow.id;

			// Initialize the newly created workflow to create tasks
			const optionsInit = {
				method: 'POST',
				url: `${URL_BASE}/workflows/${workflowId}/initiate`,
				headers,
				json: true,
			};
			return axios(optionsInit);
		});
};

const getManifestEntries = (context) => {
	const { formData } = context.body;
	if (!formData) {
		console.error('No form data found');
		return [];
	}
	if (!formData.Manifest || !formData.Manifest.manifest || !formData.Manifest.manifest.entries) {
		console.error('Could not find manifest information');
		return [];
	}
	const { entries } = formData.Manifest.manifest;
	const entriesOut = entries.map((e) => ({
		type: e.type,
		options: e.options.model,
		model: formData[e.id],
		title: e.title,
		stage_id: e.stage_id,
	}));
	return entriesOut;
};

module.exports = (context, cb) => {
	const token = getToken(context);
	const orderId = getOrderId(context);

	const workflowsToAdd = getWorkflows(getManifestEntries(context));
	const workflowCreationPromises = [];
	if (workflowsToAdd) {
		// if no workflow was found, exit with no further action
		if (!Array.isArray(workflowsToAdd)) {
			console.error('Workflow creation requires an array');
			return cb('Workflow creation requires an array');
		}
		workflowsToAdd.forEach((wf) => {
			workflowCreationPromises.push(addAndInitWorkflow({
				format: 'order',
				parent: `f4::order::${orderId}`,
				code: wf.code,
				name: wf.name ? wf.name : undefined,
			}, token));
		});
	}
	return Promise.all(workflowCreationPromises)
		.then(() => cb(null, 'Created workflows'))
		.catch((err) => {
			console.error(err);
			return cb('Could not add workflows successfully');
		});
};

Search the FactoryFour Learn Center


FactoryFour Learn Center