Name

sn_risk_advanced.AssessmentTypeUtilsBase

Description

Utility for risk assessment type methods

Script

var AssessmentTypeUtilsBase = Class.create();
AssessmentTypeUtilsBase.prototype = {
  initialize: function() {

      this.instanceRatingToScoreColumnMap = {
          'inherent_computed_risk': 'inherent_computed_score',
          'summary_inherent_risk': 'final_inherent_score',
          'control_computed_effectiveness': 'control_computed_score',
          'summary_control_effectiveness': 'final_control_score',
          'residual_computed_risk': 'residual_computed_score',
          'summary_residual_risk': 'final_residual_score',
          'target_computed_risk': 'target_computed_score',
          'summary_target_risk': 'final_target_score',
          'inherent_risk_when_overriden': 'inherent_score_when_overriden',
          'control_effectiveness_when_overridden': 'control_score_when_overridden',
          'residual_risk_when_overridden': 'residual_score_when_overridden',
          'target_risk_when_overridden': 'target_score_when_overridden'
      };

      this.instanceRatingToRiskScoreColumnMap = {
          'inherent_computed_risk': 'inherent_computed_risk_score',
          'summary_inherent_risk': 'summary_inherent_risk_score',
          'control_computed_effectiveness': 'control_computed_effectiveness_score',
          'summary_control_effectiveness': 'summary_control_effectiveness_score',
          'residual_computed_risk': 'residual_computed_risk_score',
          'summary_residual_risk': 'summary_residual_risk_score',
          'target_computed_risk': 'target_computed_risk_score',
          'summary_target_risk': 'summary_target_risk_score',
          'inherent_risk_when_overriden': 'inherent_risk_score_when_overriden',
          'control_effectiveness_when_overridden': 'control_effectiveness_score_when_overridden',
          'residual_risk_when_overridden': 'residual_risk_score_when_overridden',
          'target_risk_when_overriden': 'target_risk_score_when_overriden',
      };

      this.rollupResultRatingToScoreColumnMap = {
          'inherent_rating': 'inherent_score',
          'residual_rating': 'residual_score',
          'control_rating': 'control_score',
          'target_rating': 'target_score',
      };

      this.rollupResultRatingToRiskScoreColumnMap = {
          'inherent_rating': 'inherent_rating_display',
          'residual_rating': 'residual_rating_display',
          'control_rating': 'control_rating_display',
          'target_rating': 'target_rating_display'
      };

  },

  copyFactorsFromAssessment: function(toAsmtGr, fromAsmtType) {
      return this._copyFactorsFromAssessment(toAsmtGr, fromAsmtType);
  },

  checkInsertionInLookupMatrix: function(matrixRecord) {
      return this._checkInsertionInLookupMatrix(matrixRecord);
  },

  copyRatingCriteria: function(assessmentType, fromType) {
      return this._copyRatingCriteria(assessmentType, fromType);
  },

  deleteFactorsFromResidualAssessment: function(assessmentType) {
      return this._deleteFactorsFromResidualAssessment(assessmentType);
  },

  createQualitativeRiskCriteriaRecord: function(assessmentType) {
      return this._createQualitativeRiskCriteriaRecord(assessmentType);
  },

  copyValues: function(assessmentType, fromType) {
      return this._copyValues(assessmentType, fromType);
  },

  setScoresToDefault: function(assessmentType) {
      return this._setScoresToDefault(assessmentType);
  },

  getFactorsForAssessmentType: function(assessmentType) {
      return this._getFactorsForAssessmentType(assessmentType);
  },

  syncResidualFactorsToInherent: function(asmtTypeToFactrM2m) {
      return this._syncResidualFactorsToInherent(asmtTypeToFactrM2m);
  },

  syncTargetFactors: function(asmtTypeToFactrM2m, type) {
      return this._syncTargetFactors(asmtTypeToFactrM2m, type);
  },

  createResidualAsmtMatrixEntries: function(residualAssessment, errorMesg) {
      this._createResidualAsmtMatrixEntries(residualAssessment, errorMesg);
  },

  deleteResidualAssessmentMatrix: function(residualAssessment) {
      this._deleteResidualAssessmentMatrix(residualAssessment);
  },

  getFactorsForInherentOrControlAssessment: function(inherentAssessment) {
      return this._getFactorsForInherentOrControlAssessment(inherentAssessment);
  },

  getFactorsForTargetAssessment: function(targetAssessment) {
      return this._getFactorsNotAssociatedToAnyRAM(targetAssessment);
  },

  validateInherentAssessment: function(inherentAssessment) {
      return this._validateInherentAssessment(inherentAssessment);
  },

  validateControlAssessment: function(controlAssessment) {
      return this._validateControlAssessment(controlAssessment);
  },

  validateTargetAssessment: function(targetAssessment) {
      return this._validateTargetAssessment(targetAssessment);
  },

  syncQualitativeRatingChange: function(ratingCriteria) {
      this._syncQualitativeRatingChange(ratingCriteria);
  },

  syncRatingChangeOnUpgrade: function() {
      this._syncRatingChangeOnUpgrade();
  },

  moveResidualToDraftIfSameAsInherent: function(inherentAsmt) {
      return this._moveResidualToDraftIfSameAsInherent(inherentAsmt);
  },

  moveTargetToDraftIfSameAsInherent: function(inherentAsmt) {
      return this._moveTargetToDraftIfSameAsInherent(inherentAsmt);
  },

  moveTargetToDraftIfSameAsResidual: function(residualAsmt) {
      return this._moveTargetToDraftIfSameAsResidual(residualAsmt);
  },

  canSyncRatingCriteria: function(assmtType, fromType) {
      return this._canSyncRatingCriteria(assmtType, fromType);
  },

  updateRating: function(record, ratingColumns, ratingToScoreColumnMap, ratingToRiskScoreColumnMap, ratingCriteria) {
      return this._updateRating(record, ratingColumns, ratingToScoreColumnMap, ratingToRiskScoreColumnMap, ratingCriteria);
  },

  canShowEditButtonForAssessmentType: function(parent) {
      return this._canShowEditButtonForAssessmentType(parent);
  },

  isAssessmentTypePublished: function(ramReference, className) {
      return this._isAssessmentTypePublished(ramReference, className);
  },

  isAssessmentTypeMandatory: function(assessmentInstanceId, assessmentType, ramId) {
      return this._isAssessmentTypeMandatory(assessmentInstanceId, assessmentType, ramId);
  },

  getIsAssessmentTypeMandatoryFlag: function(assessmentInstanceId, assessmentType) {
      return this._getIsAssessmentTypeMandatoryFlag(assessmentInstanceId, assessmentType);
  },

  isTargetOverallAssessment: function(ramId) {
      return this._isTargetOverallAssessment(ramId);
  },

  _canSyncRatingCriteria: function(assmtType, fromType) {
      if (assmtType.sys_class_name == 'sn_risk_advanced_residual_assessment') {
          return assmtType.canWrite() && assmtType.state == '1' && assmtType.calculate_based_on == 'factor_responses' && assmtType.factors_same_as_inherent == true && assmtType.assessment_contribution != '1';
      } else if (assmtType.sys_class_name == 'sn_risk_advanced_target_assessment') {
          //check if inherent is present or not, then show the UI action for inherent. This cannot be done in runtime because by default factor same as inherent is selected which is then removed via an ajax call. Not the same with residual as it is not the default choice.
          var isInherentAssessmentPresent = new sn_risk_advanced.RiskAssessmentUtils().hasInherentAssessment(assmtType.risk_assessment_methodology);
          return assmtType.canWrite() && assmtType.state == '1' && ((assmtType.calculate_based_on == 'factor_same_as_inherent' && fromType == 'inherent' && isInherentAssessmentPresent) || (assmtType.calculate_based_on == 'factor_same_as_residual' && fromType == 'residual')) && assmtType.assessment_contribution != '1';
      }

  },

  _moveResidualToDraftIfSameAsInherent: function(inherentAsmt) {
      var canInherentBeDraft = true;
      var residualAsmt = new GlideRecord('sn_risk_advanced_residual_assessment');
      if (residualAsmt.get('risk_assessment_methodology', inherentAsmt.risk_assessment_methodology)) {
          if (residualAsmt.factors_same_as_inherent && residualAsmt.state == '2') {
              residualAsmt.state = '1';
              canInherentBeDraft = !gs.nil(residualAsmt.update());
          }
      }
      return canInherentBeDraft;
  },

  _moveTargetToDraftIfSameAsInherent: function(inherentAsmt) {
      var canInherentBeDraft = true;
      var targetAsmt = new GlideRecord('sn_risk_advanced_target_assessment');
      if (targetAsmt.get('risk_assessment_methodology', inherentAsmt.risk_assessment_methodology)) {
          if (targetAsmt.calculate_based_on == 'factor_same_as_inherent' && targetAsmt.state == '2') {
              targetAsmt.state = '1';
              canInherentBeDraft = !gs.nil(targetAsmt.update());
          }
      }
      return canInherentBeDraft;
  },

  _moveTargetToDraftIfSameAsResidual: function(residualAsmt) {
      var canResidualBeDraft = true;
      var targetAsmt = new GlideRecord('sn_risk_advanced_target_assessment');
      if (targetAsmt.get('risk_assessment_methodology', residualAsmt.risk_assessment_methodology)) {
          if (targetAsmt.calculate_based_on == 'factor_same_as_residual' && targetAsmt.state == '2') {
              targetAsmt.state = '1';
              canResidualBeDraft = !gs.nil(targetAsmt.update());
          }
      }
      return canResidualBeDraft;
  },

  handleRiskColorStyleChangeInMatrix: function(matrixRecord) {
      this._handleRiskColorStyleChangeInMatrix(matrixRecord);
  },

  updateOverriddenScoreAndRiskColorStyle: function(matrixRecord) {
      this._updateOverriddenScoreAndRiskColorStyle(matrixRecord);
  },

  syncRatingCriteriaChangestoMatrix: function(ratingCriteria, previousRating) {
      this._syncRatingCriteriaChangestoMatrix(ratingCriteria, previousRating);
  },

  _syncQualitativeRatingChange: function(ratingCriteria) {
      var assessmentTypeElement = ratingCriteria.getElement('assessment_type');
      var assessmentTypeRecord = assessmentTypeElement.getRefRecord();
      this._syncQualitativeRatingChangeForAssessmentInstance(assessmentTypeRecord);
  },

  _syncQualitativeRatingChangeForAssessmentInstance: function(assessmentTypeRecord) {
      //Get any object assessments, to update the rating scores
      var assessments = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      assessments.addQuery('risk_assessment_methodology', assessmentTypeRecord.risk_assessment_methodology);
      assessments.addQuery('source_record', '!=', null);
      assessments.addQuery('state', '!=', '9');
      assessments.query();

      while (assessments.next()) {
          new sn_risk_advanced.RiskAssessmentUtils().copyAssessmentResultsToSourceRecord(assessments);
      }
  },

  _updateRating: function(record, ratingColumns, ratingToScoreColumnMap, ratingToRiskScoreColumnMap, ratingCriteria) {
      for (var j = 0; j < ratingColumns.length; j++) {
          var ratringColumn = ratingColumns[j];
          if (record[ratringColumn] == ratingCriteria.getUniqueValue()) {
              var riskScoreColumn = ratingToRiskScoreColumnMap[ratringColumn];
              var rating = ratingCriteria.getValue('rating');
              var scoreColumn = ratingToScoreColumnMap[ratringColumn];
              var newRiskScore = rating + " (Score: " + record.getValue(scoreColumn) + ')';
              record.setValue(riskScoreColumn, newRiskScore);
          }
      }
      record.update();
  },

  _syncRatingChangeOnUpgrade: function() {
      var ratingRefColumns = ['inherent_computed_risk', 'summary_inherent_risk', 'control_computed_effectiveness', 'summary_control_effectiveness', 'residual_computed_risk', 'summary_residual_risk', 'target_computed_risk', 'summary_target_risk'];

      var assessments = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      assessments.addQuery('state', 'NOT IN', '0,1,9');
      assessments.query();
      while (assessments.next()) {
          this._updateRatingOnUpgrade(assessments, ratingRefColumns, this.instanceRatingToScoreColumnMap, this.instanceRatingToRiskScoreColumnMap);
      }

      var rollupRatingColumn = ['inherent_rating', 'residual_rating', 'control_rating', 'target_rating'];
      var rollUpResults = new GlideRecord('sn_risk_advanced_risk_assessment_result');
      rollUpResults.query();
      while (rollUpResults.next()) {
          this._updateRatingOnUpgrade(rollUpResults, rollupRatingColumn, this.rollupResultRatingToScoreColumnMap, this.rollupResultRatingToRiskScoreColumnMap);
      }
  },

  _updateRatingOnUpgrade: function(record, ratingRefColumns, ratingToScoreColumnMap, ratingToRiskScoreColumnMap) {
      for (var j = 0; j < ratingRefColumns.length; j++) {
          var newRating = record[ratingRefColumns[j]].rating + '';
          var scoreColumn = ratingToScoreColumnMap[ratingRefColumns[j]];
          var newRiskScore = newRating + " (Score: " + record.getValue(scoreColumn) + ')';
          var riskScoreColumn = ratingToRiskScoreColumnMap[ratingRefColumns[j]];
          record.setValue(riskScoreColumn, newRiskScore);
      }
      record.update();
  },

  _checkInsertionInLookupMatrix: function(matrixRecord) {
      var currentScore = parseFloat(matrixRecord.getValue('score'));

      var gr2 = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr2.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
      gr2.addQuery('sys_id', "!=", matrixRecord.getUniqueValue());
      gr2.addQuery('score', matrixRecord.getValue('score'));
      gr2.addNotNullQuery('rating');
      gr2.query();

      if (gr2.next()) {
          if (gr2.getValue('rating') != matrixRecord.getValue('rating')) {
              return gs.getMessage('Another record with same score {0} and a different rating {1} exists. Provide a different score.', [currentScore, gr2.getValue('rating')]);
          }
      }

      var gr1 = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr1.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
      gr1.addQuery('sys_id', "!=", matrixRecord.getUniqueValue());
      gr1.addNotNullQuery('score');
      gr1.addNotNullQuery('rating');
      gr1.orderBy('score');
      gr1.query();

      if (gr1.hasNext()) {
          gr1.next();
          var lowRating = gr1.getValue('rating');
          var lowScore = parseFloat(gr1.getValue('score'));
          while (gr1.next()) {
              if (lowScore < currentScore && parseFloat(gr1.getValue('score')) > currentScore) {
                  if (lowRating != matrixRecord.getValue('rating') && lowRating == gr1.getValue('rating')) {
                      return gs.getMessage('Select a different score or rating because the score {0} with rating {1} you have entered, falls in the range of {2} rating.', [
                          currentScore,
                          matrixRecord.getValue('rating'),
                          lowRating
                      ]);
                  }
              }

              lowRating = gr1.getValue('rating');
              lowScore = parseFloat(gr1.getValue('score'));

          }
      }

      var gr = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr.addQuery('rating', matrixRecord.getValue('rating'));
      gr.addQuery('sys_id', "!=", matrixRecord.getUniqueValue());
      gr.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
      gr.addNotNullQuery('score');
      gr.addNotNullQuery('rating');
      gr.orderBy('score');
      gr.query();

      if (gr.hasNext()) {
          gr.next();
          var minScore = parseFloat(gr.getValue('score'));
          var maxScore = minScore;
          while (gr.hasNext()) {
              gr.next();
          }
          maxScore = parseFloat(gr.getValue('score'));
          var record = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
          record.addQuery('rating', "!=", matrixRecord.getValue('rating'));
          record.addQuery('sys_id', "!=", matrixRecord.getUniqueValue());
          record.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
          record.addQuery('score', '>', minScore);
          record.addQuery('score', '<', currentScore);
          record.query();

          if (record.next()) {
              return gs.getMessage('Select a different score or rating because the score {0} with rating {1} you have entered, falls in the range of {2} rating.', [
                  currentScore,
                  matrixRecord.getValue('rating'),
                  record.getValue('rating')
              ]);
          } else {
              var maxRecord = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
              maxRecord.addQuery('rating', "!=", matrixRecord.getValue('rating'));
              maxRecord.addQuery('sys_id', "!=", matrixRecord.getUniqueValue());
              maxRecord.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
              maxRecord.addQuery('score', '<', maxScore);
              maxRecord.addQuery('score', '>', currentScore);
              maxRecord.query();

              if (maxRecord.next()) {
                  return gs.getMessage('Select a different score or rating because the score {0} with rating {1} you have entered, falls in the range of {2} rating.', [
                      currentScore,
                      matrixRecord.getValue('rating'),
                      maxRecord.getValue('rating'),
                  ]);
              }
          }

      }

      return null;
  },

  _createQualitativeRiskCriteriaRecord: function(residualAssessment) {

      var record = new GlideRecord("sn_risk_advanced_rating_criteria");
      record.addQuery("assessment_type", residualAssessment.getUniqueValue());
      record.deleteMultiple();

      var gr = new GlideRecord("sn_risk_advanced_residual_assessment_matrix");
      gr.addQuery('sn_risk_advanced_assessment_type', residualAssessment.getUniqueValue());
      gr.orderBy('score');
      gr.query();
      var riskRatingValue = "";
      while (gr.next()) {
          if (gr.rating != riskRatingValue) {
              var gr1 = new GlideRecord("sn_risk_advanced_rating_criteria");
              gr1.initialize();
              gr1.lower_interval = gr.score;
              gr1.rating = gr.rating;
              gr1.overridden_score = gr.overridden_score;
              gr1.risk_color_style = gr.risk_color_style;
              gr1.assessment_type = residualAssessment.getUniqueValue();
              gr1.insert();
              riskRatingValue = gr1.rating + '';
          }
      }
  },

  _validateInherentAssessment: function(inherentAssessment) {
      var factorAssociation = true,
          ratingAssociation = true;
      if (inherentAssessment.quantitative_scoring_logic == 'SCRIPT' || inherentAssessment.qualitative_scoring_logic == 'SCRIPT') {
          var result = {};
          new sn_risk_advanced.FactorUtils().validateBothAsmtTypeScripts(inherentAssessment, result);
          if (result.error) {
              gs.addErrorMessage(result.error);
              return false;
          }
      }
      if (inherentAssessment.calculate_based_on == 'factor_responses') {
          factorAssociation = this._checkFactorsAssociated(inherentAssessment);
      }
      if (inherentAssessment.assessment_contribution == '2' || inherentAssessment.assessment_contribution == '3') {
          ratingAssociation = this._checkRatingAssociated(inherentAssessment);
      }

      return factorAssociation && ratingAssociation;
  },

  _validateControlAssessment: function(controlAssessment) {
      var factorAssociation = true,
          ratingAssociation = true;
      if (controlAssessment.qualitative_scoring_logic == 'SCRIPT') {
          var result = new sn_risk_advanced.FactorUtils().validateAsmtTypeScript(controlAssessment, 'qualitative_script', '2');
          if (!result) {
              gs.addErrorMessage(gs.getMessage('Qualitative script validation failed.'));
              return false;
          }
      }
      if (controlAssessment.control_assessment_methodology == 'control_env_assessment') {
          factorAssociation = this._checkFactorsAssociated(controlAssessment);
          ratingAssociation = this._checkRatingAssociated(controlAssessment);
          return factorAssociation && ratingAssociation;
      } else
          return this._checkRatingAssociated(controlAssessment);
  },

  _validateTargetAssessment: function(targetAssessment) {
      var factorAssociation = true,
          ratingAssociation = true,
          isPresent = true;
      if (targetAssessment.quantitative_scoring_logic == 'SCRIPT' || targetAssessment.qualitative_scoring_logic == 'SCRIPT') {
          var result = {};
          new sn_risk_advanced.FactorUtils().validateBothAsmtTypeScripts(targetAssessment, result);
          if (result.error) {
              gs.addErrorMessage(result.error);
              return false;
          }
      }

      if (targetAssessment.calculate_based_on == 'factor_responses') {
          factorAssociation = this._checkFactorsAssociated(targetAssessment);
      } else if (targetAssessment.calculate_based_on == 'factor_same_as_inherent') {
          var inherent = new GlideRecord('sn_risk_advanced_inherent_assessment');
          isPresent = inherent.get('risk_assessment_methodology', targetAssessment.risk_assessment_methodology);
          if (isPresent && inherent.state != '2') {
              gs.addErrorMessage(gs.getMessage("Publish the inherent assessment before publishing the target assessment."));
              return false;

          }
      } else if (targetAssessment.calculate_based_on == 'factor_same_as_residual') {
          var residual = new GlideRecord('sn_risk_advanced_residual_assessment');
          isPresent = residual.get('risk_assessment_methodology', targetAssessment.risk_assessment_methodology);
          if (isPresent && residual.state != '2') {
              gs.addErrorMessage(gs.getMessage("Publish the residual assessment before publishing the target assessment."));
              return false;
          }
      }

      if (targetAssessment.assessment_contribution == '2' || targetAssessment.assessment_contribution == '3') {
          ratingAssociation = this._checkRatingAssociated(targetAssessment);
      }

      return factorAssociation && ratingAssociation;
  },

  //If assessment contribution is quantitative/both, atleast one factor should be of type currency
  _checkCurrencyFactor: function(assessment) {
      var group_factors = [];
      if (assessment.assessment_contribution == '1' || assessment.assessment_contribution == '3') {
          var m2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
          m2m.addQuery('sn_risk_advanced_assessment_type', assessment.getUniqueValue());
          if (assessment.assessment_contribution == '3')
              m2m.addQuery('sn_risk_advanced_factor.factor_contribution', '!=', '2');
          m2m.query();
          while (m2m.next()) {
              var className = m2m.sn_risk_advanced_factor.sys_class_name;
              if (className == 'sn_risk_advanced_manual_factor' || className == 'sn_risk_advanced_automated_scripted_factor' || className == 'sn_risk_advanced_automated_query_factor') {
                  if (m2m.sn_risk_advanced_factor.user_response == '4') {
                      return true;
                  }
              } else {
                  group_factors.push(m2m.sn_risk_advanced_factor + '');
              }
          }
          var childFactors = new GlideRecord('sn_risk_advanced_sub_factor');
          childFactors.addQuery('parent', 'IN', group_factors);
          childFactors.query();
          while (childFactors.next()) {
              var child = new GlideRecord(childFactors.sys_class_name);
              child.get(childFactors.getUniqueValue());
              child.addQuery('user_response', '4');
              child.setLimit(1);
              child.query();
              if (child.hasNext())
                  return true;
          }

          gs.addErrorMessage(gs.getMessage("Associate at least one currency factor with the assessment contribution of either Quantitative or Both."));
          return false;
      }
  },

  //If assessment contribution is both , there should factors contributing to both qualitative and quantitative scores
  _checkFactorTypesForBothContribution: function(assessment) {
      var qual = 0,
          quant = 0;
      var typeFactorm2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      typeFactorm2m.addQuery('sn_risk_advanced_assessment_type', assessment.getUniqueValue());
      typeFactorm2m.query();
      while (typeFactorm2m.next()) {
          if (typeFactorm2m.sn_risk_advanced_factor.factor_contribution == '3') {
              return true;
          } else {
              if (typeFactorm2m.sn_risk_advanced_factor.factor_contribution == '1') {
                  quant++;
              } else {
                  qual++;
              }
          }
      }
      if (qual == 0) {
          gs.addErrorMessage(gs.getMessage("Associate at least one qualitative factor"));
          return false;
      }
      if (quant == 0) {
          gs.addErrorMessage(gs.getMessage("Associate at least one quantitative factor"));
          return false;
      }
      return true;
  },


  _checkFactorsAssociated: function(assessment) {
      var typeFactorM2M = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');

      factorAssociation = typeFactorM2M.get('sn_risk_advanced_assessment_type', assessment.getUniqueValue());
      if (factorAssociation == false) {
          gs.addErrorMessage(gs.getMessage("Associate at least one factor to publish the assessment."));
          return false;
      } else {

          if (assessment.assessment_contribution == '1') {
              return this._checkCurrencyFactor(assessment);
          }
          if (assessment.assessment_contribution == '3') {
              return this._checkCurrencyFactor(assessment) && this._checkFactorTypesForBothContribution(assessment);
          }
      }
      return true;
  },

  _checkRatingAssociated: function(assessment) {
      var ratingAssociation, result = true;
      if (assessment.assessment_contribution == '2' || assessment.assessment_contribution == '3') {
          var ratingCriteria = new GlideRecord('sn_risk_advanced_rating_criteria');
          ratingAssociation = ratingCriteria.get('assessment_type', assessment.getUniqueValue());
          if (ratingAssociation == false) {
              gs.addErrorMessage(gs.getMessage("Associate at least one qualitative rating criteria to publish the assessment."));
              result = false;
          }
      }
      return result;
  },


  _getFactorsForAssessment: function(assessmentType, className) {
      var asmtTypeFactrM2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type', '!=', assessmentType.getUniqueValue());
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type.sys_class_name', className);
      asmtTypeFactrM2m.query();
  },

  _syncResidualFactorsToInherent: function(asmtTypeToFactrM2m) {
      var asmtType = new GlideRecord('sn_risk_advanced_residual_assessment');
      asmtType.addQuery('risk_assessment_methodology', asmtTypeToFactrM2m.sn_risk_advanced_assessment_type.risk_assessment_methodology);
      asmtType.addQuery('calculate_based_on', 'factor_responses');
      asmtType.addQuery('factors_same_as_inherent', 'true');
      asmtType.query();

      if (asmtType.next()) {
          var typeFactorM2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
          if (asmtTypeToFactrM2m.operation() == 'insert') {
              typeFactorM2m.initialize();
              typeFactorM2m.sn_risk_advanced_assessment_type = asmtType.getUniqueValue();
              typeFactorM2m.sn_risk_advanced_factor = asmtTypeToFactrM2m.sn_risk_advanced_factor;
              typeFactorM2m.insert();
          } else {
              typeFactorM2m.addQuery('sn_risk_advanced_assessment_type', asmtType.getUniqueValue());
              typeFactorM2m.addQuery('sn_risk_advanced_factor', asmtTypeToFactrM2m.sn_risk_advanced_factor);
              typeFactorM2m.query();
              if (typeFactorM2m.next())
                  typeFactorM2m.deleteRecord();
          }
      }
  },

  _syncTargetFactors: function(asmtTypeToFactrM2m, type) {
      var asmtType = new GlideRecord('sn_risk_advanced_target_assessment');
      asmtType.addQuery('risk_assessment_methodology', asmtTypeToFactrM2m.sn_risk_advanced_assessment_type.risk_assessment_methodology);
      if (type == 'sn_risk_advanced_inherent_assessment')
          asmtType.addQuery('calculate_based_on', 'factor_same_as_inherent');
      else
          asmtType.addQuery('calculate_based_on', 'factor_same_as_residual');
      asmtType.query();

      if (asmtType.next()) {
          var typeFactorM2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
          if (asmtTypeToFactrM2m.operation() == 'insert') {
              typeFactorM2m.initialize();
              typeFactorM2m.sn_risk_advanced_assessment_type = asmtType.getUniqueValue();
              typeFactorM2m.sn_risk_advanced_factor = asmtTypeToFactrM2m.sn_risk_advanced_factor;
              typeFactorM2m.insert();
          } else {
              typeFactorM2m.addQuery('sn_risk_advanced_assessment_type', asmtType.getUniqueValue());
              typeFactorM2m.addQuery('sn_risk_advanced_factor', asmtTypeToFactrM2m.sn_risk_advanced_factor);
              typeFactorM2m.query();
              if (typeFactorM2m.next())
                  typeFactorM2m.deleteRecord();
          }
      }
  },

  _copyFactorsFromAssessment: function(toAsmtGr, fromAsmtType) {

      var assessmentTypeToFactor = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      assessmentTypeToFactor.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', toAsmtGr.risk_assessment_methodology);
      assessmentTypeToFactor.addQuery('sn_risk_advanced_assessment_type.sys_class_name', fromAsmtType);
      assessmentTypeToFactor.query();

      var assessmentFactorM2M = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      while (assessmentTypeToFactor.next()) {
          assessmentFactorM2M.initialize();
          assessmentFactorM2M.sn_risk_advanced_assessment_type = toAsmtGr.getUniqueValue();
          assessmentFactorM2M.sn_risk_advanced_factor = assessmentTypeToFactor.sn_risk_advanced_factor;
          assessmentFactorM2M.insert();
      }

  },

  _copyRatingCriteria: function(assessmentType, fromType) {

      this._deleteRatingCriteriaInAssessment(assessmentType);
      var assessmentTypeToRating = new GlideRecord('sn_risk_advanced_rating_criteria');
      assessmentTypeToRating.addQuery('assessment_type.risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      assessmentTypeToRating.addQuery('assessment_type.sys_class_name', fromType);
      assessmentTypeToRating.query();

      var assessmentRatingM2M = new GlideRecord('sn_risk_advanced_rating_criteria');
      while (assessmentTypeToRating.next()) {
          assessmentRatingM2M.initialize();
          assessmentRatingM2M.assessment_type = assessmentType.getUniqueValue();
          assessmentRatingM2M.background_color = assessmentTypeToRating.background_color;
          assessmentRatingM2M.text_color = assessmentTypeToRating.text_color;
          assessmentRatingM2M.overridden_score = assessmentTypeToRating.overridden_score;
          assessmentRatingM2M.lower_interval = assessmentTypeToRating.lower_interval;
          assessmentRatingM2M.risk_color_style = assessmentTypeToRating.risk_color_style;
          assessmentRatingM2M.rating = assessmentTypeToRating.rating;
          assessmentRatingM2M.insert();

      }

  },

  _deleteFactorsFromResidualAssessment: function(assessmentType) {
      var m2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      m2m.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      m2m.addQuery('sn_risk_advanced_assessment_type.sys_class_name', 'sn_risk_advanced_residual_assessment');
      if (assessmentType.calculate_based_on == 'factor_responses' && assessmentType.factors_same_as_inherent == false && assessmentType.assessment_contribution.changes())
          m2m.addQuery('sn_risk_advanced_factor.factor_contribution', 'NOT IN', assessmentType.assessment_contribution + ',3,4');
      m2m.deleteMultiple();
  },

  deleteRatingCriteriaInAssessment: function(assessmentType) {
      return this._deleteRatingCriteriaInAssessment(assessmentType);
  },

  _deleteRatingCriteriaInAssessment: function(assessmentType) {
      var m2m = new GlideRecord('sn_risk_advanced_rating_criteria');
      m2m.addQuery('assessment_type.risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      m2m.addQuery('assessment_type.sys_class_name', assessmentType.sys_class_name);
      m2m.deleteMultiple();
  },

  _copyValues: function(assessmentType, fromType) {
      var scores = new GlideRecord('sn_risk_advanced_assessment_type');
      scores.addQuery('risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      scores.addQuery('sys_class_name', fromType);
      scores.query();

      if (scores.next()) {
          assessmentType.setValue('qualitative_scoring_logic', scores.getValue('qualitative_scoring_logic'));
          assessmentType.setValue('quantitative_scoring_logic', scores.getValue('quantitative_scoring_logic'));
          assessmentType.setValue('assessment_contribution', scores.getValue('assessment_contribution'));
          assessmentType.setValue('qualitative_script', scores.getValue('qualitative_script'));
          assessmentType.setValue('quantitative_script', scores.getValue('quantitative_script'));
          assessmentType.setValue('enable_heatmap', scores.getValue('enable_heatmap'));
          assessmentType.setValue('x_axis_factor', scores.getValue('x_axis_factor'));
          assessmentType.setValue('y_axis_factor', scores.getValue('y_axis_factor'));
      }
  },

  _setScoresToDefault: function(assessmentType) {
      var scores = new GlideRecord('sn_risk_advanced_assessment_type');
      scores.addQuery('risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      scores.addQuery('sys_class_name', 'sn_risk_advanced_residual_assessment');
      scores.query();

      if (scores.next()) {
          assessmentType.setValue('qualitative_scoring_logic', '');
          assessmentType.setValue('quantitative_scoring_logic', '');
      }
  },

  _getFactorsForAssessmentType: function(assessmentType) {
      var factorsNotAssociated = [];
      var factors = new GlideRecord('sn_risk_advanced_sub_factor');
      factors.addNullQuery('risk_assessment_methodology');
      factors.addNullQuery('parent');
      factors.addQuery('state', '2');
      factors.query();

      while (factors.next()) {
          factorsNotAssociated.push(factors.getUniqueValue() + '');
      }

      factors = new GlideRecord('sn_risk_advanced_group_factor');
      factors.addNullQuery('risk_assessment_methodology');
      factors.addQuery('state', '2');
      factors.query();

      while (factors.next()) {
          factorsNotAssociated.push(factors.getUniqueValue() + '');
      }

      var asmtTypeFactrM2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', assessmentType.risk_assessment_methodology);
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type', '!=', assessmentType.getUniqueValue());
      asmtTypeFactrM2m.query();

      while (asmtTypeFactrM2m.next()) {
          factorsNotAssociated.push(asmtTypeFactrM2m.sn_risk_advanced_factor + '');
      }

      return factorsNotAssociated.join(',');
  },

  _createResidualAsmtMatrixEntries: function(residualAssessment, errorMesg) {
      var matrix = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      var inherent_ratings = [];
      var control_ratings = [];

      var ratings = this._validateInherentControlRatingCriteria(residualAssessment, errorMesg);
      if (ratings != null) {
          inherent_ratings = ratings.inherent_ratings;
          control_ratings = ratings.control_ratings;
      }

      var count = 1;
      for (var i = 0; i < inherent_ratings.length; i++) {
          for (var j = 0; j < control_ratings.length; j++) {
              matrix.initialize();
              matrix.sn_risk_advanced_assessment_type = residualAssessment.getUniqueValue() + '';
              matrix.inherent_risk = inherent_ratings[i];
              matrix.control_effectiveness = control_ratings[j];
              matrix.display_order = count++;
              matrix.insert();
          }
      }
  },

  _deleteResidualAssessmentMatrix: function(residualAssessment) {
      var matrix = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      matrix.get('sn_risk_advanced_assessment_type', residualAssessment.getUniqueValue());
      matrix.deleteMultiple();
  },

  _getFactorsForInherentOrControlAssessment: function(inherentAssessment) {
      return this._getFactorsNotAssociatedToAnyRAM(inherentAssessment);
  },

  _getFactorsNotAssociatedToAnyRAM: function(assessmentType) {
      var ramUtils = new sn_risk_advanced.RiskAssessmentMethodologyUtils();
      var haveLicenseToShowAutomatedFactor = this._hasLicenseToShowAutomatedFactors(assessmentType);
      var factorsNotAssociated = [];
      var factorList = '';
      var factors = new GlideRecord('sn_risk_advanced_sub_factor');
      factors.addNullQuery('risk_assessment_methodology');
      factors.addNullQuery('parent');
      if (!haveLicenseToShowAutomatedFactor) {
          factors.addEncodedQuery("sys_class_name!=sn_risk_advanced_automated_query_factor^sys_class_name!=sn_risk_advanced_automated_scripted_factor");
      }
      factors.addQuery('state', '2');
      if (assessmentType.assessment_contribution == '1') {
          factors.addQuery('factor_contributionIN1,3,4');
      } else if (assessmentType.assessment_contribution == '2') {
          factors.addQuery('factor_contributionIN2,3,4');
      }

      factors.query();
      while (factors.next()) {
          var className = factors.sys_class_name;
          if ((className == 'sn_risk_advanced_automated_query_factor' || className == 'sn_risk_advanced_automated_scripted_factor')) {
              var automatedFactor = new GlideRecord(className);
              automatedFactor.get(factors.getUniqueValue());
              if (automatedFactor.factor_usage != parseInt(assessmentType.risk_assessment_methodology.assessed_on) + 1)
                  continue;
          }
          factorsNotAssociated.push(factors.getUniqueValue() + '');
      }

      factors = new GlideRecord('sn_risk_advanced_group_factor');
      factors.addNullQuery('risk_assessment_methodology');
      factors.addQuery('factor_usage', (parseInt(assessmentType.risk_assessment_methodology.assessed_on) + 1).toString());
      factors.addQuery('state', '2');
      if (assessmentType.assessment_contribution == '1')
          factors.addQuery('factor_contributionIN1,3,4');
      else if (assessmentType.assessment_contribution == '2')
          factors.addQuery('factor_contributionIN2,3,4');
      factors.query();

      while (factors.next()) {
          factorsNotAssociated.push(factors.getUniqueValue() + '');
      }

      factorList = factorsNotAssociated.join(',');
      var control_assessment = new GlideRecord('sn_risk_advanced_control_assessment');
      if (control_assessment.get('sn_risk_advanced_assessment_type', assessmentType.getUniqueValue())) {
          factorList = factorList.replace(control_assessment.overall_effectiveness_factor, '');
      }

      return factorList;
  },

  getControlOverallEffectivenessFactor: function(controlAssessment) {
      return this._getControlOverallEffectivenessFactor(controlAssessment);
  },

  _getControlOverallEffectivenessFactor: function(controlAssessment) {
      var overall_effectiveness_factors = [];
      var haveLicenseToShowAutomatedFactor = this._hasLicenseToShowAutomatedFactors(controlAssessment);
      var factors = new GlideRecord('sn_risk_advanced_sub_factor');
      factors.addNullQuery('risk_assessment_methodology');
      factors.addNullQuery('parent');
      if (!haveLicenseToShowAutomatedFactor) {
          factors.addEncodedQuery("sys_class_name!=sn_risk_advanced_automated_query_factor^sys_class_name!=sn_risk_advanced_automated_scripted_factor");
      }
      factors.addQuery('state', '2');
      factors.addQuery('factor_contribution', 'IN', '2,3');
      factors.query();

      while (factors.next()) {
          var className = factors.sys_class_name;
          if ((className == 'sn_risk_advanced_automated_scripted_factor' || className == 'sn_risk_advanced_automated_query_factor')) {
              var automatedFactor = new GlideRecord(className);
              automatedFactor.get(factors.getUniqueValue());
              if (automatedFactor.factor_usage != '1')
                  continue;
          }
          overall_effectiveness_factors.push(factors.getUniqueValue() + '');
      }

      var groupFactors = new GlideRecord('sn_risk_advanced_group_factor');
      groupFactors.addNullQuery('risk_assessment_methodology');
      groupFactors.addQuery('state', '2');
      groupFactors.addQuery('factor_contribution', 'IN', '2,3');
      groupFactors.addQuery('factor_usage', '1');
      groupFactors.query();

      while (groupFactors.next()) {
          overall_effectiveness_factors.push(groupFactors.getUniqueValue() + '');
      }

      var asmtFactorm2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      asmtFactorm2m.addQuery('sn_risk_advanced_assessment_type', controlAssessment.getUniqueValue());
      asmtFactorm2m.addQuery('sn_risk_advanced_factor.factor_contribution', 'NOT IN', '4');
      asmtFactorm2m.query();
      while (asmtFactorm2m.next()) {
          overall_effectiveness_factors.push(asmtFactorm2m.sn_risk_advanced_factor + '');
      }

      return overall_effectiveness_factors.join(',');
  },

  _hasLicenseToShowAutomatedFactors: function(assessmentType) {
      var ramUtils = new sn_risk_advanced.RiskAssessmentMethodologyUtils();
      var hasEntitlementAccess = ramUtils.hasARALimitedLicense() || ramUtils.hasIRMProfessional() || ramUtils.hasIRMEnterpriseLicense();
      //Check if entitlements are there, if not provide access else check for specific entitlements like ARA etc. 
      return (!hasEntitlementAccess) || ((ramUtils.hasARALimitedLicense() && assessmentType.risk_assessment_methodology.license != 0) || ramUtils.hasIRMEnterpriseLicense());
  },

  getFactorsForResidualAssessment: function(residualAssessment) {
      return this._getFactorsForResidualAssessment(residualAssessment);
  },

  _getFactorsForResidualAssessment: function(residualAssessment) {
      var factorsNotAssociated = this._getFactorsNotAssociatedToAnyRAM(residualAssessment);
      var inherentFactors = [];
      var asmtTypeFactrM2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', residualAssessment.risk_assessment_methodology);
      asmtTypeFactrM2m.addQuery('sn_risk_advanced_assessment_type.sys_class_name', 'sn_risk_advanced_inherent_assessment');
      if (residualAssessment.assessment_contribution == '1')
          asmtTypeFactrM2m.addQuery('sn_risk_advanced_factor.factor_contribution', '1');
      else if (residualAssessment.assessment_contribution == '2') {
          asmtTypeFactrM2m.addQuery('sn_risk_advanced_factor.factor_contributionIN2,3');
      } else
          asmtTypeFactrM2m.addQuery('sn_risk_advanced_factor.factor_contributionIN1,2,3');
      asmtTypeFactrM2m.query();

      while (asmtTypeFactrM2m.next()) {
          inherentFactors.push(asmtTypeFactrM2m.sn_risk_advanced_factor + '');
      }

      var inherent = inherentFactors.join(',');

      var result = inherent.concat(',' + factorsNotAssociated);
      return result;
  },

  validateResidualAssessment: function(residualAssessment, errorMesg) {
      return this._validateResidualAssessment(residualAssessment, errorMesg);
  },

  _validateResidualAssessment: function(residualAssessment, errorMesg) {
      var isPresent, factorAssociation = true,
          ratingAssociation = true;
      if (residualAssessment.qualitative_scoring_logic == 'SCRIPT' || residualAssessment.quantitative_scoring_logic == 'SCRIPT') {
          var result = {};
          new sn_risk_advanced.FactorUtils().validateBothAsmtTypeScripts(residualAssessment, result);
          if (result.error) {
              gs.addErrorMessage(result.error);
              return false;
          }
      }
      if (residualAssessment.calculate_based_on == 'factor_responses') {
          if (residualAssessment.factors_same_as_inherent == true) {
              var inherent = new GlideRecord('sn_risk_advanced_inherent_assessment');
              isPresent = inherent.get('risk_assessment_methodology', residualAssessment.risk_assessment_methodology);
              if (isPresent && inherent.state != '2') {
                  gs.addErrorMessage(gs.getMessage("Publish the inherent assessment before publishing the residual assessment."));
                  return false;

              }

              //Rating criteria is not copied over from inherent assessment by default, so validation required
              if (residualAssessment.assessment_contribution != '1')
                  ratingAssociation = this._checkRatingAssociated(residualAssessment);
              return ratingAssociation;
          } else {
              factorAssociation = this._checkFactorsAssociated(residualAssessment);
              if (residualAssessment.assessment_contribution != '1')
                  ratingAssociation = this._checkRatingAssociated(residualAssessment);
              return factorAssociation && ratingAssociation;
          }
      } else if (residualAssessment.calculate_based_on == 'overall_assessment') {
          if (residualAssessment.assessment_contribution != '1') {
              ratingAssociation = this._checkRatingAssociated(residualAssessment);
              return ratingAssociation;
          }
      } else {
          if (residualAssessment.qualitative_scoring_type == 'lookup_matrix') {
              var residual_matrix = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
              var matrixPresent = residual_matrix.get('sn_risk_advanced_assessment_type', residualAssessment.getUniqueValue());
              if (!matrixPresent) {
                  if (this._validateInherentControlRatingCriteria(residualAssessment, errorMesg) == null)
                      return false;
              }
              return this._validateAssessmentMatrix(residualAssessment);
          } else {
              return this._checkRatingAssociated(residualAssessment);
          }
      }
      return true;
  },

  _validateInherentControlRatingCriteria: function(residualAssessment, errorMesg) {
      var inherent = true,
          control = true;
      var inherent_ratings = [];
      var control_ratings = [];

      var inherent_asmt = new GlideRecord('sn_risk_advanced_inherent_assessment');
      inherent = inherent_asmt.get('risk_assessment_methodology', residualAssessment.risk_assessment_methodology);

      var control_asmt = new GlideRecord('sn_risk_advanced_control_assessment');
      control = control_asmt.get('risk_assessment_methodology', residualAssessment.risk_assessment_methodology);

      if (!inherent && !control) {
          if (errorMesg) {
              gs.addErrorMessage(gs.getMessage("Define inherent and control assessment to generate residual assessment matrix"));
          }
          return null;
      } else if (!inherent) {
          if (errorMesg) {
              gs.addErrorMessage(gs.getMessage("Define inherent assessment to generate residual assessment matrix"));
          }
          return null;
      } else if (!control) {
          if (errorMesg) {
              gs.addErrorMessage(gs.getMessage("Define control assessment to generate residual assessment matrix"));
          }
          return null;
      } else {
          var inherent_rating = new GlideRecord('sn_risk_advanced_rating_criteria');
          inherent_rating.addQuery('assessment_type', inherent_asmt.getUniqueValue());
          inherent_rating.orderBy('lower_interval');
          inherent_rating.query();

          var control_rating = new GlideRecord('sn_risk_advanced_rating_criteria');
          control_rating.addQuery('assessment_type', control_asmt.getUniqueValue());
          control_rating.orderBy('lower_interval');
          control_rating.query();

          if (!inherent_rating.hasNext() && !control_rating.hasNext()) {
              if (errorMesg) {
                  gs.addErrorMessage(gs.getMessage("Specify rating criteria in inherent and control assessment to generate assessment matrix"));
              }
              return null;
          } else if (!inherent_rating.hasNext()) {
              if (errorMesg) {
                  gs.addErrorMessage(gs.getMessage("Specify rating criteria in inherent assessment to generate assessment matrix"));
              }
              return null;
          } else if (!control_rating.hasNext()) {
              if (errorMesg) {
                  gs.addErrorMessage(gs.getMessage("Specify rating criteria in control assessment to generate assessment matrix"));
              }
              return null;
          } else {
              var ratings = {};
              while (inherent_rating.next()) {
                  inherent_ratings.push(inherent_rating.getUniqueValue() + '');
              }

              while (control_rating.next()) {
                  control_ratings.push(control_rating.getUniqueValue() + '');
              }

              ratings.inherent_ratings = inherent_ratings;
              ratings.control_ratings = control_ratings;
              return ratings;
          }
      }

  },

  _validateAssessmentMatrix: function(residualAssessment) {
      var matrix = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      matrix.addQuery('sn_risk_advanced_assessment_type', residualAssessment.getUniqueValue());
      matrix.orderBy('display_order');
      matrix.query();

      var valid = true;
      var scoreLabel = matrix.getElement('score').getLabel();
      var ratingLabel = matrix.getElement('rating').getLabel();
      var riskColorLabel = matrix.getElement('risk_color_style').getLabel();
      var overriddenScoreLable = matrix.getElement('overridden_score').getLabel();

      var message = gs.getMessage("Each entry in the assessment matrix must have a {0}, a {1}, a {2} and an {3}.", [scoreLabel, ratingLabel, riskColorLabel, overriddenScoreLable]);
      message = "<p>" + message + "</p> <ul style='padding-left:40px'>";
      while (matrix.next()) {
          var fields = '';
          if (gs.nil(matrix.getValue('score')))
              fields += scoreLabel + ', ';

          if (gs.nil(matrix.getValue('rating')))
              fields += ratingLabel + ', ';

          if (gs.nil(matrix.getValue('risk_color_style')))
              fields += riskColorLabel + ', ';

          if (gs.nil(matrix.getValue('overridden_score')))
              fields += overriddenScoreLable + ', ';

          if (!gs.nil(fields)) {
              fields = fields.slice(0, fields.length - 2);
              message += '<li>' + gs.getMessage('In Row {0}, provide {1}.', [matrix.getValue('display_order'), fields]) + '</li>';
              valid = false;
          }
      }

      if (!valid) {
          message += '</ul>';
          gs.addErrorMessage(message);
      }

      return valid;
  },


  deleteFactorsForAssessment: function(assessment) {
      this._deleteFactorsForAssessment(assessment);
  },

  _deleteFactorsForAssessment: function(assessment) {
      var typeFactorm2m = new GlideRecord('sn_risk_advanced_asmt_type_m2m_factor');
      typeFactorm2m.addQuery('sn_risk_advanced_assessment_type', assessment.getUniqueValue());
      if (assessment.sys_class_name == 'sn_risk_advanced_inherent_assessment') {
          if (assessment.calculate_based_on == 'factor_responses') {
              typeFactorm2m.addQuery('sn_risk_advanced_factor.factor_contribution', 'NOT IN', assessment.assessment_contribution + ',3,4');
          }
      } else if (assessment.sys_class_name == 'sn_risk_advanced_target_assessment') {
          if (assessment.calculate_based_on == 'factor_responses' || assessment.calculate_based_on == 'factor_same_as_inherent' || assessment.calculate_based_on == 'factor_same_as_residual') {
              typeFactorm2m.addQuery('sn_risk_advanced_assessment_type.risk_assessment_methodology', assessment.risk_assessment_methodology);
              typeFactorm2m.addQuery('sn_risk_advanced_assessment_type.sys_class_name', 'sn_risk_advanced_target_assessment');
              typeFactorm2m.addQuery('sn_risk_advanced_factor.factor_contribution', 'NOT IN', assessment.assessment_contribution + '3,4');
          }
      }
      typeFactorm2m.deleteMultiple();
  },


  deleteRatingForAssessment: function(assessment) {
      this._deleteRatingForAssessment(assessment);
  },

  _deleteRatingForAssessment: function(assessment) {
      var rating = new GlideRecord('sn_risk_advanced_rating_criteria');
      rating.get('assessment_type', assessment.getUniqueValue());
      rating.deleteMultiple();
  },

  updateColorsInRatingCriteriaAndMatrix: function(style) {
      this._updateColorsInRatingCriteriaAndMatrix(style);
  },

  _updateColorsInRatingCriteriaAndMatrix: function(style) {
      var ratingCriteria = new GlideRecord('sn_risk_advanced_rating_criteria');
      ratingCriteria.addQuery('risk_color_style', style.getUniqueValue());
      ratingCriteria.setValue('background_color', style.background_color);
      ratingCriteria.setValue('text_color', style.text_color);
      ratingCriteria.updateMultiple();

      var matrix = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      matrix.addQuery('risk_color_style', style.getUniqueValue());
      matrix.setValue('background_color', style.background_color);
      matrix.setValue('text_color', style.text_color);
      matrix.updateMultiple();
  },

  _handleRiskColorStyleChangeInMatrix: function(matrixRecord) {
      var riskColourStyleId = matrixRecord.getValue('risk_color_style');

      //Update all other risk colour for all other records having same rating
      var gr = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr.addQuery('rating', matrixRecord.rating);
      gr.addQuery('sys_id', '!=', matrixRecord.getUniqueValue());
      gr.setValue('risk_color_style', riskColourStyleId);
      gr.setValue('text_color', matrixRecord.getValue('text_color'));
      gr.setValue('background_color', matrixRecord.getValue('background_color'));
      gr.setWorkflow(false);
      gr.updateMultiple();


      var assessmentType = new GlideRecord('sn_risk_advanced_residual_assessment');
      assessmentType.get(matrixRecord.sn_risk_advanced_assessment_type);

      //Sync risk colour from matrix to qualitative rating criteria
      if (assessmentType.state == 2)
          this._updateRatingCriteriaWithRiskColorStyle(riskColourStyleId, matrixRecord.getValue('sn_risk_advanced_assessment_type'), matrixRecord.getValue('rating'));
  },

  _updateRatingCriteriaWithRiskColorStyle: function(riskColorStyleId, assessmentTypeId, rating) {
      var ratingCriteria = new GlideRecord('sn_risk_advanced_rating_criteria');
      ratingCriteria.addQuery('rating', rating);
      ratingCriteria.addQuery('assessment_type', assessmentTypeId);
      ratingCriteria.query();
      if (ratingCriteria.next()) {
          ratingCriteria.setValue('risk_color_style', riskColorStyleId);
          ratingCriteria.update();
      }
  },

  _updateOverriddenScoreAndRiskColorStyle: function(matrixRecord) {
      var gr = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr.addQuery('rating', matrixRecord.getValue('rating'));
      gr.addQuery('sn_risk_advanced_assessment_type', matrixRecord.getValue('sn_risk_advanced_assessment_type'));
      gr.setLimit(1);
      gr.query();
      if (gr.next()) {
          matrixRecord.setValue('risk_color_style', gr.getValue('risk_color_style'));
          matrixRecord.setValue('overridden_score', gr.getValue('overridden_score'));
      }
  },


  _syncRatingCriteriaChangestoMatrix: function(ratingCriteria, previousRatingCriteria) {
      var residualAssessment = new GlideRecord('sn_risk_advanced_residual_assessment');
      residualAssessment.get(ratingCriteria.assessment_type);
      if (residualAssessment.calculate_based_on == 'inherent_control' && residualAssessment.qualitative_scoring_type == 'lookup_matrix') {
          if (ratingCriteria.rating.changes())
              this._updateMatrixRating(previousRatingCriteria.getValue('rating'), ratingCriteria.getValue('rating'), residualAssessment.getUniqueValue());
          if (ratingCriteria.risk_color_style.changes())
              this._updateMatrixRiskColorStyle(ratingCriteria.getValue('rating'), ratingCriteria.getValue('risk_color_style'), residualAssessment.getUniqueValue());
      }
  },

  _updateMatrixRating: function(previousValue, currentValue, assessmentTypeId) {
      var gr = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr.addQuery('rating', previousValue);
      gr.addQuery('sn_risk_advanced_assessment_type', assessmentTypeId);
      gr.setValue('rating', currentValue);
      gr.setWorkflow(false);
      gr.updateMultiple();
  },


  _updateMatrixRiskColorStyle: function(rating, riskColorStyleId, assessmentTypeId) {
      var gr = new GlideRecord('sn_risk_advanced_residual_assessment_matrix');
      gr.addQuery('rating', rating);
      gr.addQuery('sn_risk_advanced_assessment_type', assessmentTypeId);
      gr.setValue('risk_color_style', riskColorStyleId);
      gr.setWorkflow(false);
      gr.updateMultiple();
  },

  _canShowEditButtonForAssessmentType: function(parent) {
      return ((parent.calculate_based_on == 'factor_responses' && !parent.factors_same_as_inherent) ||
          (parent.control_assessment_methodology == 'control_env_assessment') ||
          (parent.calculate_based_on == 'factor_responses' && (parent.sys_class_name == 'sn_risk_advanced_target_assessment')));
  },

  _isAssessmentTypePublished: function(ramReference, className) {
      var asmtType = new GlideRecord('sn_risk_advanced_assessment_type');
      asmtType.addQuery('risk_assessment_methodology', ramReference);
      asmtType.addQuery('sys_class_name', className);
      asmtType.query();

      if (asmtType.next()) {
          if (asmtType.state == '2')
              return true;
          else
              return false;
      }

      return false;
  },

  _isAssessmentTypeMandatory: function(assessmentInstanceId, assessmentState, ramId) {
      if (assessmentState == "10") {
          var targetAssessment = this._getAssessment(ramId, "sn_risk_advanced_target_assessment");
          switch (targetAssessment.getValue('make_assessment_mandatory')) {
              case '1':
                  return true;
              case '2':
                  return this._checkSpecificConditions(targetAssessment, assessmentInstanceId);
              case '3':
                  return this._evaluateMakeAssessmentMandatoryScript(targetAssessment, assessmentInstanceId);
              default:
                  return true;
          }
      }
      return true;
  },

  _checkSpecificConditions: function(targetAssessment, assessmentInstanceId) {
      var encodedQuery = targetAssessment.getValue('specific_conditions');
      return new AdvancedRiskUtils().doesRecordSatisfyFilterQuery("sn_risk_advanced_risk_assessment_instance", assessmentInstanceId, encodedQuery);
  },

  _evaluateMakeAssessmentMandatoryScript: function(assessmentType, assessmentInstanceId) {

      var makeAssessmentMandatory = true;
      var evaluator = new GlideScopedEvaluator();

      evaluator.putVariable('asmtId', assessmentInstanceId);
      evaluator.putVariable('result', {});
      evaluator.evaluateScript(assessmentType, 'make_assessment_mandatory_script', null);
      var result = evaluator.getVariable('result');
      if (result.error) {
          return true;
      } else {
          // If there is no error, then get the enableAssessment
          makeAssessmentMandatory = result.makeAssessmentMandatory;
      }
      return makeAssessmentMandatory;

  },

  _getAssessment: function(ramId, sysClassName) {
      var assessmentType = new GlideRecord(sysClassName);
      assessmentType.addQuery('risk_assessment_methodology', ramId);
      assessmentType.query();
      assessmentType.next();
      return assessmentType;
  },

  _isTargetOverallAssessment: function(ramId) {
      var targetAssessment = new GlideRecord("sn_risk_advanced_target_assessment");
      targetAssessment.get('risk_assessment_methodology', ramId);
      if (targetAssessment.calculate_based_on == 'overall_assessment') {
          return true;
      }
      return false;
  },

  _getIsAssessmentTypeMandatoryFlag: function(assessmentInstanceId, assessmentType) {
      var asmtInstance = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      asmtInstance.get(assessmentInstanceId);
      if (assessmentType == '4') {
          return asmtInstance.is_target_assessment_mandatory;
      }
      return true;
  },

  type: 'AssessmentTypeUtilsBase'
};

Sys ID

b9f147a153a100105f9fddeeff7b122c

Offical Documentation

Official Docs: