importPackage(Packages.de.elo.ix.client); //@include lib_Class.js //@include lib_sol.common.AclUtils.js //@include lib_sol.common.UserUtils.js //@include lib_sol.common.WfUtils.js //@include lib_sol.common.ix.FunctionBase.js var logger = sol.create("sol.Logger", { scope: "sol.common.ix.functions.UserDispatcher" }); /** * Decides, which direction the workflow should be dispatched, regarding the configured requirements. * * Can be used as node exit script. It updates the ELO_WF_STATUS field as configured. The status can be used in a decision node. * * # As workflow node * * Following configuration can be applied to the comments field. * * { * "wfStatus": { "onSuccess": "IS_IN_GROUP", "onFailure": "NOT_IN_GROUP" }, * "requirements": [ * { "type": "inGroup", "value": "sol.pubsec.admin.Record" } * ] * } * * @author PZ, ELO Digital Office GmbH * @version 1.03.000 * * @eloix * @requires sol.common.UserUtils * @requires sol.common.WfUtils * @requires sol.common.ix.FunctionBase * */ sol.define("sol.common.ix.functions.UserDispatcher", { extend: "sol.common.ix.FunctionBase", requiredConfig: ["wfDiagram", "userId", "objId"], /** * @cfg {de.elo.ix.client.WFDiagram} wfDiagram (required) * The workflow which should be checked. */ /** * @cfg {String} userId (required) * The ID of the user, who should be checked. */ /** * @cfg {String} objId (required) * ID of the element which should be checked */ /** * @cfg {Object} wfStatus * * "wfStatus": { "onSuccess": "left", "onFailure": "right" } * * This object can override the default workflow states which will be set after the check, if ths was used in a workflow node. * If the is `undefined`, the function will throw an exception in case the checke fails. * * - `onSuccess`: set as ELO_WF_STATUS after a successfull check * - `onFailure`: set as ELO_WF_STATUS after a check failure */ /** * @cfg {Object[]} requirements * This is an array with configurations which requirements a user has to fullfill. If empty, the check always succeeds. * * "requirements": [ * { "type": "inGroup", "value": "sol.pubsec.admin.Record" }, * { "type": "inGroup", "value": "sol.pubsec.sysadmin.Record" }, * { "type": "hasEffectiveRights", "rights": { "rights": { "d": "true" } } } * ] * * With this configuration the check would only succeed, if the user is in both groups ('sol.pubsec.admin.Record' and 'sol.pubsec.sysadmin.Record'). * The value can also be the group ID. */ /** * @cfg {Object} nextNodes * * "nextNodes": { "onSuccess": ["OK", "Approve"], "onFailure": ["Cancel", "Reject"] } * * or * * "nextNodes": { "onSuccess": "OK", "onFailure": "Cancel" } * * This object determines the next nodes to activate in dependence of the workflow status. * * - `onSuccess`: array of next nodes or string of one next node to activate after a successfull check * - `onFailure`: array of next nodes or string of one next node to activate after a check failure */ /** * @private * @property {String} [DEFAULT_PASSED_STATUS="SUCCESS"] Default workflow status in case of a successful check */ DEFAULT_PASSED_STATUS: "SUCCESS", /** * @private * @property {String} [DEFAULT_FAILED_STATUS="FAILURE"] Default workflow status in case of a check failure */ DEFAULT_FAILED_STATUS: "FAILURE", initialize: function (config) { var me = this; me.$super("sol.common.ix.FunctionBase", "initialize", [config]); }, /** * Performs the check. */ process: function () { var me = this, status, nextNodes, i, node, succNodes; if (me.checkRequirements()) { status = (me.wfStatus && me.wfStatus.onSuccess) ? me.wfStatus.onSuccess : me.DEFAULT_PASSED_STATUS; nextNodes = (me.nextNodes && me.nextNodes.onSuccess) ? me.nextNodes.onSuccess : undefined; } else { status = (me.wfStatus && me.wfStatus.onFailure) ? me.wfStatus.onFailure : me.DEFAULT_FAILED_STATUS; nextNodes = (me.nextNodes && me.nextNodes.onFailure) ? me.nextNodes.onFailure : undefined; } sol.common.WfUtils.setWorkflowStatus(me.wfDiagram, status); if (nextNodes) { if (sol.common.ObjectUtils.isString(nextNodes)) { nextNodes = [nextNodes]; } else if (!sol.common.ObjectUtils.isArray(nextNodes)) { throw "nextNodes has incorrect datatype"; } succNodes = sol.common.WfUtils.getSuccessorNodes(me.wfDiagram, me.nodeId); for (i = 0; i < succNodes.length; i++) { node = succNodes[i]; if (nextNodes.indexOf(String(node.name)) < 0) { node.allowActivate = false; } else { node.isNext = 1; } } } }, /** * @private * Checks, if the configured requirements are meet. * @return {Boolean} */ checkRequirements: function () { var me = this, checkResult = false; if (me.requirements && (me.requirements.length > 0)) { checkResult = me.requirements.every(function (requirement) { return me.checkRequirement(requirement); }); } else { checkResult = true; } return checkResult; }, /** * @private * Checks an inividual requirement. * @param {Object} requirement * @return {Boolean} */ checkRequirement: function (requirement) { var me = this; switch (requirement.type) { case "inGroup": return sol.common.UserUtils.isInGroup(requirement.value, { userId: me.userId }); case "hasEffectiveRights": return sol.common.AclUtils.hasEffectiveRights(me.objId, { rights: requirement.rights }); default: return false; } } }); /** * @member sol.common.ix.functions.UserDispatcher * @static * @inheritdoc sol.common.ix.FunctionBase#onExitNode */ function onExitNode(clInfo, userId, wFDiagram, nodeId) { var params, module; logger.enter("onExitNode_UserDispatcher", { flowId: wFDiagram.id, nodeId: nodeId }); params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId); params.wfDiagram = wFDiagram; params.userId = userId; params.objId = wFDiagram.objId; params.nodeId = nodeId; module = sol.create("sol.common.ix.functions.UserDispatcher", params); module.process(); logger.exit("onExitNode_UserDispatcher"); }