Name

global.SkillManager

Description

Manage operations related to users / groups / skills and inheritance - add inherited skills from a group to all users in the group

Script

gs.include("PrototypeServer");

var SkillManager = Class.create();

SkillManager.prototype = {
  initialize: function() {},

  addInheritedSkills: function( /* GlideRecord */ groupSkill) {
      var members = GlideUserGroup.getMembers(groupSkill.group);
      while (members.next()) {
          var skill = new GlideRecord('sys_user_has_skill');
          skill.addQuery('user', members.user);
          skill.addQuery('skill', groupSkill.skill);
          skill.query();
          // if user already has the skill then skip the insert
          if (skill.next()) {
              // check for the skill level coming from new group
              if (skill.skill_level_inherited && skill.skill_level.value < groupSkill.skill_level.value) {
                  skill.skill_level = groupSkill.skill_level;
                  skill.setWorkflow(false);
                  skill.update();
              }
          } else {
              skill.initialize();
              skill.user = members.user;
              skill.skill = groupSkill.skill;
              skill.skill_level = groupSkill.skill_level;
              skill.inherited = groupSkill.inherits;
              skill.inherited_from = groupSkill.group;
              skill.skill_level_inherited = true;
              skill.insert();
          }
      }
      this.addInheritedToGroups(groupSkill);
  },

  updateGroupUsersSkillLevel: function(groupSkill) {
      var members = GlideUserGroup.getMembers(groupSkill.group);
      while (members.next()) {
          var skill = new GlideRecord('sys_user_has_skill');
          skill.addQuery('user', members.user);
          skill.addQuery('skill', groupSkill.skill);
          // update the skill level for inherited levels only
          skill.addQuery('skill_level_inherited', true);
          skill.query();
          if (skill.next()) {
              // check if the new level is higher than other parent group levels
              var groups = GlideUserGroup.getUsersGroups(skill.user);
              var skillLevel = groupSkill.skill_level;
              if (groups.size() > 1) {
                  var groupLevel = new GlideRecord('sys_group_has_skill');
                  groupLevel.addQuery('group', 'IN', groups.toString());
                  groupLevel.addQuery('skill', skill.skill);
                  groupLevel.orderByDesc('skill_level.value');
                  groupLevel.setLimit(1);
                  groupLevel.query();
                  if (groupLevel.next())
                      skillLevel = groupLevel.getValue('skill_level');
              }
              skill.skill_level = skillLevel;
              skill.setWorkflow(false);
              skill.setForceUpdate(true);
              skill.update();
          }
      }
      this.updateSkillLevelInheritedToGroups(groupSkill);
  },

  updateSkillLevelInheritedToGroups: function( /* GlideRecord */ groupSkill) {
      var children = new GlideRecord('sys_user_group');
      children.addQuery('parent', groupSkill.group);
      children.query();
      while (children.next()) {
          var c = new GlideRecord('sys_group_has_skill');
          c.addQuery('group', children.sys_id);
          c.addQuery('skill', groupSkill.skill);
          // update the skill level for inherited levels only
          c.addQuery('skill_level_inherited', true);
          c.query();
          if (c.next()) {
              c.skill_level = groupSkill.skill_level;
              c.update();
          }
      }
  },

  addInheritedToGroups: function( /* GlideRecord */ groupSkill) {
      var children = new GlideRecord('sys_user_group');
      children.addQuery('parent', groupSkill.group);
      children.query();
      while (children.next()) {
          var c = new GlideRecord('sys_group_has_skill');
          c.addQuery('group', children.sys_id);
          c.addQuery('skill', groupSkill.skill);
          c.query();
          if (c.next()) {
              if (!c.skill_level_inherited && c.skill_level.value < groupSkill.skill_level.value) {
                  c.skill_level = groupSkill.skill_level;
                  c.update();
              }
          } else {
              c.initialize();
              c.group = children.sys_id;
              c.inherited_from = groupSkill.group;
              c.inherits = groupSkill.inherits;
              c.skill = groupSkill.skill;
              c.skill_level = groupSkill.skill_level;
              c.skill_level_inherited = true;
              c.insert();
          }

      }
  },

  deleteInheritedSkills: function( /* GlideRecord */ groupSkill) {
      var gr = new GlideRecord('sys_user_has_skill');
      gr.initialize();
      gr.addQuery('inherited_from', groupSkill.group);
      gr.addQuery('skill', groupSkill.skill);
      gr.addQuery('inherited', true);
      gr.deleteMultiple();
      this.deleteInheritedFromGroups(groupSkill);
  },

  deleteInheritedFromGroups: function( /* GlideRecord */ groupSkill) {
      var gr = new GlideRecord('sys_group_has_skill');
      gr.initialize();
      gr.addQuery('inherited_from', groupSkill.group);
      gr.addQuery('skill', groupSkill.skill);
      gr.addQuery('inherited', true);
      gr.deleteMultiple();

  },

  deleteAllSkills: function( /* GlideRecord */ groupSkill) {
      var gr = new GlideRecord('sys_user_has_skill');
      gr.initialize();
      gr.addQuery('inherited_from', groupSkill.group);
      gr.addQuery('skill', groupSkill.skill);
      gr.deleteMultiple();
  },

  // when sys_user_group.parent changes
  removeGroupSkillsFromChild: function( /* String */ parent, /* String */ child) {
      var gr = new GlideRecord('sys_group_has_skill');
      gr.addQuery('group', child);
      gr.addQuery('inherited_from', parent);
      gr.deleteMultiple();
  },

  // adds all inherited group skills to a child group
  // when sys_user_group.parent changes
  addGroupSkillsToChild: function( /* String */ parent, /* String */ child) {
      var parentSkills = new GlideRecord('sys_group_has_skill');
      parentSkills.addQuery('group', parent);
      parentSkills.addQuery('inherits', true);
      parentSkills.query();
      while (parentSkills.next()) {
          var c = new GlideRecord('sys_group_has_skill');
          c.initialize();
          c.group = child;
          c.inherited_from = parent;
          c.inherits = parentSkills.inherits;
          c.skill = parentSkills.skill;
          c.insert();
      }
  },

  // Support for included skills from here down

  /* Called when a skill is added to another skill e.g. we say "DBA now includes MySQL DBA"
   */
  addIncludedSkill: function( /* GlideRecord */ inclusion) {
      var master = inclusion.skill;
      var contains = inclusion.contains;
      var expand = new GlideRecord('sys_user_has_skill');
      expand.addQuery('skill', master);
      expand.query();
      while (expand.next()) {
          var newSkill = new GlideRecord('sys_user_has_skill');
          newSkill.initialize();
          newSkill.user = expand.user;
          newSkill.skill = contains;
          newSkill.inherited_from = expand.inherited_from;
          newSkill.inherited = true;
          newSkill.included_in_skill = expand.sys_id;
          newSkill.included_in_skill_instance = inclusion.sys_id;
          newSkill.insert();
      }
  },

  /* Called when a skill is removed from another skill e.g. we say "Network now no longer includes Network wiring"
   */
  removeIncludedSkill: function( /* GlideRecord */ inclusion) {
      var expand = new GlideRecord('sys_user_has_skill');
      expand.addQuery('included_in_skill_instance', inclusion.sys_id);
      expand.query();
      while (expand.next()) {
          expand.deleteRecord();
      }
  },

  /* Called when a skill is added to the sys_user_has_skill table.
  Responsible for expanding (adding) any skills contained within the skill in question
  Exception: skills that the user already had and were not inherited from another skill are not added
  */
  expandSkill: function( /* GlideRecord */ sys_user_has_skill) {
      var topLevel = false;
      if (typeof SKILL_HASH == 'undefined' || SKILL_HASH == null) {
          topLevel = true;
          SKILL_HASH = new Object();
      }
      var key = sys_user_has_skill.skill + '';
      SKILL_HASH[key] = true;
      var expansion = new GlideRecord('cmn_skill_contains');
      expansion.addQuery('skill', sys_user_has_skill.skill);
      expansion.addQuery('contains.active', true);
      expansion.query();
      while (expansion.next()) {
          var childkey = expansion.contains + '';
          if (SKILL_HASH[childkey])
              continue;

          var genuineSkill = new GlideRecord('sys_user_has_skill');
          genuineSkill.addQuery('user', sys_user_has_skill.user);
          genuineSkill.addQuery('skill', childkey);
          genuineSkill.addQuery('included_in_skill', '');
          genuineSkill.query();
          if (genuineSkill.next())
              continue;

          var newSkill = new GlideRecord('sys_user_has_skill');
          newSkill.initialize();
          newSkill.user = sys_user_has_skill.user;
          newSkill.skill = expansion.contains;
          newSkill.inherited = true;
          newSkill.inherited_from = sys_user_has_skill.inherited_from;
          newSkill.included_in_skill = sys_user_has_skill.sys_id;
          newSkill.included_in_skill_instance = expansion.sys_id;
          newSkill.insert();
      }
      if (topLevel)
          SKILL_HASH = null;
  },

  /* Called when a skill is deleted from the sys_user_has_skill table.
  Responsible for removing any skills that were added on account of this skill.
  For example, if DBA contains MYSQL DBA and we grant DBA to Alex B
  Alex now has DBA and MYSQL DBA
  If we remove DBA from Alex, he has to lose MYSQL as well
  */
  deleteSkill: function( /* GlideRecord */ sys_user_has_skill) {
      var kids = new GlideRecord('sys_user_has_skill');
      kids.addQuery('included_in_skill', sys_user_has_skill.sys_id);
      kids.query();
      while (kids.next()) {
          kids.deleteRecord();
      }
  },
  addParentSkill: function(skill, parentSkill) {
      var skillContainsGr = new GlideRecordSecure("cmn_skill_contains");
      skillContainsGr.setValue("skill", skill);
      skillContainsGr.setValue("contains", parentSkill);
      var newContainsRecord = skillContainsGr.insert();
      var status = 'success';
      if (gs.nil(newContainsRecord)) {
          var errorMessage = skillContainsGr.getLastErrorMessage();
          status = 'error';
      }
      return {
          newContainsRecord: newContainsRecord,
          errorMessage: errorMessage,
          status: status
      };
  },
  createM2MSkillCategory: function(skill, category) {
      var m2mCategoryGr = new GlideRecordSecure("cmn_skill_m2m_category");
      m2mCategoryGr.setValue("skill", skill);
      m2mCategoryGr.setValue("category", category);
      var newM2MRecord = m2mCategoryGr.insert();
      var status = 'success';
      if (gs.nil(newM2MRecord)) {
          var errorMessage = m2mCategoryGr.getLastErrorMessage();
          status = 'error';
      }
      return {
          newM2MRecord: newM2MRecord,
          errorMessage: errorMessage,
          status: status
      };
  },

  z: function() {}
};

Sys ID

49284de7c0a8018b3343c8783bcfc898

Offical Documentation

Official Docs: