importPackage(Packages.de.elo.ix.client);
//@include lib_Class.js
//@include lib_sol.common.IxUtils.js
//@include lib_sol.common.Template.js
//@include lib_sol.common.Injection.js
//@include lib_sol.common.UserUtils.js
//@include lib_sol.common.JsonUtils.js
//@include lib_sol.common.SordUtils.js
//@include lib_sol.common.ObjectUtils.js
//@include lib_sol.common.ix.FunctionBase.js
//@include lib_sol.common.ObjectFormatter.MapTableToArray.js
var logger = sol.create("sol.Logger", { scope: "sol.common.ix.functions.ChangeGroup" });
/**
* Changes the given ELO group.
*
* It is possible to add new members to the ELO group or remove existing members.
*
* When the user is already a member of the ELO group nothing will be happen
*
* ### Retrieving user list from mapTable
*
* In the example all userNames will be returned where the field MEETING_PERSON_CRUD_STATUS is
* equal `CREATE`. With `propSelector` you can reach that the function returns an array with plain
* strings instead of an object
*
* "addMembers": [
* {
* "type": "WFMAP",
* "key": ["MEETING_PERSON_USERNAME", "MEETING_PERSON_CRUD_STATUS"],
* "table": true,
* "propSelector": "MEETING_PERSON_USERNAME",
* "filter": [
* { "prop": "MEETING_PERSON_CRUD_STATUS", "value": "CREATE" }
* ]
* }
* ]
*
* Hint: You have to pass the flowId to the function to enable WFMAP fields
*
* # As workflow node
*
* ObjId is set based on the element that the workflow is attached to.
* Following additional configuration can be applied to the comments field.
*
* {
* "groupName": "New Group"
* }
*
* # As IX function call
*
* In addition to the workflow node configuration the objId must be passed.
*
* sol.common.IxUtils.execute("RF_sol_function_ChangeGroup", {
* groupName: "group",
* addMembers: ["renz", "kraft"],
* removeMembers: ["eichner"]
* });
*
* @eloix
* @requires sol.common.IxUtils
* @requires sol.common.WfUtils
* @requires sol.common.Template
* @requires sol.common.Injection
* @requires sol.common.ix.RfUtils
* @requires sol.common.ix.JsonUtils
* @requires sol.common.ix.ObjectUtils
* @requires sol.common.ix.FunctionBase
* @requires sol.common.ObjectFormatter.MapTableToArray
*
*/
sol.define("sol.common.ix.functions.ChangeGroup", {
extend: "sol.common.ix.FunctionBase",
/**
* @cfg groupName
*/
/**
* @cfg {Boolean} [asAdmin=false] (optional)
* When `asAdmin` is set to true the operation will be execute with an admin connection
*/
mixins: ["sol.common.mixins.Inject"],
inject: {
name: { prop: "groupName", template: true },
sord: { sordIdFromProp: "objId", flowIdFromProp: "flowId", optional: false }
},
TEMPLATESORDACCESSORS: {
SORD: "",
GRP: "objKeys.",
MAP: "mapKeys.",
WFMAP: "wfMapKeys."
},
/**
* @cfg {String} groupName
* The name of the new group. Templating is possible if objId/flowId is passed to the function
*/
/**
* @cfg {Array<Object>|Object|String} addMembers
*
*/
/**
* @cfg {Array<Object>|Object|String} removeMembers
*/
initialize: function (config) {
var me = this;
if (config.addMembers && !sol.common.ObjectUtils.isArray(config.addMembers)) {
config.addMembers = [config.addMembers];
}
if (config.removeMembers && !sol.common.ObjectUtils.isArray(config.removeMembers)) {
config.removeMembers = [config.removeMembers];
}
me.$super("sol.common.ix.FunctionBase", "initialize", [config]);
me.checkConfig();
me.connection = ((me.asAdmin === true) && (typeof ixConnectAdmin !== "undefined")) ? ixConnectAdmin : ixConnect;
},
checkConfig: function () {
var me = this, flowIdIsNecessary,
checkWorkflowIsNecessary = function (entry) {
return entry && entry.type === "WFMAP";
};
flowIdIsNecessary = (me.addMembers || []).some(checkWorkflowIsNecessary)
|| (me.removeMembers || []).some(checkWorkflowIsNecessary);
if (flowIdIsNecessary && !me.flowId) {
throw Error("Your configuration contains WFMAP fields. `flowId` must be passed to the function");
}
},
/**
*
*/
process: function () {
var me = this, addMembers, removeMembers,
groupName = me.getGroupName();
try {
if (me.shouldAddMembers()) {
// add users to created group
me.logger.debug(["addMembers {0}", JSON.stringify(me.addMembers)]);
addMembers = me.prepareUserList(me.addMembers || []);
if (!me.$dryRun) {
me.addUsersToGroups(addMembers, [groupName]);
}
}
if (me.shouldRemoveMembers()) {
removeMembers = me.prepareUserList(me.removeMembers || []);
if (!me.$dryRun) {
me.removeUsersFromGroups(removeMembers, [groupName]);
}
}
} catch (ex) {
me.logger.warn(["An error occured {0}", ex.message], ex);
throw ex;
}
return {
name: groupName,
addMembers: addMembers,
removeMembers: removeMembers
};
},
getGroupName: function () {
var me = this, key;
if (sol.common.ObjectUtils.isString(me.groupName)) {
return me.groupName;
} else if (me.groupName && me.groupName.type) {
// complex object { type: "GRP", "key": "FIELDNAME" }
if (!me.groupName || !me.hasAccesssorKey(me.groupName)) {
throw Error("process type " + me.groupName.type + "is not supported currently");
}
key = me.getAccessor(me.groupName);
return sol.common.ObjectUtils.getProp(me.sord, key);
} else {
throw Error("Could not determine groupName");
}
},
/**
* @private
* @returns
*/
shouldAddMembers: function () {
var me = this;
return me.addMembers && me.addMembers.length > 0;
},
/**
* @private
* @returns
*/
shouldRemoveMembers: function () {
var me = this;
return me.removeMembers && me.removeMembers.length > 0;
},
/**
* @private
* @param {} names
* @param {*} targetGroups
*/
addUsersToGroups: function (names, targetGroups) {
var me = this;
me.logger.debug(["addUsersToGroups {0} {1}", names, targetGroups]);
sol.common.UserUtils.addUsersToGroups(names, targetGroups, {
connection: me.connection
});
},
/**
* @private
* @param {} names
* @param {*} targetGroups
*/
removeUsersFromGroups: function (names, targetGroups) {
var me = this;
me.logger.debug(["removeUsersFromGroups {0} {1}", names, targetGroups]);
sol.common.UserUtils.removeUsersFromGroups(names, targetGroups, {
connection: me.connection
});
},
prepareUserList: function (userDef) {
var me = this, users, userList;
users = (userDef || [])
.filter(function (entry) { return entry; }) // TODO: implement default filter in ObjectUtils to filter nullable values
.reduce(function (userObjList, entry) {
if (sol.common.ObjectUtils.type(entry, "string")) {
userList = [entry];
} else if (entry.type) {
userList = me.extractUsers(entry);
} else if (entry.service) {
throw Error("elementService is currently not implemented");
} else {
throw Error("Unknown entry type in `addUsersToGroup`. Only `type` and `service` is allowed");
}
// each user should be unqiue in the array so we store the user
// into an object first. It avoids duplicates user.
// User have to been a string value here
userList && userList.reduce(function (objList, user) {
user && (objList[user] = true);
return objList;
}, userObjList);
return userObjList;
}, {});
// Now we convert it back to an array, so we can pass it easily to UserUtils
return Object.keys(users);
},
*
* @param {Object} entry
* @param {Object} entry.type
* @param {Object} entry.key
* @returns {Array<String>}
*/
extractUsers: function (entry) {
var me = this, key,
mapTableFormatter, users, output, keys;
// complex object { type: "GRP", "key": "FIELDNAME" }
if (!entry || !me.hasAccesssorKey(entry)) {
throw Error("process type " + entry.type + "is not supported currently");
}
key = me.getAccessor(entry);
if (entry.table === true) {
keys = sol.common.ObjectUtils.isArray(entry.key)
? entry.key
: [entry.key];
output = keys.map(function (k) {
return { source: { key: k }, target: { prop: k } };
});
me.logger.info(["output {0}, entry={1}", JSON.stringify(output), JSON.stringify(entry)]);
// convert map table to an array so we can pass user array easily to UserUtils later
mapTableFormatter = sol.create("sol.common.ObjectFormatter.MapTableToArray", {
kind: entry.type === "WFMAP" ? "wfMapKeys" : "mapKeys",
output: output,
options: {
propSelector: entry.propSelector || "",
filter: entry.filter || []
}
});
users = mapTableFormatter.format(me.sord);
me.logger.info(["users in table {0}", JSON.stringify(users)]);
} else {
users = [sol.common.ObjectUtils.getProp(me.sord, key)];
}
return users;
},
hasAccesssorKey: function (entry) {
var me = this;
return me.TEMPLATESORDACCESSORS.hasOwnProperty((entry.type || "").toUpperCase());
},
getAccessor: function (entry) {
var me = this;
return me.TEMPLATESORDACCESSORS[(entry.type || "").toUpperCase()] + entry.key;
},
uniqueList: function (list) {
var obj = list.reduce(function (acc, item) {
acc[item] = true;
return acc;
}, {});
return Object.keys(obj);
}
});
/**
* @member sol.common.ix.functions.ChangeGroup
* @static
* @inheritdoc sol.common.ix.FunctionBase#onEnterNode
*/
function onEnterNode(clInfo, userId, wFDiagram, nodeId) {
logger.enter("onEnterNode_ChangeGroup", { flowId: wFDiagram.id, nodeId: nodeId });
var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
module;
sol.common.WfUtils.checkMainAdminWf(wFDiagram);
params.objId = String(wFDiagram.objId);
params.flowId = String(wFDiagram.id);
module = sol.create("sol.common.ix.functions.ChangeGroup", params);
module.process();
logger.exit("onEnterNode_ChangeGroup");
}
/**
* @member sol.common.ix.functions.ChangeGroup
* @static
* @inheritdoc sol.common.ix.FunctionBase#onExitNode
*/
function onExitNode(clInfo, userId, wFDiagram, nodeId) {
logger.enter("onExitNode_ChangeGroup", { flowId: wFDiagram.id, nodeId: nodeId });
var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
module;
sol.common.WfUtils.checkMainAdminWf(wFDiagram);
params.objId = wFDiagram.objId;
params.flowId = String(wFDiagram.id);
module = sol.create("sol.common.ix.functions.ChangeGroup", params);
module.process();
logger.exit("onExitNode_ChangeGroup");
}
/**
* @member sol.common.ix.functions.ChangeGroup
* @method RF_sol_function_ChangeGroup
* @static
* @inheritdoc sol.common.ix.FunctionBase#RF_FunctionName
*/
function RF_sol_function_ChangeGroup(ec, args) {
logger.enter("RF_sol_function_ChangeGroup", args);
var module, result, params = sol.common.ix.RfUtils.parseAndCheckParams(ec, arguments.callee.name, args);
sol.common.ix.RfUtils.checkMainAdminRights(ec.user, params);
module = sol.create("sol.common.ix.functions.ChangeGroup", params);
result = module.process();
logger.exit("RF_sol_function_ChangeGroup");
return sol.common.JsonUtils.stringifyQuick(result);
}