Name

global.GRCKnowledgeBase

Description

Base functionality for publishing policies/engagements as KB articles

Script

var GRCKnowledgeBase = Class.create();
GRCKnowledgeBase.prototype = {
  initialize: function() {},

  createArticle: function(targetRecord, propertyName, templateRecord, kbId) {
      return this._createArticle(targetRecord, propertyName, templateRecord, kbId);
  },

  getDefaultKBId: function() {
      return this._getDefaultKBId();
  },

  publishArticle: function(targetRecord) {
      return this._publishArticle(targetRecord);
  },

  retireArticle: function(targetRecord) {
      return this._retireArticle(targetRecord);
  },

  checkoutArticle: function(targetRecord, propertyName, templateRecord, kbId) {
      return this._checkoutArticle(targetRecord, propertyName, templateRecord, kbId);
  },
  
  isVersioningEnabled: function() {
  	return new KBCommon().isVersioningEnabled();
  },

  _createArticle: function(targetRecord, propertyName, templateRecord, kbId) {
      var targetRecordTable = targetRecord.getTableName();

      var kb = null;
      // If a KB id has been provided, try to use that one
      if (kbId) {
          kb = new GlideRecord('kb_knowledge_base');
          if (!kb.get(kbId))
              kb = null;
      }
      // If there is no kbId or we couldn't find the KB, 
      // use the KB on the target record (policy or engagement)
      // or the default KB if the target record doesn't have a KB
      if (!kb)
          kb = this._getKnowledgeBase(targetRecord, propertyName);

      // If we still haven't found a KB, return; don't create the article
      if (!kb)
          return null;

      var article = new GlideRecord('kb_knowledge');
      article.kb_knowledge_base = kb.sys_id;
      article.short_description = targetRecord.name;
      var kbCategory = this._getKBCategory(targetRecord, propertyName);
      if (kbCategory)
          article.kb_category = kbCategory;

      article.text = this._getMarkup(targetRecord, templateRecord);

      article.valid_to = '';
      if (targetRecordTable == 'sn_compliance_policy') {
          var validToDate = new GlideDateTime();
          validToDate.setValue(targetRecord.valid_to);
          article.valid_to = validToDate.getDate();
          article.display_attachments = true;
          article.sn_grc_target_table = 'sn_compliance_policy';
      } 
      var id = article.insert();
      return id;
  },

  _getMarkup: function(targetRecord, templateRecord) {
      var controller = new GlideController();
      controller.putGlobal('current', targetRecord);
      var text = '';
      var type = templateRecord.getValue('type');

      switch (type) {
          case 'script':
              controller.putGlobal('template', '');
              controller.evaluateAsObject(templateRecord.getValue('script'));
              text = controller.getGlobal('template') + '';
              controller.removeGlobal('template');
              break;
          case 'html':
          case 'xml':
              var scriptToEvaluate = templateRecord.getValue(type);
              if (scriptToEvaluate.indexOf('${current.policy_text}')) {
                  scriptToEvaluate = scriptToEvaluate.replaceAll("${current.policy_text}", targetRecord.policy_text + '');
              }

              text = new GlideJellyRunner().runFromScript(scriptToEvaluate);
      }
      return text;
  },

  _getKBCategory: function(targetRecord, propertyName) {
      var categoryId = '';
      var kb = this._getKnowledgeBase(targetRecord, propertyName);
      if (kb == null)
          return null;

      var targetRecordTable = targetRecord.getTableName();
      if (targetRecordTable == 'sn_compliance_policy')
          categoryId = this._getPolicyKBCategory(targetRecord, kb);

      else if (targetRecordTable == 'sn_audit_engagement')
          categoryId = this._getAuditKBCategory(targetRecord, kb);

      return categoryId;
  },

  _getPolicyKBCategory: function(targetRecord, kb) {
      if (targetRecord.type.nil())
          return null;

      var category = new GlideRecord('kb_category');
      var choice = new GlideRecord('sn_grc_choice');

      if (choice.get(targetRecord.type)) {
          category.addQuery('parent_table', 'kb_knowledge_base');
          category.addQuery('parent_id', kb.sys_id);
          category.addQuery('value', choice.name);
          category.setLimit(1);
          category.query();
          if (category.next())
              return category.sys_id + '';
      }

      category = new GlideRecord('kb_category');
      category.label = choice.label;
      category.value = choice.name;
      category.parent_table = 'kb_knowledge_base';
      category.parent_id = kb.sys_id;
      return category.insert();
  },

  _getAuditKBCategory: function(targetRecord, kb) {
      var auditCategory = new GlideRecord('kb_category');
      auditCategory.addQuery('parent_table', 'kb_knowledge_base');
      auditCategory.addQuery('parent_id', kb.sys_id);
      auditCategory.addQuery('value', 'audit');
      auditCategory.setLimit(1);
      auditCategory.query();
      if (auditCategory.next())
          return auditCategory.sys_id + '';

      auditCategory = new GlideRecord('kb_category');
      auditCategory.label = 'Audit';
      auditCategory.value = 'audit';
      auditCategory.parent_table = 'kb_knowledge_base';
      auditCategory.parent_id = kb.sys_id;
      return auditCategory.insert();
  },

  _getDefaultKBId: function() {
      var kb = this._getKnowledgeBase('', 'sn_compliance.knowledge_base');
      if (!kb)
          return null;

      return kb.getUniqueValue();
  },

  _getKnowledgeBase: function(targetRecord, propertyName) {
      var kb = new GlideRecord('kb_knowledge_base');
      if (targetRecord && !targetRecord.kb_knowledge_base.nil()) {
          kb.get(targetRecord.kb_knowledge_base);
          return kb;
      }

      var kbProp = new GlideRecord('sys_properties');
      if (!kbProp.get('name', propertyName))
          return null;

      kb.get('title', kbProp.value);
      return kb;
  },

  _publishArticle: function(targetRecord) {
      if (!targetRecord)
          return false;
      var targetRecordTable = targetRecord.getTableName();
      if (targetRecordTable == 'sn_audit_engagement') {
          if (targetRecord.kb_article_draft.nil() ||
              targetRecord.kb_article_draft.kb_knowledge_base.nil() ||
              targetRecord.kb_article_draft.kb_knowledge_base.retire_workflow.nil())
              return false;
      } else {
          if (targetRecord.kb_article.nil() ||
              targetRecord.kb_article.kb_knowledge_base.nil() ||
              targetRecord.kb_article.kb_knowledge_base.retire_workflow.nil())
              return false;
      }
      var article = new GlideRecord('kb_knowledge');
      var article_id;
      if (targetRecordTable == 'sn_audit_engagement')
          article_id = targetRecord.kb_article_draft;
      else
          article_id = targetRecord.kb_article;
      if (!article.get(article_id)) {
          return false;
      }

      var publishWorkflow = article.kb_knowledge_base.workflow;

      var initial_workflow_state = article.workflow_state;
      var context = new global.Workflow().startFlow(
          publishWorkflow,
          article,
          null, {
              initial_workflow_state: initial_workflow_state
          });
      article.update();

      if (!context)
          return false;

      if (targetRecordTable == 'sn_audit_engagement') {
          targetRecord.kb_article = article.getUniqueValue();
          targetRecord.update();
      }
      return true;
  },

  _retireArticle: function(targetRecord) {
      if (!targetRecord ||
          targetRecord.kb_article.nil() ||
          targetRecord.kb_article.kb_knowledge_base.nil() ||
          targetRecord.kb_article.kb_knowledge_base.retire_workflow.nil())
          return false;

      var article = new GlideRecord('kb_knowledge');
      if (!article.get(targetRecord.kb_article))
          return false;

      var retireWorkflow = targetRecord.kb_article.kb_knowledge_base.retire_workflow;

      var initial_workflow_state = article.workflow_state;
      var context = new global.Workflow().startFlow(
          retireWorkflow,
          article,
          null, {
              initial_workflow_state: initial_workflow_state
          });

      if (!context)
          return false;

      return true;
  },

  _checkoutArticle: function(targetRecord, propertyName, templateRecord, kbId) {
      if (!targetRecord)
          return false;
      var targetRecordTable = targetRecord.getTableName();
      if (targetRecordTable == 'sn_audit_engagement') {
          if (targetRecord.kb_article_draft.nil())
              targetRecord.kb_article_draft = targetRecord.kb_article;
          if (targetRecord.kb_article_draft.nil() ||
              targetRecord.kb_article_draft.kb_knowledge_base.nil() ||
              targetRecord.kb_article_draft.kb_knowledge_base.retire_workflow.nil())
              return false;
      } else if (targetRecord.kb_article.nil() ||
          targetRecord.kb_article.kb_knowledge_base.nil() ||
          targetRecord.kb_article.kb_knowledge_base.retire_workflow.nil())
          return false;

      var article_id;
      if (targetRecordTable == 'sn_audit_engagement')
          article_id = targetRecord.kb_article_draft;
      else
          article_id = targetRecord.kb_article;

      var article = new GlideRecord('kb_knowledge');
      if (!article.get(article_id))
          return false;

      article = new KBVersioning().getLatestVersion(article.article_id);
      if (!article)
          return false;
      if (article.workflow_state == 'retired') {
          new KBVersioning().republish(article);
      }
      if (article.workflow_state == 'published') {
          var newRecord = new KBVersioning().checkout(article, true);
      } else {
          var newRecord = article;
      }
      if (newRecord) {
          if (kbId) {
              newRecord.kb_knowledge_base = kbId;
          } else {
              newRecord.kb_knowledge_base = article.kb_knowledge_base;
          }
          newRecord.kb_category = article.kb_category;
          newRecord.short_description = targetRecord.name;
          newRecord.text = this._getMarkup(targetRecord, templateRecord);
          if (targetRecordTable == 'sn_compliance_policy') {
              var validToDate = new GlideDateTime();
              validToDate.setValue(targetRecord.valid_to);
              newRecord.valid_to = validToDate.getDate();
              newRecord.display_attachments = true;

          }
          newRecord.update();
      }
      return newRecord.sys_id;
  },


  type: 'GRCKnowledgeBase'
};

Sys ID

98fdec43c3521200dd921a4112d3ae01

Offical Documentation

Official Docs: