Source: process.js

  1. /**
  2. * @file Process class to manage/run workflow rule and approval process
  3. * @author Shinichi Tomita <shinichi.tomita@gmail.com>
  4. */
  5. 'use strict';
  6. var _ = require('lodash/core'),
  7. Promise = require('./promise'),
  8. Conneciton = require('./connection');
  9. /**
  10. * A class which manages process rules and approval processes
  11. *
  12. * @class
  13. * @param {Connection} conn - Connection object
  14. */
  15. var Process = module.exports = function(conn) {
  16. /**
  17. * Object which mangages process rules
  18. * @member {Process~ProcessRule} Process#rule
  19. */
  20. this.rule = new ProcessRule(conn);
  21. /**
  22. * Object which mangages approval process
  23. * @member {Process~ApprovalProcess} Process#approval
  24. */
  25. this.approval = new ApprovalProcess(conn);
  26. };
  27. /**
  28. * A class which manages process (workflow) rules
  29. *
  30. * @class Process~ProcessRule
  31. * @param {Connection} conn - Connection object
  32. */
  33. var ProcessRule = function(conn) {
  34. this._conn = conn;
  35. };
  36. /**
  37. * @typedef {Object} Process~ProcessRuleDefinition
  38. * @prop {String} id - Id of approval process definition
  39. * @prop {String} name - Name of process rule definition
  40. * @prop {String} object - SObject name which process rule is defined
  41. */
  42. /**
  43. * Get all process rule definitions registered to sobjects
  44. *
  45. * @method Process~ProcessRule#list
  46. * @param {Callback.<Map.<String, Array.<Process~ProcessRuleDefinition>>>} [callback] - Callback function
  47. * @returns {Promise.<Map.<String, Array.<Process~ProcessRuleDefinition>>>}
  48. */
  49. ProcessRule.prototype.list = function(callback) {
  50. return this._conn.request("/process/rules").then(function(res) {
  51. return res.rules;
  52. }).thenCall(callback);
  53. };
  54. /**
  55. * @typedef {Object} Process~ProcessRuleTriggerResult
  56. * @prop {Boolean} success - Is process rule trigger succeeded or not
  57. * @prop {Array.<Object>} errors - Array of errors returned if the request failed
  58. */
  59. /**
  60. * Trigger process rule for given entities
  61. *
  62. * @method Process~ProcessRule#trigger
  63. * @param {String|Array.<String>} contextIds - Entity ID(s) to trigger workflow process
  64. * @param {Callback.<Process~ProcessRuleTriggerResult>} [callback] - Callback function
  65. * @returns {Promise.<Process~ProcessRuleTriggerResult>}
  66. */
  67. ProcessRule.prototype.trigger = function(contextIds, callback) {
  68. contextIds = _.isArray(contextIds) ? contextIds : [ contextIds ];
  69. return this._conn.request({
  70. method: "POST",
  71. url: "/process/rules/",
  72. body: JSON.stringify({
  73. contextIds: contextIds
  74. }),
  75. headers: {
  76. "content-type": "application/json"
  77. }
  78. }).thenCall(callback);
  79. };
  80. /**
  81. * A class which manages approval processes
  82. *
  83. * @class Process~ApprovalProcess
  84. * @param {Connection} conn - Connection object
  85. */
  86. var ApprovalProcess = function(conn) {
  87. this._conn = conn;
  88. };
  89. /**
  90. * @typedef {Object} Process~ApprovalProcessDefinition
  91. * @prop {String} id - Id of approval process definition
  92. * @prop {String} name - Name of approval process definition
  93. * @prop {String} object - SObject name which approval process is defined
  94. * @prop {Number} sortOrder - Processing order of approval in SObject
  95. */
  96. /**
  97. * Get all approval process definitions registered to sobjects
  98. *
  99. * @method Process~ApprovalProcess#list
  100. * @param {Callback.<Map.<String, Array.<ApprovalProcessDefinition>>>} [callback] - Callback function
  101. * @returns {Promise.<Map.<String, Array.<ApprovalProcessDefinition>>>}
  102. */
  103. ApprovalProcess.prototype.list = function(callback) {
  104. return this._conn.request("/process/approvals").then(function(res) {
  105. return res.approvals;
  106. }).thenCall(callback);
  107. };
  108. /**
  109. * @typedef {Object} Process~ApprovalProcessRequestResult
  110. * @prop {Boolean} success - True if processing or approval completed successfully
  111. * @prop {Array.<Object>} errors - The set of errors returned if the request failed
  112. * @prop {Array.<String>} actorIds - IDs of the users who are currently assigned to this approval step
  113. * @prop {String} entityId - Object being processed
  114. * @prop {String} instanceId - ID of the ProcessInstance associated with the object submitted for processing
  115. * @prop {String} instanceStatus - Status of the current process instance (not an individual object but the entire process instance)
  116. * @prop {Array.<String>} newWorkItemIds - Case-insensitive IDs that point to ProcessInstanceWorkitem items (the set of pending approval requests)
  117. */
  118. /**
  119. * Send bulk requests for approval process
  120. *
  121. * @method Process~ApprovalProcess#request
  122. * @param {Array.<ApprovalProcessRequest>} requests - Array of approval process request to send
  123. * @param {Callback.<Array.<ApprovalProcessRequestResult>>} - Callback function
  124. * @param {Promise.<Array.<ApprovalProcessRequestResult>>}
  125. */
  126. ApprovalProcess.prototype.request = function(requests, callback) {
  127. requests = requests.map(function(req) {
  128. return req._request ? req._request : req;
  129. });
  130. return this._conn.request({
  131. method: 'POST',
  132. url: '/process/approvals',
  133. headers: { "content-type": "application/json" },
  134. body: JSON.stringify({ requests: requests })
  135. }).thenCall(callback);
  136. };
  137. /**
  138. * Create approval process request
  139. *
  140. * @private
  141. */
  142. ApprovalProcess.prototype._createRequest = function(actionType, contextId, comments, options, callback) {
  143. if (typeof comments === "function") {
  144. callback = comments;
  145. options = null;
  146. comments = null;
  147. }
  148. if (typeof options === "function") {
  149. callback = options;
  150. options = null;
  151. }
  152. options = options || {};
  153. var request = {
  154. actionType: actionType,
  155. contextId: contextId,
  156. comments: comments
  157. };
  158. _.extend(request, options);
  159. return new ApprovalProcessRequest(this, request).thenCall(callback);
  160. };
  161. /**
  162. * Submit approval request for an item
  163. *
  164. * @method Process~ApprovalProcess#submit
  165. * @param {String} contextId - ID of the item that is being acted upon
  166. * @param {String} [comments] - Comment to add to the history step associated with this request
  167. * @param {Object} [options] - Request parameters
  168. * @param {Array.<String>} [options.nextApproverIds] - If the process requires specification of the next approval, the ID of the user to be assigned the next request
  169. * @param {String} [options.processDefinitionNameOrId] - Developer name or ID of the process definition
  170. * @param {Boolean} [options.skipEntryCriteria] - Determines whether to evaluate the entry criteria for the process (true) or not (false) if the process definition name or ID isn’t null
  171. * @param {Callback.<ApprovalProcessRequestResult>} [callback] - Callback function
  172. * @returns {ApprovalProcessRequest}
  173. */
  174. ApprovalProcess.prototype.submit = function(contextId, comments, options, callback) {
  175. return this._createRequest("Submit", contextId, comments, options, callback);
  176. };
  177. /**
  178. * Approve approval request for an item
  179. *
  180. * @method Process~ApprovalProcess#approve
  181. * @param {String} workitemId - ID of the item that is being acted upon
  182. * @param {String} [comments] - Comment to add to the history step associated with this request
  183. * @param {Object} [options] - Request parameters
  184. * @param {Array.<String>} [options.nextApproverIds] - If the process requires specification of the next approval, the ID of the user to be assigned the next request
  185. * @param {String} [options.processDefinitionNameOrId] - Developer name or ID of the process definition
  186. * @param {Boolean} [options.skipEntryCriteria] - Determines whether to evaluate the entry criteria for the process (true) or not (false) if the process definition name or ID isn’t null
  187. * @param {Callback.<ApprovalProcessRequestResult>} [callback] - Callback function
  188. * @returns {ApprovalProcessRequest}
  189. */
  190. ApprovalProcess.prototype.approve = function(workitemId, comments, options, callback) {
  191. return this._createRequest("Approve", workitemId, comments, options, callback);
  192. };
  193. /**
  194. * Reject approval request for an item
  195. *
  196. * @method Process~ApprovalProcess#reject
  197. * @param {String} workitemId - ID of the item that is being acted upon
  198. * @param {String} [comments] - Comment to add to the history step associated with this request
  199. * @param {Object} [options] - Request parameters
  200. * @param {Array.<String>} [options.nextApproverIds] - If the process requires specification of the next approval, the ID of the user to be assigned the next request
  201. * @param {String} [options.processDefinitionNameOrId] - Developer name or ID of the process definition
  202. * @param {Boolean} [options.skipEntryCriteria] - Determines whether to evaluate the entry criteria for the process (true) or not (false) if the process definition name or ID isn’t null
  203. * @param {Callback.<ApprovalProcessRequestResult>} [callback] - Callback function
  204. * @returns {ApprovalProcessRequest}
  205. */
  206. ApprovalProcess.prototype.reject = function(workitemId, comments, options, callback) {
  207. return this._createRequest("Reject", workitemId, comments, options, callback);
  208. };
  209. /**
  210. * A class representing approval process request
  211. *
  212. * @protected
  213. * @class Process~ApprovalProcessRequest
  214. * @implements {Promise.<Process~ApprovalProcessRequestResult>}
  215. * @param {Process~ApprovalProcess} process - ApprovalProcess
  216. * @param {Object} request - Request parameters
  217. * @param {String} request.actionType - Represents the kind of action to take: Submit, Approve, or Reject
  218. * @param {String} request.contextId - ID of the item that is being acted upon
  219. * @param {String} request.comments - Comment to add to the history step associated with this request
  220. * @param {Array.<String>} [request.nextApproverIds] - If the process requires specification of the next approval, the ID of the user to be assigned the next request
  221. * @param {String} [request.processDefinitionNameOrId] - Developer name or ID of the process definition
  222. * @param {Boolean} [request.skipEntryCriteria] - Determines whether to evaluate the entry criteria for the process (true) or not (false) if the process definition name or ID isn’t null
  223. */
  224. var ApprovalProcessRequest = function(process, request) {
  225. this._process = process;
  226. this._request = request;
  227. };
  228. /**
  229. * Promise/A+ interface
  230. * http://promises-aplus.github.io/promises-spec/
  231. *
  232. * @method Process~ApprovalProcessRequest#then
  233. */
  234. ApprovalProcessRequest.prototype.then = function(onResolve, onReject) {
  235. if (!this._promise) {
  236. this._promise = this._process.request([ this ]).then(function(rets) {
  237. return rets[0];
  238. });
  239. }
  240. this._promise.then(onResolve, onReject);
  241. };
  242. /**
  243. * Promise/A+ extension
  244. * Call "then" using given node-style callback function
  245. *
  246. * @method Process~ApprovalProcessRequest#thenCall
  247. */
  248. ApprovalProcessRequest.prototype.thenCall = function(callback) {
  249. return callback ? this.then(function(res) {
  250. callback(null, res);
  251. }, function(err) {
  252. callback(err);
  253. }) :
  254. this;
  255. };