Name

sn_risk_advanced.RiskAppetiteUtilsBase

Description

Utility for risk appetite methods

Script

var RiskAppetiteUtilsBase = Class.create();
RiskAppetiteUtilsBase.prototype = {
  initialize: function() {
      this.asmtTypeTables = {
          2: "sn_risk_advanced_inherent_assessment",
          3: "sn_risk_advanced_control_assessment",
          4: "sn_risk_advanced_residual_assessment",
          10: "sn_risk_advanced_target_assessment"
      };

      this.asmtTableColumns = {
          2: {
              "final_risk_rating": "summary_inherent_risk",
              "final_risk_rating_display": "summary_inherent_risk_score",
              "final_ale": "final_inherent_ale",
              "name": "inherent"
          },
          3: {
              "final_risk_rating": "summary_control_effectiveness",
              "final_risk_rating_display": "summary_control_effectiveness_score",
              "name": "control effectiveness"
          },
          4: {
              "final_risk_rating": "summary_residual_risk",
              "final_risk_rating_display": "summary_residual_risk_score",
              "final_ale": "final_residual_ale",
              "name": "residual"
          },
          10: {
              "final_risk_rating": "summary_target_risk",
              "final_risk_rating_display": "summary_target_risk_score",
              "final_ale": "final_target_ale",
              "name": "target"
          },
      };

      this.withInAppetiteStatusId = "e20308cd53611110bad1ddeeff7b1292";
      this.outsideAppetiteStautusId = "a713c0cd53611110bad1ddeeff7b120d";
      this.outsideToleranceStautusId = "7d2348cd53611110bad1ddeeff7b12ea";

      this.appetiteColorMapping = {};
      this.appetiteColorMapping['critical'] = {
          "colorVariable": "--now-color_alert--critical-4",
          "defaultValue": "120,36,32",
          "backgroundColorVariable": "--now-color_alert--critical-1",
          "defaultBackgroundColor": "221,133,129"
      };
      this.appetiteColorMapping['high'] = {
          "colorVariable": "--now-color_alert--high-4",
          "defaultValue": "133,87,20",
          "backgroundColorVariable": "--now-color_alert--high-1",
          "defaultBackgroundColor": "234,186,117"
      };
      this.appetiteColorMapping['warning'] = {
          "colorVariable": "--now-color_alert--warning-4",
          "defaultValue": "149,139,17",
          "backgroundColorVariable": "--now-color_alert--warning-1",
          "defaultBackgroundColor": "227,218,96"
      };
      this.appetiteColorMapping['moderate'] = {
          "colorVariable": "--now-color_alert--moderate-4",
          "defaultValue": "50,52,124",
          "backgroundColorVariable": "--now-color_alert--moderate-1",
          "defaultBackgroundColor": "148,149,225"
      };
      this.appetiteColorMapping['positive'] = {
          "colorVariable": "--now-color_alert--positive-4",
          "defaultValue": "22,79,26",
          "backgroundColorVariable": "--now-color_alert--positive-1",
          "defaultBackgroundColor": "119,178,123"
      };
      this.appetiteColorMapping['low'] = {
          "colorVariable": "--now-color_alert--low-4",
          "defaultValue": "61,61,61",
          "backgroundColorVariable": "--now-color_alert--low-1",
          "defaultBackgroundColor": "159,159,159"
      };
      this.appetiteColorMapping['info'] = {
          "colorVariable": "--now-color_alert--info-4",
          "defaultValue": "8,72,118",
          "backgroundColorVariable": "--now-color_alert--info-1",
          "defaultBackgroundColor": "104,171,218"
      };
      this.appetiteColorMapping['magenta'] = {
          "colorVariable": "--now-color_grouped--magenta-4",
          "defaultValue": "142,85,135",
          "backgroundColorVariable": "--now-color_grouped--magenta-1",
          "defaultBackgroundColor": "221,168,215"
      };
      this.appetiteColorMapping['pink'] = {
          "colorVariable": "--now-color_grouped--pink-4",
          "defaultValue": "142,85,100",
          "backgroundColorVariable": "--now-color_grouped--pink-1",
          "defaultBackgroundColor": "221,168,182"
      };
      this.appetiteColorMapping['orange'] = {
          "colorVariable": "--now-color_grouped--orange-4",
          "defaultValue": "151,90,74",
          "backgroundColorVariable": "--now-color_grouped--orange-1",
          "defaultBackgroundColor": "229,173,158"
      };
      this.appetiteColorMapping['yellow'] = {
          "colorVariable": "--now-color_grouped--yellow-4",
          "defaultValue": "168,145,71",
          "backgroundColorVariable": "--now-color_grouped--yellow-1",
          "defaultBackgroundColor": "245,224,155"
      };
      this.appetiteColorMapping['brown'] = {
          "colorVariable": "--now-color_grouped--brown-4",
          "defaultValue": "109,97,83",
          "backgroundColorVariable": "--now-color_grouped--brown-1",
          "defaultBackgroundColor": "191,179,167"
      };
      this.appetiteColorMapping['green'] = {
          "colorVariable": "--now-color_grouped--green-4",
          "defaultValue": "103,119,88",
          "backgroundColorVariable": "--now-color_grouped--green-1",
          "defaultBackgroundColor": "185,200,171"
      };
      this.appetiteColorMapping['green-yellow'] = {
          "colorVariable": "--now-color_grouped--green-yellow-4",
          "defaultValue": "108,121,66",
          "backgroundColorVariable": "--now-color_grouped--green-yellow-1",
          "defaultBackgroundColor": "189,202,150"
      };
      this.appetiteColorMapping['blue'] = {
          "colorVariable": "--now-color_grouped--blue-4",
          "defaultValue": "84,123,143",
          "backgroundColorVariable": "--now-color_grouped--blue-1",
          "defaultBackgroundColor": "167,204,222"
      };
      this.appetiteColorMapping['grey'] = {
          "colorVariable": "--now-color_grouped--gray-4",
          "defaultValue": "97,102,105",
          "backgroundColorVariable": "--now-color_grouped--gray-1",
          "defaultBackgroundColor": "189,202,150"
      };
      this.appetiteColorMapping['teal'] = {
          "colorVariable": "--now-color_grouped--teal-4",
          "defaultValue": "73,122,114",
          "backgroundColorVariable": "--now-color_grouped--teal-1",
          "defaultBackgroundColor": "157,202,195"
      };
      this.appetiteColorMapping['purple'] = {
          "colorVariable": "--now-color_grouped--purple-4",
          "defaultValue": "127,109,146",
          "backgroundColorVariable": "--now-color_grouped--purple-1",
          "defaultBackgroundColor": "207,190,225"
      };

  },

  getAppetiteStatusMessagesForRiskStatement: function(riskStatment) {
      return this._getAppetiteStatusMessagesForRiskStatement(riskStatment);
  },

  getAppetiteStatusMessagesForAssessment: function(assessment) {
      return this._getAppetiteStatusMessagesForAssessment(assessment);
  },


  getAppetiteStatusMessagesForEntity: function(entity) {
      return this._getAppetiteStatusMessagesForEntity(entity);
  },

  getOverallAppetiteStatus: function(qual_appetite_status, quant_appetite_status, isTwoPointScale) {
      return this._getOverallAppetiteStatus(qual_appetite_status, quant_appetite_status, isTwoPointScale);
  },

  getAppetiteFieldsToHide: function(asmtInstance) {
      return this._getAppetiteFieldsToHide(asmtInstance);
  },

  computeAppetiteStatusOnRollUpChange: function(rollUpRecord) {
      this._computeAppetiteStatusOnRollUpChange(rollUpRecord);
  },

  computeAppetiteStatusOnRollUpDelete: function(rollUpRecord) {
      this._computeAppetiteStatusOnRollUpDelete(rollUpRecord);
  },

  computeAppetiteStatusForRiskStatement: function(riskStatement, shouldUpdate) {
      this._computeAppetiteStatusForRiskStatement(riskStatement, shouldUpdate);
  },

  computeAppetiteStatusForEntity: function(entity, shouldUpdate) {
      this._computeAppetiteStatusForEntity(entity, shouldUpdate);
  },

  getRollupRecordForRiskStatement: function(riskStatementId, ramId) {
      return this._getRollupRecordForRiskStatement(riskStatementId, ramId);
  },

  getRiskAppetiteSectionInfo: function(asmtInstanceId) {
      return this._getRiskAppetiteSectionInfo(asmtInstanceId);
  },

  computeAppetiteStatusForRiskAssessment: function(asmtInstance, shouldUpdate) {
      this._computeAppetiteStatusForRiskAssessment(asmtInstance, shouldUpdate);
  },

  computeAppetiteStatusForTargetRiskAssessment: function(asmtInstance, shouldUpdate) {
      this._computeAppetiteStatusForTargetRiskAssessment(asmtInstance, shouldUpdate);
  },

  getLastAssessmentState: function(ram) {
      return this._getLastAssessmentState(ram);
  },

  isJustificationRequired: function(assessmentInstanceId) {
      return this._isJustificationRequired(assessmentInstanceId);
  },

  isRiskResponseRequired: function(assessmentInstanceId) {
      return this._isRiskResponseRequired(assessmentInstanceId);
  },

  validateLastStateComments: function(assessmentInstanceId) {
      return this._validateLastStateComments(assessmentInstanceId);
  },

  isRiskAppetiteEnabled: function() {
      return this._isRiskAppetiteEnabled();
  },

  verifyToleranceIsGreaterThanAppetite: function(record) {
      return this._verifyToleranceIsGreaterThanAppetite(record);
  },

  clearAppetiteFromAssessmentType: function(assmtTable, ram) {
      return this._clearAppetiteFromAssessmentType(assmtTable, ram);
  },

  getAppetiteStatusColors: function() {
      return this._getAppetiteStatusColors();
  },

  copyAppetiteToDownstreamRisks: function(riskDefId) {
      return this._copyAppetiteToDownstreamRisks(riskDefId);
  },

  hasDownstreamRisks: function(riskDefId) {
      return this._hasDownstreamRisks(riskDefId);
  },

  copyAppetiteToDownstreamEntities: function(entityId) {
      return this._copyAppetiteToDownstreamEntities(entityId);
  },

  hasDownstreamEntities: function(entityId) {
      return this._hasDownstreamEntities(entityId);
  },

  getRiskAppetiteValuesForRisk: function(riskId) {
      return this._getRiskAppetiteValuesForRisk(riskId);
  },

  getAppetiteStatusColorsAndIconsWS: function() {
      return this._getAppetiteStatusColorsAndIconsWS();
  },

  computeAllAssessmentsAppetiteStatus: function(risk) {
      return this._computeAllAssessmentsAppetiteStatus(risk);
  },

  handleAppetiteScaleValueChange: function(appetiteScale) {
      return this._handleAppetiteScaleValueChange(appetiteScale);
  },

  handleInActiveAppetiteScale: function(appetiteScale) {
      return this._handleInActiveAppetiteScale(appetiteScale);
  },

  handleAppetiteScaleChangeOnRatingCriteria: function(ratingCriteria) {
      return this._handleAppetiteScaleChangeOnRatingCriteria(ratingCriteria);
  },

  sendRiskAppetiteReviewNotification: function() {
      this._sendRiskAppetiteReviewNotification();
  },

  setOverallAppetiteStatus: function(record) {
      this._setOverallAppetiteStatus(record);
  },

  setProjectedAppetiteStatus: function(record) {
      this._setProjectedAppetiteStatus(record);
  },

  handleAppetiteTypePropertyChange: function(oldValue, newValue) {
      this._handleAppetiteTypePropertyChange(oldValue, newValue);
  },

  handleAppetiteScalePropertyChange: function(oldValue, newValue) {
      this._handleAppetiteScalePropertyChange(oldValue, newValue);
  },

  getAppetitePropertyChangeInprogressMessage: function() {
      return this._getAppetitePropertyChangeInprogressMessage();
  },

  createEmailNotificationForRiskAppetiteStatusBreach: function(currentState, previousState, salutationName, owner, tableName, record) {
      return this._createEmailNotificationForRiskAppetiteStatusBreach(currentState, previousState, salutationName, owner, tableName, record);
  },

  getAppetiteScaleChangeInProgressMessage: function() {
      return this._getAppetiteScaleChangeInProgressMessage();
  },

  canShowAppetiteDetails: function() {
      return this._canShowAppetiteDetails();
  },

  canShowCopyAppetiteActionOnEntity: function(entity) {
      return this._canShowCopyAppetiteActionOnEntity(entity);
  },

  canShowCopyAppetiteActionOnRiskStatement: function(riskStatement) {
      return this._canShowCopyAppetiteActionOnRiskStatement(riskStatement);
  },

  _canShowCopyAppetiteActionOnEntity: function(entity) {
      return !entity.disable_copy_appetite && this.isRiskAppetiteEnabled() && this._canHaveQualitativeAppetite() && this._hasDownstreamEntities(entity.getUniqueValue());
  },

  _canShowCopyAppetiteActionOnRiskStatement: function(riskStatement) {
      return !riskStatement.disable_copy_appetite && this.isRiskAppetiteEnabled() && this._canHaveQualitativeAppetite() && this._hasDownstreamRisks(riskStatement.getUniqueValue());
  },

  _getActiveRiskAssessmentState: function() {
      return new sn_risk_advanced.RiskAssessmentUtils().getActiveRiskAssessmentState();
  },

  _sendRiskAppetiteReviewNotification: function() {
      var gdt = new GlideDate();
      var daysLeft = gs.getProperty("sn_risk_advanced.risk_appetite_review_notifcation");
      gdt.addDaysUTC(daysLeft);
      gdt.getByFormat("yyyy-mm-dd");
      var gr = new GlideRecord("sn_risk_definition");
      gr.addQuery("next_review_date", gdt.getValue());
      gr.query();
      while (gr.next()) {
          gs.eventQueue('sn_risk_advanced.appetite_review_date', gr, "", gr.getUniqueValue());
      }
  },

  _getAppetitePropertyChangeInprogressMessage: function() {
      var message = "";
      var isAppetiteTypePropertyChangeInProgress = gs.getProperty("sn_risk_advanced.appetite_type_prop_chage_in_progress", 'true') == 'true';
      var isAppetiteScalePropertyChangeInProgress = gs.getProperty("sn_risk_advanced.appetite_scale_prop_chage_in_progress", 'true') == 'true';
      if (isAppetiteTypePropertyChangeInProgress)
          message = gs.getMessage('Appetite type property change is in progress, please try after some time');
      else if (isAppetiteScalePropertyChangeInProgress)
          message = gs.getMessage('Appetite scale property change is in progress, please try after some time');
      return message;
  },

  _handleAppetiteTypePropertyChange: function(oldValue, newValue) {
      var appetiteStatusColumn = "";
      if (newValue == 'risk_appetite_qualitative') {
          this._setAppetiteData({
              'appetiteFields': {
                  'quant_appetite': '0',
                  'quant_tolerance': '0',
              },
              'appetiteStatusFields': {
                  'quant_appetite_status': 'NULL',
                  'computed_quant_appetite': 'NULL',
                  'overall_appetite_status': 'NULL',
              },
              'projectedAppetiteStatusFields': {
                  'projected_quant_appetite_status': 'NULL',
                  'projected_computed_quant_appetite': 'NULL',
                  'projected_appetite_status': 'NULL'
              },
              'risk_appetite_statement': 'NULL',
              'next_review_date': 'NULL'
          });
          appetiteStatusColumn = 'qual_appetite_status';
      } else if (newValue == 'risk_appetite_quantitative') {
          this._setAppetiteData({
              'appetiteFields': {
                  'qual_appetite': 'NULL',
                  'qual_tolerance': 'NULL'
              },
              'appetiteStatusFields': {
                  'qual_appetite_status': 'NULL',
                  'computed_qual_appetite': 'NULL',
                  'overall_appetite_status': 'NULL',
              },
              'projectedAppetiteStatusFields': {
                  'projected_qual_appetite_status': 'NULL',
                  'projected_computed_qual_appetite': 'NULL',
                  'projected_appetite_status': 'NULL',
              },
              'risk_appetite_statement': 'NULL',
              'next_review_date': 'NULL',
              'override_appetite': 'NULL',
              'override_justfication': 'NULL',
              'query': 'qual_appetiteISNOTEMPTY^ORqual_toleranceISNOTEMPTY',
              'assessmentQuery': 'risk.qual_appetiteISNOTEMPTY^ORrisk.qual_toleranceISNOTEMPTY'
          });
          appetiteStatusColumn = 'quant_appetite_status';
      }

      if (appetiteStatusColumn && oldValue == 'risk_appetite_both') {
          var hooks = new GlideScriptedExtensionPoint().getExtensions('sn_risk_advanced.setAppetiteValues');
          hooks.forEach(function(hook) {
              hook.copyOverallAppetitStatus(appetiteStatusColumn);
          });
      }

  },

  _handleAppetiteScalePropertyChange: function(oldValue, newValue) {
      if (newValue == 'risk_appetite_none') {
          this._setAppetiteData({
              'appetiteFields': {
                  'qual_appetite': 'NULL',
                  'qual_tolerance': 'NULL',
                  'quant_appetite': '0',
                  'quant_tolerance': '0'
              },
              'appetiteStatusFields': {
                  'qual_appetite_status': 'NULL',
                  'quant_appetite_status': 'NULL',
                  'overall_appetite_status': 'NULL',
                  'computed_quant_appetite': 'NULL',
                  'computed_qual_appetite': 'NULL',
              },
              'projectedAppetiteStatusFields': {
                  'projected_quant_appetite_status': 'NULL',
                  'projected_computed_quant_appetite': 'NULL',
                  'projected_qual_appetite_status': 'NULL',
                  'projected_computed_qual_appetite': 'NULL',
                  'projected_appetite_status': 'NULL'
              },
              'risk_appetite_statement': 'NULL',
              'next_review_date': 'NULL',
              'override_appetite': 'NULL',
              'override_justfication': 'NULL',
              'ram_status_calculation': 'NULL'
          });
      } else if (newValue == 'risk_appetite_one_point' && oldValue == "risk_appetite_two_point") {
          this._setAppetiteData({
              'appetiteFields': {
                  'qual_tolerance': 'NULL',
                  'quant_tolerance': '0',
              }
          });
          this._updateOutSideToleranceAppetiteStatusToOutSideAppetite();
          this._updateOutSideToleranceAppetiteStatusToOutSideAppetiteForTarget();
      }
  },

  _setAppetiteData: function(appetiteInfo) {
      var hooks = new GlideScriptedExtensionPoint().getExtensions('sn_risk_advanced.setAppetiteValues');
      hooks.forEach(function(hook) {
          hook.setAppetiteValues(appetiteInfo);
      });
  },

  _updateOutSideToleranceAppetiteStatusToOutSideAppetite: function() {
      var tables = ['sn_grc_profile', 'sn_risk_definition', 'sn_risk_advanced_risk_assessment_instance'];
      for (var i = 0; i < tables.length; i++) {
          var table = tables[i];
          var record = new GlideRecord(table);
          if (table == 'sn_risk_advanced_risk_assessment_instance') {
              record.addNotNullQuery('risk.qual_appetite');
              record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
          } else
              record.addNotNullQuery('qual_appetite');
          record.addQuery('qual_appetite_status', this.outsideToleranceStautusId);
          record.setValue('qual_appetite_status', this.outsideAppetiteStautusId);
          record.updateMultiple();

          record = new GlideRecord(table);
          if (table == 'sn_risk_advanced_risk_assessment_instance') {
              record.addNullQuery('risk.qual_appetite');
              record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
          } else
              record.addNullQuery('qual_appetite');
          record.addQuery('qual_appetite_status', this.outsideToleranceStautusId);
          record.setValue('qual_appetite_status', 'NULL');
          record.updateMultiple();

          record = new GlideRecord(table);
          if (table == 'sn_risk_advanced_risk_assessment_instance') {
              record.addQuery('state', 'IN', this._getActiveRiskAssessmentState());
          }
          record.addQuery('quant_appetite_status', this.outsideToleranceStautusId);
          record.setValue('quant_appetite_status', this.outsideAppetiteStautusId);
          record.updateMultiple();
      }
  },

  _updateOutSideToleranceAppetiteStatusToOutSideAppetiteForTarget: function() {
      var table = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      table.addNotNullQuery('risk.qual_appetite');
      table.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      table.addQuery('projected_qual_appetite_status', this.outsideToleranceStautusId);
      table.setValue('projected_qual_appetite_status', this.outsideAppetiteStautusId);
      table.updateMultiple();

      table = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      table.addNullQuery('risk.qual_appetite');
      table.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      table.addQuery('projected_qual_appetite_status', this.outsideToleranceStautusId);
      table.setValue('projected_qual_appetite_status', 'NULL');
      table.updateMultiple();

      table = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      table.addQuery('state', 'IN', this._getActiveRiskAssessmentState());
      table.addQuery('projected_quant_appetite_status', this.outsideToleranceStautusId);
      table.setValue('projected_quant_appetite_status', this.outsideAppetiteStautusId);
      table.updateMultiple();

  },

  _setOverallAppetiteStatus: function(record) {
      var qualStatus = record.getValue('qual_appetite_status');
      var quantStatus = record.getValue('quant_appetite_status');
      record.setValue('overall_appetite_status', this._getOverallAppetiteStatus(qualStatus, quantStatus, this._isTwoPointScale()));
  },

  _setProjectedAppetiteStatus: function(record) {
      var qualStatus = record.getValue('projected_qual_appetite_status');
      var quantStatus = record.getValue('projected_quant_appetite_status');
      record.setValue('projected_appetite_status', this._getOverallAppetiteStatus(qualStatus, quantStatus, this._isTwoPointScale()));
  },

  canShowRiskAppetiteScale: function(ratingCriteria) {

      var canShow = false;

      if (!this._isRiskAppetiteEnabled())
          return canShow;

      var assessmentType = new GlideRecord("sn_risk_advanced_assessment_type");
      assessmentType.get(ratingCriteria.getValue('assessment_type'));

      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ram.get(assessmentType.getValue('risk_assessment_methodology'));

      // Hide for Object based assessment
      if (ram.getValue("assessed_on") == 1)
          return canShow;

      // For target assessment always return true.
      if (assessmentType.getValue('sys_class_name') == "sn_risk_advanced_target_assessment")
          canShow = true;
      else {
          //Call a method to get last state of assessment, update canShow by comparing rating criteria
          var lastAssessableState = this._getLastAssessmentState(ram);
          if (ratingCriteria.assessment_type.sys_class_name == this.asmtTypeTables[lastAssessableState])
              canShow = true;
      }


      return canShow;
  },

  verifyAppetiteScaleOrder: function(ratingCrit) {
      // If we are trying to save an empty value, allow it
      if (gs.nil(ratingCrit.getValue("risk_appetite_scale")))
          return true;

      // Get the respective assessment
      var assessmentType = new GlideRecord("sn_risk_advanced_assessment_type");
      assessmentType.get(ratingCrit.getValue('assessment_type'));

      var appetiteScale = new GlideRecord("sn_risk_advanced_risk_appetite_scale");
      appetiteScale.get(ratingCrit.getValue("risk_appetite_scale"));
      var currentAppetiteScaleValue = appetiteScale.getValue("value");

      // check for the immediate small value
      var ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
      ratingCriteria.addQuery("assessment_type", assessmentType.getUniqueValue());
      ratingCriteria.addQuery("lower_interval", "<", ratingCrit.getValue("lower_interval"));
      ratingCriteria.orderByDesc("lower_interval");
      ratingCriteria.setLimit(1);
      ratingCriteria.query();


      if (ratingCriteria.next()) {
          appetiteScale = new GlideRecord("sn_risk_advanced_risk_appetite_scale");
          appetiteScale.get(ratingCriteria.getValue("risk_appetite_scale"));
          var lowerValue = appetiteScale.getValue("value");
          if (!gs.nil(lowerValue) && parseInt(lowerValue) > parseInt(currentAppetiteScaleValue))
              return false;
      }

      // check for the immediate higher value
      ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
      ratingCriteria.addQuery("assessment_type", assessmentType.getUniqueValue());
      ratingCriteria.addQuery("lower_interval", ">", ratingCrit.getValue("lower_interval"));
      ratingCriteria.orderBy("lower_interval");
      ratingCriteria.setLimit(1);
      ratingCriteria.query();

      if (ratingCriteria.next()) {
          appetiteScale = new GlideRecord("sn_risk_advanced_risk_appetite_scale");
          appetiteScale.get(ratingCriteria.getValue("risk_appetite_scale"));
          var higherValue = appetiteScale.getValue("value");
          if (!gs.nil(higherValue) && parseInt(higherValue) < parseInt(currentAppetiteScaleValue))
              return false;
      }

      return true;

  },

  _clearAppetiteFromAssessmentType: function(assmtTable, ram) {

      var asmt = new GlideRecord(assmtTable);
      asmt.addQuery("risk_assessment_methodology", ram);
      asmt.query();

      if (asmt.next()) {
          var ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
          ratingCriteria.addQuery("assessment_type", asmt.getUniqueValue());
          ratingCriteria.query();

          while (ratingCriteria.next()) {
              ratingCriteria.setValue("risk_appetite_scale", '');
              ratingCriteria.update();
          }
      }
  },

  _isRiskAppetiteEnabled: function() {
      return gs.getProperty('sn_risk_advanced.hide_risk_legacy_lifecycle', 'false') == 'true' && gs.getProperty('sn_risk_advanced.risk_appetite_scale', 'risk_appetite_none') != 'risk_appetite_none';
  },


  _verifyToleranceIsGreaterThanAppetite: function(record) {
      var appetiteScale = gs.getProperty('sn_risk_advanced.risk_appetite_scale', 'risk_appetite_none');

      var message = "";
      if (appetiteScale == "risk_appetite_two_point") {
          var qualMessage = gs.getMessage('The qualitative tolerance should be greater than the qualitative appetite');
          var quantMessage = gs.getMessage('The quantitative tolerance should be greater than the quantitative appetite');
          var bothMessage = gs.getMessage('The qualitative and quantitative tolerances should be greater than the qualitative and quantitative appetites');
          var appetiteType = gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative');


          var qualAppetiteValue = '';
          if (record.qual_appetite)
              qualAppetiteValue = record.qual_appetite.value;

          var qualToleranceValue = '';
          if (record.qual_tolerance)
              qualToleranceValue = record.qual_tolerance.value;
          var quantAppetiteValue = parseFloat(record.quant_appetite.getReferenceValue());
          var quantToleranceValue = parseFloat(record.quant_tolerance.getReferenceValue());

          if (appetiteType == 'risk_appetite_qualitative') {
              if (qualAppetiteValue && qualToleranceValue && qualAppetiteValue > qualToleranceValue)
                  message = qualMessage;
          } else if (appetiteType == 'risk_appetite_quantitative') {
              if (quantAppetiteValue > quantToleranceValue)
                  message = quantMessage;
          } else if (appetiteType == 'risk_appetite_both') {
              if ((qualAppetiteValue && qualToleranceValue && qualAppetiteValue > qualToleranceValue) && quantAppetiteValue > quantToleranceValue)
                  message = bothMessage;
              else if (qualAppetiteValue && qualToleranceValue && qualAppetiteValue > qualToleranceValue)
                  message = qualMessage;
              else if (quantAppetiteValue > quantToleranceValue)
                  message = quantMessage;
          }
      }
      var isValid = gs.nil(message);
      return {
          isValid: isValid,
          message: message
      };
  },

  _getLastAssessmentState: function(ram) {
      if (ram.getValue("residual_risk") == true) {
          var asmtType = new GlideRecord("sn_risk_advanced_residual_assessment");
          asmtType.addQuery("risk_assessment_methodology", ram.getUniqueValue());
          asmtType.query();
          if (asmtType.next()) {
              return 4;
          }
      } else if (ram.getValue("control_effectiveness") == true) {
          asmtType = new GlideRecord("sn_risk_advanced_control_assessment");
          asmtType.addQuery("risk_assessment_methodology", ram.getUniqueValue());
          asmtType.query();
          if (asmtType.next()) {
              return 3;
          }
      } else if (ram.getValue("inherent_risk") == true) {
          asmtType = new GlideRecord("sn_risk_advanced_inherent_assessment");
          asmtType.addQuery("risk_assessment_methodology", ram.getUniqueValue());
          asmtType.query();
          if (asmtType.next()) {
              return 2;
          }
      }
      return;
  },

  _isJustificationRequired: function(assessmentInstanceId) {
      var assessmentInstance = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      assessmentInstance.get(assessmentInstanceId);
      var ramId = assessmentInstance.getValue('risk_assessment_methodology');
      var ramRecord = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ramRecord.get(ramId);
      var isLastStateCommentMandatory = false;
      var validateCommentIsProvided = ramRecord.getValue("validate_comment_is_provided");
      var appetiteStatus = assessmentInstance.getValue("overall_appetite_status");
      if (validateCommentIsProvided == "always")
          isLastStateCommentMandatory = true;
      else if (validateCommentIsProvided == "on_breach_of_appetite") {
          if (appetiteStatus == this.outsideAppetiteStautusId || appetiteStatus == this.outsideToleranceStautusId)
              isLastStateCommentMandatory = true;
      } else if (validateCommentIsProvided == "on_breach_of_tolerance") {
          if (appetiteStatus == this.outsideToleranceStautusId)
              isLastStateCommentMandatory = true;
      }
      var response = {};
      response.isLastStateCommentMandatory = isLastStateCommentMandatory;
      response.validateCommentIsProvided = validateCommentIsProvided;
      var appetiteStatusRecord = new GlideRecord("sn_risk_advanced_risk_appetite_status");
      if (appetiteStatusRecord.get(appetiteStatus)) {
          var appetiteStatusName = appetiteStatusRecord.getValue('name');
          response.appetiteStatus = appetiteStatusName;
      }
      return response;
  },

  _isRiskResponseRequired: function(assessmentInstanceId) {
      var assessmentInstance = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      assessmentInstance.get(assessmentInstanceId);
      var ramId = assessmentInstance.getValue('risk_assessment_methodology');
      var ramRecord = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ramRecord.get(ramId);
      var isRiskResponseMandatory = false;
      var validate_risk_response_is_defined = ramRecord.getValue("validate_risk_response_is_defined");
      var appetiteStatus;

      if (validate_risk_response_is_defined == "on_breach_of_appetite") {
          appetiteStatus = assessmentInstance.getValue("overall_appetite_status");
          if (appetiteStatus == this.outsideAppetiteStautusId || appetiteStatus == this.outsideToleranceStautusId)
              isRiskResponseMandatory = true;
      } else if (validate_risk_response_is_defined == "on_breach_of_tolerance") {
          appetiteStatus = assessmentInstance.getValue("overall_appetite_status");
          if (appetiteStatus == this.outsideToleranceStautusId)
              isRiskResponseMandatory = true;
      }
      var response = {};
      response.isRiskResponseMandatory = isRiskResponseMandatory;
      response.validateRiskResponseIsDefined = validate_risk_response_is_defined;
      return response;
  },

  _validateLastStateComments: function(assessmentInstanceId) {
      var isValid = true;
      var isJustificationRequired = this.isJustificationRequired(assessmentInstanceId).isLastStateCommentMandatory;
      if (isJustificationRequired) {
          var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
          ram.get(current.risk_assessment_methodology);
          var lastState = this.getLastAssessmentState(ram);
          if (lastState == 2 && current.inherent_justification == "")
              isValid = false;
          else if (lastState == 3 && current.control_justification == "")
              isValid = false;
          else if (lastState == 4 && current.residual_justification == "")
              isValid = false;
      }
      return isValid;
  },

  _getAssessmentContributionOfLastState: function(ram, lastAssessableState) {
      var assessmentType;
      var assessmentContribution;

      var assessmentTypeReference = new GlideRecord(this.asmtTypeTables[lastAssessableState]);
      assessmentTypeReference.addQuery('risk_assessment_methodology', ram.getUniqueValue());

      assessmentTypeReference.query();
      if (assessmentTypeReference.next())
          return assessmentTypeReference.getValue('assessment_contribution');
  },

  _getAssessmentContribution: function(ram, assessmentTypeReferenceTable) {

      var assessmentTypeReference = new GlideRecord(assessmentTypeReferenceTable);
      assessmentTypeReference.addQuery('risk_assessment_methodology', ram.getUniqueValue());
      assessmentTypeReference.query();

      if (assessmentTypeReference.next())
          return assessmentTypeReference.getValue('assessment_contribution');
  },

  _updateFinalAppetites: function(asmtInstance, lastAssessableState, asmtContribution) {
      var computedAppetites = {
          "qual_appetite": "",
          "quant_appetite": "",
          "has_quant_contribution": false,
          "has_qual_contribution": false,
          "computed_qual_appetite": "",
          "computed_quant_appetite": ""
      };
      // Update Final Rating Appetite : If asmt contribution is qualitative or both, update the field
      if ((asmtContribution == 2 || asmtContribution == 3) && this._canHaveQualitativeAppetite()) {
          //Get the rating of the calculated /overriden value, get the corresponding risk appetite scale and update it
          var ratingCriteriaId;
          switch (lastAssessableState) {
              case 4:
                  //Check residual risk is applicable
                  if (asmtInstance.getValue("residual_risk_not_applicable") != true)
                      ratingCriteriaId = asmtInstance.getValue("summary_residual_risk");
                  break;
              case 3:
                  //Check control effectiveness is applicable
                  if (asmtInstance.getValue("mitigating_controls_to_assess") != true)
                      ratingCriteriaId = asmtInstance.getValue("summary_control_effectiveness");
                  break;
              case 2:
                  ratingCriteriaId = asmtInstance.getValue("summary_inherent_risk");
                  break;
          }
          //Set final_appetite_rating if assessment type exists and is applicable
          if (ratingCriteriaId) {
              var ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
              ratingCriteria.get(ratingCriteriaId);
              computedAppetites.qual_appetite = this._getQualAppetitValue(ratingCriteria.getValue("risk_appetite_scale"));
              computedAppetites.computed_qual_appetite = ratingCriteria.getValue("risk_appetite_scale");
          }
          computedAppetites.has_qual_contribution = true;
      }
      // Update Final Quantitative Appetite: If assessment contribution is quantitative or both AND last assessable state is inherent OR resiudal AND residual risk is applicable
      if ((asmtContribution == 1 || asmtContribution == 3) && (lastAssessableState == 2 || lastAssessableState == 4) && (asmtInstance.residual_risk_not_applicable != true) && this._canHaveQuantitativeAppetite()) {
          //If inherent is the final state set final ale, else set residual's ale
          if (lastAssessableState == 4) {
              computedAppetites.quant_appetite = asmtInstance.final_residual_ale.getReferenceValue();
              computedAppetites.computed_quant_appetite = asmtInstance.final_residual_ale.getSessionValue();
          } else {
              computedAppetites.quant_appetite = asmtInstance.final_inherent_ale.getReferenceValue();
              computedAppetites.computed_quant_appetite = asmtInstance.final_inherent_ale.getSessionValue();
          }
          computedAppetites.has_quant_contribution = true;
      }
      return computedAppetites;
  },

  _updateFinalAppetitesForTarget: function(asmtInstance, asmtContribution) {
      var computedAppetites = {
          "qual_appetite": "",
          "quant_appetite": "",
          "has_quant_contribution": false,
          "has_qual_contribution": false,
          "computed_qual_appetite": "",
          "computed_quant_appetite": ""
      };
      // Update Final Rating Appetite : If asmt contribution is qualitative or both, update the field
      if ((asmtContribution == 2 || asmtContribution == 3) && this._canHaveQualitativeAppetite()) {
          //Get the rating of the calculated /overriden value, get the corresponding risk appetite scale and update it
          var ratingCriteriaId = asmtInstance.getValue("summary_target_risk");
          //Set final_appetite_rating if assessment type exists and is applicable
          if (ratingCriteriaId) {
              var ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
              ratingCriteria.get(ratingCriteriaId);
              computedAppetites.qual_appetite = this._getQualAppetitValue(ratingCriteria.getValue("risk_appetite_scale"));
              computedAppetites.computed_qual_appetite = ratingCriteria.getValue("risk_appetite_scale");
          }
          computedAppetites.has_qual_contribution = true;
      }
      // Update Final Quantitative Appetite: If assessment contribution is quantitative or both
      if ((asmtContribution == 1 || asmtContribution == 3) && this._canHaveQuantitativeAppetite()) {

          computedAppetites.quant_appetite = asmtInstance.final_target_ale.getReferenceValue();
          computedAppetites.computed_quant_appetite = asmtInstance.final_target_ale.getSessionValue();
          computedAppetites.has_quant_contribution = true;
      }
      return computedAppetites;
  },

  _getOverallAppetiteStatus: function(qual_appetite_status, quant_appetite_status, isTwoPointScale) {
      var overall_status = "";
      //Outside tolerance
      if (qual_appetite_status == this.outsideToleranceStautusId || quant_appetite_status == this.outsideToleranceStautusId && isTwoPointScale)
          overall_status = this.outsideToleranceStautusId;
      //Outside Appetite
      else if (qual_appetite_status == this.outsideAppetiteStautusId || quant_appetite_status == this.outsideAppetiteStautusId)
          overall_status = this.outsideAppetiteStautusId;
      //Inside Appetite
      else if (qual_appetite_status == this.withInAppetiteStatusId || quant_appetite_status == this.withInAppetiteStatusId)
          overall_status = this.withInAppetiteStatusId;

      return overall_status;
  },

  _computeAppetiteStatusForRiskAssessment: function(asmtInstance, shouldUpdate) {
      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ram.get(asmtInstance.risk_assessment_methodology);
      var lastAssessableState = this._getLastAssessmentState(ram);
      if (this._isRiskAppetiteEnabled() && ram.getValue("assessed_on") == 0) {
          var riskRecord = new GlideRecord("sn_risk_risk");
          riskRecord.get(asmtInstance.getValue("risk"));
          var givenAppetiteValues = this._getGivenAppetiteValues(riskRecord);
          //Get the assessment contribution of the last assessment state
          var asmtContribution = this._getAssessmentContributionOfLastState(ram, lastAssessableState);
          //Update the "Ratings in term of appetite" and Final ALE of the asmt field
          var calculatedAppetites = this._updateFinalAppetites(asmtInstance, lastAssessableState, asmtContribution);
          //Compute the Appetite Status and set it in assessment details
          var appetiteStatus = this._computeAppetiteStatus(givenAppetiteValues, calculatedAppetites);
          return this._updateAppetiteColumnsInRecord(asmtInstance, appetiteStatus, shouldUpdate);
      }
  },

  _computeAppetiteStatusForTargetRiskAssessment: function(asmtInstance, shouldUpdate) {
      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ram.get(asmtInstance.risk_assessment_methodology);
      var isTargetEnabled = new sn_risk_advanced.RiskAssessmentUtils().hasTargetAssessment(asmtInstance.risk_assessment_methodology, asmtInstance.getUniqueValue());
      if (this._isRiskAppetiteEnabled() && ram.getValue("assessed_on") == 0 && isTargetEnabled) {
          var riskRecord = new GlideRecord("sn_risk_risk");
          riskRecord.get(asmtInstance.getValue("risk"));
          var givenAppetiteValues = this._getGivenAppetiteValues(riskRecord);
          //Get the assessment contribution of target risk
          var asmtContribution = this._getAssessmentContribution(ram, this.asmtTypeTables[10]);
          //Update the "Ratings in term of appetite" and Final ALE of the asmt field
          var calculatedAppetites = this._updateFinalAppetitesForTarget(asmtInstance, asmtContribution);
          //Compute the Appetite Status and set it in assessment details
          var appetiteStatus = this._computeAppetiteStatus(givenAppetiteValues, calculatedAppetites);
          return this._updateAppetiteColumnsInTarget(asmtInstance, appetiteStatus, shouldUpdate);
      }
  },


  _getAppetiteStatusColors: function() {
      var appetiteStatusToColorMapping = {};
      var appetiteStatus = new GlideRecord("sn_risk_advanced_risk_appetite_status");
      appetiteStatus.query();
      while (appetiteStatus.next()) {
          var color = appetiteStatus.getValue('risk_appetite_status_color');
          if (color) {
              var backgroundVariable = this.appetiteColorMapping[color].backgroundColorVariable;
              var defaultBackgroundColor = this.appetiteColorMapping[color].defaultBackgroundColor;
              if (backgroundVariable && defaultBackgroundColor)
                  appetiteStatusToColorMapping[appetiteStatus.getUniqueValue()] = "rgb(var(" + backgroundVariable + ',' + defaultBackgroundColor + "))";
          }
      }
      return appetiteStatusToColorMapping;
  },

  _getAppetiteStatusColorsAndIconsWS: function() {
      var appetiteStatusToColorMapping = {};
      var appetiteStatus = new GlideRecord("sn_risk_advanced_risk_appetite_status");
      var statusRecords = [this.withInAppetiteStatusId, this.outsideAppetiteStautusId, this.outsideToleranceStautusId];
      for (var i = 0; i < statusRecords.length; i += 1) {
          var status = statusRecords[i];
          appetiteStatus.initialize();
          appetiteStatus.get(status);
          var statusColorAndIcon = {};
          var colorName = appetiteStatus.getValue("risk_appetite_status_color") || "";
          statusColorAndIcon = {
              "colorName": colorName,
              "iconName": appetiteStatus.getValue("icon") || "",
              "name": appetiteStatus.getValue("name") || "",
              "iconColor": gs.nil(this.appetiteColorMapping[colorName]) ? "" : this.appetiteColorMapping[colorName],
          };
          appetiteStatusToColorMapping[status] = statusColorAndIcon;
      }
      return appetiteStatusToColorMapping;
  },

  _getAppetiteFieldsToHide: function(asmtInstance) {
      var fieldsToHide = [];
      var qual_fields = ["qual_appetite_status", "risk.qual_appetite", "risk.qual_tolerance"];
      var quant_fields = ["quant_appetite_status", "risk.quant_appetite", "risk.quant_tolerance"];
      var common_fields = ["overall_appetite_status", "risk.risk_appetite_statement"];

      if (!this._isRiskAppetiteEnabled() || asmtInstance.risk_assessment_methodology.assessed_on != 0) {
          fieldsToHide = common_fields;
          return fieldsToHide;
      }

      //If its one point scale, hide tolerance
      if (gs.getProperty('sn_risk_advanced.risk_appetite_scale', 'risk_appetite_none') == 'risk_appetite_one_point') {
          fieldsToHide.push("risk.qual_tolerance");
          fieldsToHide.push("risk.quant_tolerance");
      }

      //Based on appetite property
      if (gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative') == 'risk_appetite_qualitative') {
          fieldsToHide = fieldsToHide.concat(quant_fields);
      } else if (gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative') == 'risk_appetite_quantitative') {
          fieldsToHide = fieldsToHide.concat(qual_fields);
      }

      return fieldsToHide;
  },

  _getQualitativeAppetiteStatusMessage: function(appetiteStatusId, appetiteStatusName, qualitativeRatingId, asmtName, sourceRecord) {
      var msg = "";

      //Get Qualitative appetite status tooltip, if defined in source record and final risk rating exists
      if (qualitativeRatingId && (sourceRecord.qual_appetite || sourceRecord.qual_tolerance)) {
          var rating = new GlideRecord("sn_risk_advanced_rating_criteria");
          rating.get(qualitativeRatingId);
          switch (appetiteStatusId) {
              case this.withInAppetiteStatusId:
                  var appetiteScaleDisplayValue = '';
                  var appetiteType = "";
                  if (sourceRecord.qual_appetite) {
                      appetiteScaleDisplayValue = sourceRecord.qual_appetite.display_value;
                      appetiteType = gs.getMessage("appetite");
                  } else if (sourceRecord.qual_tolerance) {
                      appetiteScaleDisplayValue = sourceRecord.qual_tolerance.display_value;
                      appetiteType = gs.getMessage("tolerance");
                  }

                  msg = gs.getMessage("The {0} risk rating '{1}' has an appetite of '{2}' that is within the defined risk {3} '{4}', and is '{5}'", [asmtName, rating.rating, rating.risk_appetite_scale.display_value, appetiteType, appetiteScaleDisplayValue, appetiteStatusName]);
                  break;
              case this.outsideAppetiteStautusId:
                  msg = gs.getMessage("The {0} risk rating '{1}' has an appetite of '{2}' that exceeds the defined risk appetite '{3}', and is '{4}'", [asmtName, rating.rating, rating.risk_appetite_scale.display_value, sourceRecord.qual_appetite.display_value, appetiteStatusName]);
                  break;
              case this.outsideToleranceStautusId:
                  msg = gs.getMessage("The {0} risk rating '{1}' has an appetite of '{2}' that exceeds the defined risk tolerance '{3}', and is '{4}'", [asmtName, rating.rating, rating.risk_appetite_scale.display_value, sourceRecord.qual_tolerance.display_value, appetiteStatusName]);
                  break;
          }
      }
      return msg;
  },

  _getQuantitativeAppetiteStatusMessage: function(appetiteStatusId, appetiteStatusName, quantitativeALE, asmtName, sourceRecord) {
      var msg = "";
      switch (appetiteStatusId) {
          case this.withInAppetiteStatusId:
              msg = gs.getMessage("The {0} ale {1} is within the defined risk appetite {2}, and is '{3}''", [asmtName, quantitativeALE, sourceRecord.quant_appetite.getSessionDisplayValue(), appetiteStatusName]);
              break;
          case this.outsideAppetiteStautusId:
              msg = gs.getMessage("The {0} ale {1} exceeds the defined risk appetite {2}, and is '{3}'", [asmtName, quantitativeALE, sourceRecord.quant_appetite.getSessionDisplayValue(), appetiteStatusName]);
              break;
          case this.outsideToleranceStautusId:
              msg = gs.getMessage("The {0} ale {1} exceeds the defined risk tolerance {2}, and is '{3}''", [asmtName, quantitativeALE, sourceRecord.quant_tolerance.getSessionDisplayValue(), appetiteStatusName]);
              break;
      }
      return msg;
  },

  _getOverallAppetiteStatusMessage: function(qual_appetite, quant_appetite, overAllStatusId, overAllStatusName) {
      var msg = "";
      if (overAllStatusId) {
          if (qual_appetite && quant_appetite)
              msg = gs.getMessage("The overall status considers the worst-case scenario between the qualitative and the quantitative status. Hence, it is computed as '{0}'.", [overAllStatusName]);
          else if (qual_appetite)
              msg = gs.getMessage("As qualitative appetite status is '{0}', overall status is also '{1}'", [qual_appetite, overAllStatusName]);
          else
              msg = gs.getMessage("As quantitative appetite status is '{0}', overall status is also '{1}'", [quant_appetite, overAllStatusName]);
      }
      return msg;
  },

  _getProjectedAppetiteStatusMessage: function(qual_appetite, quant_appetite, projectedStatusId, projectedStatusName) {
      var msg = "";
      if (projectedStatusId) {
          if (qual_appetite && quant_appetite)
              msg = gs.getMessage("The future appetite status considers the worst-case scenario between the qualitative and the quantitative status. Hence, it is computed as '{0}'.", [projectedStatusName]);
          else if (qual_appetite)
              msg = gs.getMessage("As qualitative appetite status is '{0}', future appetite status is also '{1}'", [qual_appetite, projectedStatusName]);
          else
              msg = gs.getMessage("As quantitative appetite status is '{0}', future appetite status is also '{1}'", [quant_appetite, projectedStatusName]);
      }
      return msg;
  },

  _getAppetiteStatusMessagesForAssessment: function(asmtInstance, lastAssessableState) {
      var appetiteStatusMessages = {};
      var appetiteInfo = {};
      var risk = new GlideRecord("sn_risk_risk");
      risk.get(asmtInstance.getValue('risk'));

      if (!lastAssessableState) {
          var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
          ram.get(asmtInstance.risk_assessment_methodology);
          lastAssessableState = this._getLastAssessmentState(ram);
      }

      appetiteInfo.asmtName = this.asmtTableColumns[lastAssessableState]["name"];
      appetiteInfo.qualRatingId = asmtInstance.getValue(this.asmtTableColumns[lastAssessableState]["final_risk_rating"]);
      //Incase of control effectiveness, no ale
      if (lastAssessableState != 3) {
          var field = this.asmtTableColumns[lastAssessableState]["final_ale"];
          appetiteInfo.quantALE = asmtInstance[field].getSessionDisplayValue();
      }

      this._setAppetiteStatusInfo(appetiteInfo, asmtInstance);
      this._setTargetAppetiteStatusInfo(appetiteInfo, asmtInstance);
      appetiteStatusMessages = this._getAppetiteStatusMessages(appetiteInfo, risk);
      return appetiteStatusMessages;
  },

  _getAppetiteStatusMessagesForRiskStatement: function(riskStatement) {
      return this._getAppetiteStatusMessagesForEntityOrRiskStatement(riskStatement);
  },

  _getAppetiteStatusMessagesForEntity: function(entity) {
      return this._getAppetiteStatusMessagesForEntityOrRiskStatement(entity);
  },

  _getAppetiteStatusMessagesForEntityOrRiskStatement: function(record) {
      var appetiteStatusMessages = {};
      var appetiteInfo = {};

      var rollUpRecordId = record.getValue("sn_risk_advanced_rollup_result");
      if (!gs.nil(rollUpRecordId)) {
          var rollUpRecord = new GlideRecord("sn_risk_advanced_risk_assessment_result");
          if (rollUpRecord.get(rollUpRecordId)) {
              var ramId = rollUpRecord.getValue("risk_assessment_methodology");
              var columns = this._getAggregatedRecordInfo(ramId);

              appetiteInfo.qualRatingId = rollUpRecord.getValue(columns.ratingColumn);
              appetiteInfo.asmtName = columns.asmtName;

              //Incase of control effectiveness, no ale
              if (columns.lastAssessableState != 3) {
                  appetiteInfo.quantALE = rollUpRecord[columns.aleColumn].getSessionDisplayValue();
              }

              this._setAppetiteStatusInfo(appetiteInfo, record);
              appetiteStatusMessages = this._getAppetiteStatusMessages(appetiteInfo, record);
          }
      }

      return appetiteStatusMessages;
  },

  _setAppetiteStatusInfo: function(appetiteInfo, record) {
      appetiteInfo.qualStatusId = record.getValue('qual_appetite_status');
      appetiteInfo.quantStatusId = record.getValue('quant_appetite_status');
      appetiteInfo.overAllStatusId = record.getValue('overall_appetite_status');
      appetiteInfo.qualStatusName = appetiteInfo.qualStatusId ? record.qual_appetite_status.name : "";
      appetiteInfo.quantStatusName = appetiteInfo.quantStatusId ? record.quant_appetite_status.name : "";
      appetiteInfo.overAllStatusName = appetiteInfo.overAllStatusId ? record.overall_appetite_status.name : "";
  },

  _setTargetAppetiteStatusInfo: function(appetiteInfo, record) {
      appetiteInfo.projectedAsmtName = this.asmtTableColumns[10]["name"];
      appetiteInfo.projectedQualRatingId = record.getValue(this.asmtTableColumns[10]["final_risk_rating"]);
      appetiteInfo.projectedQuantALE = record[this.asmtTableColumns[10]["final_ale"]].getSessionDisplayValue();
      appetiteInfo.projectedQualStatusId = record.getValue('projected_qual_appetite_status');
      appetiteInfo.projectedQuantStatusId = record.getValue('projected_quant_appetite_status');
      appetiteInfo.projectedStatusId = record.getValue('projected_appetite_status');
      appetiteInfo.projectedQualStatusName = appetiteInfo.projectedQualStatusId ? record.projected_qual_appetite_status.name : "";
      appetiteInfo.projectedQuantStatusName = appetiteInfo.projectedQuantStatusId ? record.projected_quant_appetite_status.name : "";
      appetiteInfo.projectedStatusName = appetiteInfo.projectedStatusId ? record.projected_appetite_status.name : "";
  },

  _getAppetiteStatusMessages: function(appetiteInfo, record) {
      var appetiteStatusMessages = {};
      var isAssessmentRecord = (record.getTableName() == "sn_risk_risk");
      if (this._hasQualitativeAppetiteRole()) {
          appetiteStatusMessages.qual_tooltip = this._getQualitativeAppetiteStatusMessage(appetiteInfo.qualStatusId, appetiteInfo.qualStatusName, appetiteInfo.qualRatingId, appetiteInfo.asmtName, record);
          if (isAssessmentRecord)
              appetiteStatusMessages.projected_qual_tooltip = this._getQualitativeAppetiteStatusMessage(appetiteInfo.projectedQualStatusId, appetiteInfo.projectedQualStatusName, appetiteInfo.projectedQualRatingId, appetiteInfo.projectedAsmtName, record);
      }
      if (this._hasQuantitativeAppetiteRole()) {
          appetiteStatusMessages.quant_tooltip = this._getQuantitativeAppetiteStatusMessage(appetiteInfo.quantStatusId, appetiteInfo.quantStatusName, appetiteInfo.quantALE, appetiteInfo.asmtName, record);
          if (isAssessmentRecord)
              appetiteStatusMessages.projected_quant_tooltip = this._getQuantitativeAppetiteStatusMessage(appetiteInfo.projectedQuantStatusId, appetiteInfo.projectedQuantStatusName, appetiteInfo.projectedQuantALE, appetiteInfo.projectedAsmtName, record);
      }
      appetiteStatusMessages.overall_tooltip = this._getOverallAppetiteStatusMessage(appetiteInfo.qualStatusName, appetiteInfo.quantStatusName, appetiteInfo.overAllStatusId, appetiteInfo.overAllStatusName);
      if (isAssessmentRecord)
          appetiteStatusMessages.projected_tooltip = this._getProjectedAppetiteStatusMessage(appetiteInfo.projectedQualStatusName, appetiteInfo.projectedQuantStatusName, appetiteInfo.projectedStatusId, appetiteInfo.projectedStatusName);
      return appetiteStatusMessages;
  },

  _hasQualitativeAppetiteRole: function() {
      return gs.hasRole('sn_risk_advanced.qualitative_risk_appetite_reader');
  },

  _hasQuantitativeAppetiteRole: function() {
      return gs.hasRole('sn_risk_advanced.quantitative_risk_appetite_reader');
  },

  _getRiskAppetiteSectionInfo: function(asmtInstanceId) {
      var appetiteInfo = {};
      var asmtInstance = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      asmtInstance.get(asmtInstanceId);
      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ram.get(asmtInstance.risk_assessment_methodology);
      var lastAssessableState = this._getLastAssessmentState(ram);
      appetiteInfo.canShowAppetiteSection = this._isRiskAppetiteEnabled() && ram.assessed_on == 0;
      appetiteInfo.lastAssessableState = lastAssessableState;
      appetiteInfo.asmtContributionOfLastState = this._getAssessmentContributionOfLastState(ram, lastAssessableState);
      appetiteInfo.canHaveQualitativeAppetite = this._canHaveQualitativeAppetite();
      appetiteInfo.canHaveQuantitativeAppetite = this._canHaveQuantitativeAppetite();
      appetiteInfo.hasQualitativeAppetiteRole = this._hasQualitativeAppetiteRole();
      appetiteInfo.hasQuantitativeAppetiteRole = this._hasQuantitativeAppetiteRole();
      appetiteInfo.qualAppetiteStatus = asmtInstance.getValue("qual_appetite_status");
      appetiteInfo.quantAppetiteStatus = asmtInstance.getValue("quant_appetite_status");
      appetiteInfo.overallAppetiteStatus = asmtInstance.getValue("overall_appetite_status");
      appetiteInfo.appetiteStatusToColorMapping = this._getAppetiteStatusColorsAndIconsWS();
      appetiteInfo.projectedQualAppetiteStatus = asmtInstance.getValue("projected_qual_appetite_status");
      appetiteInfo.projectedQuantAppetiteStatus = asmtInstance.getValue("projected_quant_appetite_status");
      appetiteInfo.projectedAppetiteStatus = asmtInstance.getValue("projected_appetite_status");

      var toolTips = this._getAppetiteStatusMessagesForAssessment(asmtInstance, lastAssessableState);
      appetiteInfo.tooltips = toolTips;
      return appetiteInfo;
  },


  _computeAppetiteStatusOnRollUpChange: function(rollUpRecord) {
      var entityId = rollUpRecord.getValue('entity');
      var riskStatementId = rollUpRecord.getValue('statement');

      if (!gs.nil(entityId) && !gs.nil(riskStatementId))
          return;

      if (!gs.nil(entityId)) {
          var entity = new GlideRecord("sn_grc_profile");
          entity.get(entityId);

          if (entity.getValue('sn_risk_advanced_rollup_result') == rollUpRecord.getUniqueValue()) {
              this._computeAppetiteStatusForEntity(entity, true);
          }
      } else if (!gs.nil(riskStatementId)) {
          var riskStatement = new GlideRecord("sn_risk_definition");
          riskStatement.get(riskStatementId);

          if (riskStatement.getValue('sn_risk_advanced_rollup_result') == rollUpRecord.getUniqueValue()) {
              this._computeAppetiteStatusForRiskStatement(riskStatement, true);
          }
      }
  },

  _computeAppetiteStatusOnRollUpDelete: function(rollUpRecord) {
      var entityId = rollUpRecord.getValue('entity');
      var riskStatementId = rollUpRecord.getValue('statement');

      if (!gs.nil(entityId) && !gs.nil(riskStatementId))
          return;

      if (!gs.nil(entityId)) {
          var entity = new GlideRecord("sn_grc_profile");
          entity.get(entityId);
          entity.addQuery("sn_risk_advanced_rollup_result", rollUpRecord.getUniqueValue());
          this._setAppetiteStatusToEmpty(entity);
          entity.update();
      } else if (!gs.nil(riskStatementId)) {
          var riskStatement = new GlideRecord("sn_risk_definition");
          riskStatement.get(riskStatementId);
          riskStatement.addQuery("sn_risk_advanced_rollup_result", rollUpRecord.getUniqueValue());
          this._setAppetiteStatusToEmpty(riskStatement);
          riskStatement.update();
      }
  },

  _setAppetiteStatusToEmpty: function(record) {
      record.setValue("qual_appetite_status", "");
      record.setValue("quant_appetite_status", "");
  },

  _computeAppetiteStatusForRiskStatement: function(riskStatement, shouldUpdate) {
      this._computeAppetiteStatusForEntityORiskStatement(riskStatement, shouldUpdate);
  },

  _computeAppetiteStatusForEntity: function(entity, shouldUpdate) {
      this._computeAppetiteStatusForEntityORiskStatement(entity, shouldUpdate);
  },

  _computeAppetiteStatusForEntityORiskStatement: function(record, shouldUpdate) {
      if (this._isRiskAppetiteEnabled()) {
          var rollUpRecordId = record.getValue("sn_risk_advanced_rollup_result");
          if (gs.nil(rollUpRecordId)) {
              record.setValue("qual_appetite_status", "");
              record.setValue("quant_appetite_status", "");
              if (shouldUpdate)
                  record.update();
          } else {
              var rollUpRecord = new GlideRecord("sn_risk_advanced_risk_assessment_result");
              if (rollUpRecord.get(rollUpRecordId)) {
                  var appetiteStatus = this._getAppetiteStatus(rollUpRecord, record);
                  this._updateAppetiteColumnsInRecord(record, appetiteStatus, shouldUpdate);
              }
          }
      }
  },

  _getAppetiteStatus: function(rollUpRecord, record) {
      var givenAppetiteValues = this._getGivenAppetiteValues(record);
      var computedAppetiteValues = this._getComputedAppetites(rollUpRecord);
      return this._computeAppetiteStatus(givenAppetiteValues, computedAppetiteValues);
  },

  _getGivenAppetiteValues: function(record) {
      var givenAppetiteValues = {
          "qual_appetite": "",
          "qual_tolerance": "",
          "quant_appetite": "",
          "quant_tolerance": ""
      };

      var isTwoPointScale = this._isTwoPointScale();

      if (this._canHaveQualitativeAppetite()) {
          if (!gs.nil(record.getValue('qual_appetite')))
              givenAppetiteValues.qual_appetite = parseInt(record.qual_appetite.value);
          if (isTwoPointScale && !gs.nil(record.getValue('qual_tolerance')))
              givenAppetiteValues.qual_tolerance = parseInt(record.qual_tolerance.value);
      }

      if (this._canHaveQuantitativeAppetite()) {
          givenAppetiteValues.quant_appetite = parseFloat(record.quant_appetite.getReferenceValue());
          if (isTwoPointScale)
              givenAppetiteValues.quant_tolerance = parseFloat(record.quant_tolerance.getReferenceValue());
      }

      return givenAppetiteValues;
  },

  _getComputedAppetites: function(rollupRecord) {
      var computedAppetites = {
          "qual_appetite": "",
          "quant_appetite": "",
          "has_quant_contribution": false,
          "has_qual_contribution": false,
          "computed_qual_appetite": "",
          "computed_quant_appetite": ""
      };

      var ramId = rollupRecord.getValue("risk_assessment_methodology");
      var columns = this._getAggregatedRecordInfo(ramId);
      var ratingColumn = columns.ratingColumn;
      var aleColumn = columns.aleColumn;
      var assessmentContribution = columns.assessmentContribution;
      if (ratingColumn && (assessmentContribution == "2" || assessmentContribution == "3")) {
          if (!gs.nil(rollupRecord.getValue(ratingColumn))) {
              var riskAppetite = rollupRecord[ratingColumn].risk_appetite_scale;
              computedAppetites.qual_appetite = this._getQualAppetitValue(riskAppetite);
              computedAppetites.computed_qual_appetite = riskAppetite;
          }
          computedAppetites.has_qual_contribution = true;
      }

      if (aleColumn && columns.lastAssessableState != 3 && (assessmentContribution == "1" || assessmentContribution == "3")) {
          computedAppetites.quant_appetite = parseFloat(rollupRecord[aleColumn].getReferenceValue());
          computedAppetites.has_quant_contribution = true;
          computedAppetites.computed_quant_appetite = rollupRecord[aleColumn].getSessionValue();
      }
      return computedAppetites;
  },

  _getAggregatedRecordInfo: function(ramId) {
      var columns = {
          ratingColumn: "",
          aleColumn: "",
          assessmentContribution: "",
          asmtName: "",
          lastAssessableState: ""
      };
      var stateToRatingColumnsMapping = {
          "2": "inherent_rating",
          "3": "control_rating",
          "4": "residual_rating"
      };

      var stateToALEColumnsMapping = {
          "2": "inherent_ale",
          "4": "residual_ale"
      };

      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      if (ram.get(ramId)) {
          var lastAssessableState = this._getLastAssessmentState(ram);
          columns.assessmentContribution = this._getAssessmentContributionOfLastState(ram, lastAssessableState);
          columns.ratingColumn = stateToRatingColumnsMapping[lastAssessableState];
          columns.aleColumn = stateToALEColumnsMapping[lastAssessableState];
          columns.asmtName = this.asmtTableColumns[lastAssessableState]["name"];
          columns.lastAssessableState = lastAssessableState;
      }
      return columns;
  },

  _computeAppetiteStatus: function(givenAppetiteValues, computedAppetiteValues) {
      var isTwoPointScale = this._isTwoPointScale();
      var appetiteStatus = {
          "qualAppetiteStatus": "",
          "quantAppetiteStatus": "",
          "overAllAppetiteStatus": "",
          "computedQualitativeAppetite": "",
          "computedQuantitativeAppetite": ""
      };

      if (computedAppetiteValues.has_qual_contribution && this._canHaveQualitativeAppetite()) {
          var computedQualAppetite = computedAppetiteValues.qual_appetite;
          var givenQualAppetite = givenAppetiteValues.qual_appetite;
          var givenQualTolerance = givenAppetiteValues.qual_tolerance;
          appetiteStatus.qualAppetiteStatus = this._getStatusBasedOnComputedValue(isTwoPointScale, givenQualAppetite, givenQualTolerance, computedQualAppetite);
          appetiteStatus.computedQualitativeAppetite = computedAppetiteValues.computed_qual_appetite;
      }

      if (computedAppetiteValues.has_quant_contribution && this._canHaveQuantitativeAppetite()) {
          var computedQuantAppetite = computedAppetiteValues.quant_appetite;
          var givenQuantAppetite = givenAppetiteValues.quant_appetite;
          var givenQuantTolerance = givenAppetiteValues.quant_tolerance;
          appetiteStatus.quantAppetiteStatus = this._getStatusBasedOnComputedValue(isTwoPointScale, givenQuantAppetite, givenQuantTolerance, computedQuantAppetite);
          appetiteStatus.computedQuantitativeAppetite = computedAppetiteValues.computed_quant_appetite;
      }

      return appetiteStatus;
  },

  _getStatusBasedOnComputedValue: function(isTwoPointScale, givenAppetite, givenTolerance, computedAppetite) {
      var status = "";
      if (computedAppetite) {
          if (isTwoPointScale && givenTolerance) {
              if (computedAppetite > givenTolerance)
                  status = this.outsideToleranceStautusId;
              else if (gs.nil(givenAppetite))
                  status = this.withInAppetiteStatusId;

              if (status)
                  return status;
          }

          if (!gs.nil(givenAppetite)) {
              if (computedAppetite > givenAppetite)
                  status = this.outsideAppetiteStautusId;
              else
                  status = this.withInAppetiteStatusId;
          }
      }
      return status;
  },

  _getQualAppetitValue: function(appetiteId) {
      var appetite = new GlideRecord("sn_risk_advanced_risk_appetite_scale");
      return appetite.get(appetiteId) ? parseInt(appetite.getValue('value')) : null;
  },

  _getRollupRecordForRiskStatement: function(riskStatementId, ramId) {
      var aggregation = new GlideRecord("sn_risk_advanced_risk_assessment_result");
      aggregation.addQuery("statement", riskStatementId);
      aggregation.addNullQuery("entity");
      aggregation.addQuery("risk_assessment_methodology", ramId);
      aggregation.query();

      return aggregation.next() ? aggregation : null;
  },

  _copyAppetiteValues: function(copyTo, copyFrom, shouldCopyStmt, table) {
      var qualAppetite = copyFrom.getValue('qual_appetite');
      var qualTolerance = copyFrom.getValue('qual_tolerance');
      qualAppetite = qualAppetite ? qualAppetite : "NULL";
      qualTolerance = qualTolerance ? qualTolerance : "NULL";
      copyTo.setValue("qual_appetite", qualAppetite);
      copyTo.setValue("qual_tolerance", qualTolerance);

      if (shouldCopyStmt) {
          var riskAppetiteStatement = copyFrom.risk_appetite_statement;
          riskAppetiteStatement = riskAppetiteStatement ? riskAppetiteStatement : "NULL";
          copyTo.risk_appetite_statement = riskAppetiteStatement;
      }

      if (table && table == "sn_risk_definition")
          copyTo.ram_status_calculation = copyFrom.ram_status_calculation;
  },

  _copyAppetiteToDownstreamRisks: function(riskDefId) {
      var riskDef = new GlideRecord('sn_risk_definition');
      riskDef.get(riskDefId);
      this._setRiskAppetite(riskDef, true, riskDef);
      riskDef.setValue("disable_copy_appetite", false);
      riskDef.update();
  },

  _setRiskAppetite: function(rs, isBaseRisk, riskDef) {
      if (!isBaseRisk) {
          this._copyAppetiteValues(rs, riskDef, true, 'sn_risk_definition');
          rs.update();
      }
      var risks = new GlideRecord('sn_risk_risk');
      risks.addQuery('statement', rs.sys_id);
      risks.addQuery('override_appetite', false);
      this._copyAppetiteValues(risks, riskDef, true);
      risks.updateMultiple();

      var child = new GlideRecord('sn_risk_definition');
      child.addQuery('parent', rs.sys_id);
      child.addQuery('override_appetite', false);
      child.query();
      while (child.next()) {
          this._setRiskAppetite(child, false, riskDef);
      }
  },

  _hasDownstreamRisks: function(riskDefId) {
      var risk = new GlideRecord("sn_risk_risk");
      risk.addQuery('override_appetite', false);
      risk.addQuery('statement', riskDefId);
      risk.setLimit(1);
      risk.query();
      if (risk.hasNext())
          return true;
      else {
          var rs = new GlideRecord("sn_risk_definition");
          rs.addQuery('override_appetite', false);
          rs.addQuery('parent', riskDefId);
          rs.setLimit(1);
          rs.query();
          if (rs.hasNext())
              return true;
      }
      return false;
  },

  _copyAppetiteToDownstreamEntities: function(entityId) {
      var entity = new GlideRecord('sn_grc_profile');
      entity.get(entityId);
      this._setEntityAppetite(entity, true, entity);
      entity.setValue("disable_copy_appetite", false);
      entity.update();
  },

  _setEntityAppetite: function(childEntity, isBaseEntity, entity) {
      if (!isBaseEntity) {
          this._copyAppetiteValues(childEntity, entity, false);
          childEntity.update();
      }
      var relationships = new GlideRecord('sn_grc_m2m_profile_profile');
      relationships.addQuery("upstream_profile", childEntity.sys_id);
      relationships.addQuery("downstream_profile.override_appetite", false);
      relationships.query();
      while (relationships.next()) {
          var e = new GlideRecord("sn_grc_profile");
          e.get(relationships.getValue("downstream_profile"));
          this._setEntityAppetite(e, false, entity);
      }
  },

  _hasDownstreamEntities: function(entityId) {
      var relationships = new GlideRecord('sn_grc_m2m_profile_profile');
      relationships.addQuery("upstream_profile", entityId);
      relationships.addQuery("downstream_profile.override_appetite", false);
      relationships.setLimit(1);
      relationships.query();
      return relationships.hasNext();
  },

  _canHaveQualitativeAppetite: function() {
      return gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative') != 'risk_appetite_quantitative';
  },

  _canHaveQuantitativeAppetite: function() {
      return gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative') != 'risk_appetite_qualitative';
  },

  _isTwoPointScale: function() {
      return gs.getProperty('sn_risk_advanced.risk_appetite_scale', 'risk_appetite_none') == 'risk_appetite_two_point';
  },

  _getRiskAppetiteValuesForRisk: function(riskId) {
      var risk = new GlideRecord("sn_risk_risk");
      var riskAppetiteValues = {};
      riskAppetiteValues.qualitativeRiskAppetite = "-";
      riskAppetiteValues.qualitativeRiskTolerance = "-";
      riskAppetiteValues.quantitativeRiskAppetite = "0.0";
      riskAppetiteValues.quantitativeRiskTolerance = "0.0";
      riskAppetiteValues.riskAppetiteStatement = "";
      riskAppetiteValues.qualAppetiteStatus = "";
      riskAppetiteValues.quantAppetiteStatus = "";
      riskAppetiteValues.overallAppetiteStatus = "";
      if (risk.get(riskId)) {
          riskAppetiteValues.qualitativeRiskAppetite = risk.qual_appetite ? risk.qual_appetite.getDisplayValue() : "-";
          riskAppetiteValues.qualitativeRiskTolerance = risk.qual_tolerance ? risk.qual_tolerance.getDisplayValue() : "-";
          riskAppetiteValues.quantitativeRiskAppetite = risk.quant_appetite ? risk.quant_appetite.getSessionDisplayValue() + '' : "0.0";
          riskAppetiteValues.quantitativeRiskTolerance = risk.quant_tolerance ? risk.quant_tolerance.getSessionDisplayValue() + '' : "0.0";
          riskAppetiteValues.riskAppetiteStatement = risk.risk_appetite_statement ? risk.risk_appetite_statement + '' : "";
          if (risk.assessment_instance) {
              riskAppetiteValues.qualAppetiteStatus = risk.assessment_instance.qual_appetite_status ? risk.assessment_instance.qual_appetite_status + '' : "";
              riskAppetiteValues.qualAppetiteStatusName = risk.assessment_instance.qual_appetite_status ? risk.assessment_instance.qual_appetite_status.name + '' : "";
              riskAppetiteValues.quantAppetiteStatus = risk.assessment_instance.quant_appetite_status ? risk.assessment_instance.quant_appetite_status + '' : "";
              riskAppetiteValues.quantAppetiteStatusName = risk.assessment_instance.quant_appetite_status ? risk.assessment_instance.quant_appetite_status.name + '' : "";
              riskAppetiteValues.overallAppetiteStatus = risk.assessment_instance.overall_appetite_status ? risk.assessment_instance.overall_appetite_status + '' : "";
              riskAppetiteValues.overallAppetiteStatusName = risk.assessment_instance.overall_appetite_status ? risk.assessment_instance.overall_appetite_status.name + '' : "";
          }
      }
      return riskAppetiteValues;
  },

  _getRiskAppetiteDetails: function(riskId) {
      var appetiteAnalysis = gs.getProperty('sn_risk_advanced.risk_appetite_analysis');
      var riskAppetiteInfo = {};
      var riskAppetiteValues = this.getRiskAppetiteValuesForRisk(riskId);
      riskAppetiteInfo.canHaveQualitativeAppetite = this._canHaveQualitativeAppetite();
      riskAppetiteInfo.canHaveQuantitativeAppetite = this._canHaveQuantitativeAppetite();
      riskAppetiteInfo.appetiteScale = gs.getProperty('sn_risk_advanced.risk_appetite_scale');
      riskAppetiteInfo.canShowAppetiteSection = this._isRiskAppetiteEnabled();
      var qualitativeLabelValues = [];
      var quantitativeLabelValues = [];
      // based on risk appetite properties adding qualitative results to result object
      qualitativeLabelValues.push({
          "label": gs.getMessage("Qualitative risk appetite"),
          "value": {
              "type": "string",
              "value": riskAppetiteValues.qualitativeRiskAppetite
          }
      });
      quantitativeLabelValues.push({
          "label": gs.getMessage("Quantitative risk appetite"),
          "value": {
              "type": "string",
              "value": riskAppetiteValues.quantitativeRiskAppetite
          }
      });
      // based on risk appetite properties adding quantitative results to result object
      if (this._isTwoPointScale()) {
          qualitativeLabelValues.push({
              "label": gs.getMessage("Qualitative risk tolerance"),
              "value": {
                  "type": "string",
                  "value": riskAppetiteValues.qualitativeRiskTolerance
              }
          });
          quantitativeLabelValues.push({
              "label": gs.getMessage("Quantitative risk tolerance"),
              "value": {
                  "type": "string",
                  "value": riskAppetiteValues.quantitativeRiskTolerance
              }
          });
      }
      var appetiteStatusToColorMapping = this._getAppetiteStatusColorsAndIconsWS();
      riskAppetiteInfo.qualitativeLabelValues = qualitativeLabelValues;
      riskAppetiteInfo.quantitativeLabelValues = quantitativeLabelValues;
      var qualAppetiteStatus = {};
      qualAppetiteStatus.status = riskAppetiteValues.qualAppetiteStatusName;
      if (appetiteStatusToColorMapping[riskAppetiteValues.qualAppetiteStatus]) {
          qualAppetiteStatus.color = appetiteStatusToColorMapping[riskAppetiteValues.qualAppetiteStatus]["colorName"] || "";
          qualAppetiteStatus.icon = appetiteStatusToColorMapping[riskAppetiteValues.qualAppetiteStatus]["iconName"] || "";
      } else {
          qualAppetiteStatus.color = "";
          qualAppetiteStatus.icon = "";
      }
      var quantAppetiteStatus = {};
      quantAppetiteStatus.status = riskAppetiteValues.quantAppetiteStatusName;
      if (appetiteStatusToColorMapping[riskAppetiteValues.quantAppetiteStatus]) {
          quantAppetiteStatus.color = appetiteStatusToColorMapping[riskAppetiteValues.quantAppetiteStatus]["colorName"] || "";
          quantAppetiteStatus.icon = appetiteStatusToColorMapping[riskAppetiteValues.quantAppetiteStatus]["iconName"] || "";
      } else {
          quantAppetiteStatus.color = "";
          quantAppetiteStatus.icon = "";
      }
      var overallAppetiteStatus = {};
      overallAppetiteStatus.status = riskAppetiteValues.overallAppetiteStatusName;
      if (appetiteStatusToColorMapping[riskAppetiteValues.overallAppetiteStatus]) {
          overallAppetiteStatus.color = appetiteStatusToColorMapping[riskAppetiteValues.overallAppetiteStatus]["colorName"] || "";
          overallAppetiteStatus.icon = appetiteStatusToColorMapping[riskAppetiteValues.overallAppetiteStatus]["iconName"] || "";
      } else {
          overallAppetiteStatus.color = "";
          overallAppetiteStatus.icon = "";
      }
      riskAppetiteInfo.qualAppetiteStatus = qualAppetiteStatus;
      riskAppetiteInfo.quantAppetiteStatus = quantAppetiteStatus;
      riskAppetiteInfo.overallAppetiteStatus = overallAppetiteStatus;
      riskAppetiteInfo.riskAppetiteStatement = riskAppetiteValues.riskAppetiteStatement;
      return riskAppetiteInfo;
  },

  _computeAllAssessmentsAppetiteStatus: function(risk) {

      var assessments = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      assessments.addQuery("risk", risk);
      assessments.addQuery("state", "IN", this._getActiveRiskAssessmentState());
      assessments.addQuery("risk_assessment_methodology.state", "2");
      assessments.query();

      while (assessments.next()) {
          this._computeAppetiteStatusForRiskAssessment(assessments, true);
          this._computeAppetiteStatusForTargetRiskAssessment(assessments, true);
      }

  },

  _updateAppetiteColumnsInRecord: function(record, appetiteStatus, shouldUpdate) {
      if (record) {
          record.setValue("qual_appetite_status", appetiteStatus.qualAppetiteStatus);
          record.setValue("quant_appetite_status", appetiteStatus.quantAppetiteStatus);
          record.setValue("computed_qual_appetite", appetiteStatus.computedQualitativeAppetite);
          record.computed_quant_appetite.setValue(appetiteStatus.computedQuantitativeAppetite);
          if (shouldUpdate)
              record.update();
      }
  },

  _updateAppetiteColumnsInTarget: function(record, appetiteStatus, shouldUpdate) {
      if (record) {
          record.setValue("projected_qual_appetite_status", appetiteStatus.qualAppetiteStatus);
          record.setValue("projected_quant_appetite_status", appetiteStatus.quantAppetiteStatus);
          record.setValue("projected_computed_qual_appetite", appetiteStatus.computedQualitativeAppetite);
          record.projected_computed_quant_appetite.setValue(appetiteStatus.computedQuantitativeAppetite);
          if (shouldUpdate)
              record.update();
      }
  },

  _handleInActiveAppetiteScale: function(record) {
      if (!this._isRiskAppetiteEnabled())
          return;
      // Clear the Given Appetite
      this._clearAppetiteScale("sn_risk_definition", "qual_appetite", record);
      this._clearAppetiteScale("sn_risk_definition", "qual_tolerance", record);
      this._clearAppetiteScale("sn_grc_profile", "qual_appetite", record);
      this._clearAppetiteScale("sn_grc_profile", "qual_tolerance", record);
      this._clearAppetiteScale("sn_risk_risk", "qual_appetite", record);
      this._clearAppetiteScale("sn_risk_risk", "qual_tolerance", record);

      // Clear the Computed Qual appetite
      this._clearAppetiteScaleAndStatus("sn_risk_definition", "computed_qual_appetite", "qual_appetite_status", record);
      this._clearAppetiteScaleAndStatus("sn_grc_profile", "computed_qual_appetite", "qual_appetite_status", record);
      this._clearAppetiteScaleAndStatus("sn_risk_advanced_risk_assessment_instance", "computed_qual_appetite", "qual_appetite_status", record);
      this._clearAppetiteScaleAndStatus("sn_risk_advanced_risk_assessment_instance", "projected_computed_qual_appetite", "projected_qual_appetite_status", record);

      // Clear the Rating Criteria 
      this._clearAppetiteScale("sn_risk_advanced_rating_criteria", "risk_appetite_scale", record, false);
  },

  _clearAppetiteScale: function(tableName, columnName, appetiteScale, workflowStatus) {
      var record = new GlideRecord(tableName);
      record.addQuery(columnName, appetiteScale);
      record.setValue(columnName, 'NULL');
      if (!gs.nil(workflowStatus))
          record.setWorkflow(workflowStatus);
      record.updateMultiple();
  },

  _clearAppetiteScaleAndStatus: function(tableName, appetiteColumnName, appetiteStatusColumnName, appetiteScale, workflowStatus) {
      var record = new GlideRecord(tableName);
      record.addQuery(appetiteColumnName, appetiteScale);
      record.setValue(appetiteColumnName, 'NULL');
      record.setValue(appetiteStatusColumnName, 'NULL');
      if (!gs.nil(workflowStatus))
          record.setWorkflow(workflowStatus);
      record.updateMultiple();
  },

  _handleAppetiteScaleValueChange: function(record) {
      if (!this._isRiskAppetiteEnabled())
          return;
      // Fetch all the Entity, Risk Statement, Risk Assessments and Risk. Check if the given appetite / tolerance / computed_qual_appetite has the above appetite scale, recompute
      this._reComputeAppetiteStatusForAllEntitiesOrRiskStatements("sn_risk_definition", record);
      this._reComputeAppetiteStatusForAllEntitiesOrRiskStatements("sn_grc_profile", record);
      this._reComputeAppetiteStatusForAllRisks(record);
      this._reComputeAppetiteStatusForAllRiskAssessments(record);
      this._reComputeAppetiteStatusForAllTargetRiskAssessments(record);
  },

  _reComputeAppetiteStatusForAllEntitiesOrRiskStatements: function(tableName, appetiteScale) {
      var record = new GlideRecord(tableName);
      var qc = record.addQuery("qual_appetite", appetiteScale);
      qc.addOrCondition("qual_tolerance", appetiteScale);
      qc.addOrCondition("computed_qual_appetite", appetiteScale);
      record.query();
      while (record.next()) {
          this._computeAppetiteStatusForEntityORiskStatement(record, true);
      }
  },

  _reComputeAppetiteStatusForAllRisks: function(appetiteScale) {
      var record = new GlideRecord('sn_risk_risk');
      var qc = record.addQuery("qual_appetite", appetiteScale);
      qc.addOrCondition("qual_tolerance", appetiteScale);
      record.query();
      while (record.next()) {
          this.computeAllAssessmentsAppetiteStatus(record);
      }
  },

  _reComputeAppetiteStatusForAllRiskAssessments: function(appetiteScale) {
      var record = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      record.addQuery("computed_qual_appetite", appetiteScale);
      record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      record.query();

      while (record.next()) {
          this._computeAppetiteStatusForRiskAssessment(record, true);
      }
  },

  _reComputeAppetiteStatusForAllTargetRiskAssessments: function(appetiteScale) {
      var record = new GlideRecord('sn_risk_advanced_risk_assessment_instance');
      record.addQuery("projected_computed_qual_appetite", appetiteScale);
      record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      record.query();

      while (record.next()) {
          this._computeAppetiteStatusForTargetRiskAssessment(record, true);
      }
  },

  _handleAppetiteScaleChangeOnRatingCriteria: function(ratingCrit) {

      var ratingCriteria = new GlideRecord("sn_risk_advanced_rating_criteria");
      ratingCriteria.get(ratingCrit);

      var assessmentType = new GlideRecord("sn_risk_advanced_assessment_type");
      assessmentType.get(ratingCriteria.getValue('assessment_type'));

      var ram = new GlideRecord("sn_risk_advanced_risk_assessment_methodology");
      ram.get(assessmentType.getValue('risk_assessment_methodology'));

      // Return for Object based assessment
      if (ram.getValue("assessed_on") == 1)
          return;

      var stateToRatingColumnsMapping = {
          "2": "sn_risk_advanced_rollup_result.inherent_rating",
          "3": "sn_risk_advanced_rollup_result.control_rating",
          "4": "sn_risk_advanced_rollup_result.residual_rating",
          "10": "sn_risk_advanced_rollup_result.target_rating"
      };

      var lastAssessableState = this._getLastAssessmentState(ram);
      var ratingColumn = stateToRatingColumnsMapping[lastAssessableState];
      var assessmentRatingColumn = this.asmtTableColumns[lastAssessableState]["final_risk_rating"];


      this._reComputeAppetiteStatus("sn_risk_advanced_risk_assessment_instance", assessmentRatingColumn, ratingCriteria, 'risk_assessment_methodology', ram);
      this._reComputeAppetiteStatus("sn_risk_definition", ratingColumn, ratingCriteria, 'ram_status_calculation', ram);
      this._reComputeAppetiteStatus("sn_grc_profile", ratingColumn, ratingCriteria, 'sn_risk_advanced_primary_risk_assessment_methodology', ram);
      this._reComputeAppetiteStatusForTargetAssessment(ratingCriteria, ram);

  },

  _reComputeAppetiteStatus: function(tableName, ratingColumn, ratingCriteria, ramColumnName, ram) {
      var record = new GlideRecord(tableName);
      record.addQuery(ramColumnName, ram.getUniqueValue());
      record.addQuery(ratingColumn, ratingCriteria.getUniqueValue());
      if (tableName == "sn_risk_advanced_risk_assessment_instance")
          record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      record.query();
      while (record.next()) {
          if (tableName == "sn_risk_advanced_risk_assessment_instance")
              this._computeAppetiteStatusForRiskAssessment(record, true);
          else
              this._computeAppetiteStatusForEntityORiskStatement(record, true);
      }
  },

  _reComputeAppetiteStatusForTargetAssessment: function(ratingCriteria, ram) {
      var record = new GlideRecord("sn_risk_advanced_risk_assessment_instance");
      record.addQuery('risk_assessment_methodology', ram.getUniqueValue());
      record.addQuery(this.asmtTableColumns[10]["final_risk_rating"], ratingCriteria.getUniqueValue());
      record.addQuery('state', "IN", this._getActiveRiskAssessmentState());
      record.query();
      while (record.next()) {
          this._computeAppetiteStatusForTargetRiskAssessment(record, true);
      }
  },


  _createEmailNotificationForRiskAppetiteStatusBreach: function(currentState, previousState, salutationName, owner, tableName, record) {
      var params = new Object();
      params['currentAppState'] = currentState;
      params['previousAppState'] = previousState;
      params['salutationName'] = salutationName;
      params['tableName'] = tableName;
      gs.eventQueue('sn_risk_advanced.risk_breach_of_appetite', record, owner.toString(), JSON.stringify(params));
  },

  _getAppetiteScaleChangeInProgressMessage: function() {
      var message = "";
      var isAppetiteScaleChangeInProgress = gs.getProperty("sn_risk_advanced.appetite_scale_change_in_progress", 'true') == 'true';

      if (isAppetiteScaleChangeInProgress)
          message = gs.getMessage('Appetite scale change is in progress. Please try after some time.');

      return message;
  },

  _canShowAppetiteDetails: function() {
      var canShow = false;
      var isQualitativeAppetiteEnabled = this._canHaveQualitativeAppetite();
      var isQuantitativeAppetiteEnabled = this._canHaveQuantitativeAppetite();
      var isBothAppetiteTypeEnabled = gs.getProperty('sn_risk_advanced.risk_appetite_analysis', 'risk_appetite_qualitative') == 'risk_appetite_both';
      if (isBothAppetiteTypeEnabled) {
          canShow = (gs.hasRole('sn_risk_advanced.qualitative_risk_appetite_reader') || gs.hasRole('sn_risk_advanced.quantitative_risk_appetite_reader'));
      } else if (isQualitativeAppetiteEnabled) {
          canShow = gs.hasRole('sn_risk_advanced.qualitative_risk_appetite_reader');
      } else if (isQuantitativeAppetiteEnabled) {
          canShow = gs.hasRole('sn_risk_advanced.quantitative_risk_appetite_reader');
      }
      var message = gs.getMessage("The current user does not have proper roles to view the appetite details. Please contact the System Administrator");
      return {
          canShow: canShow,
          message: message
      };
  },

  type: 'RiskAppetiteUtilsBase'
};

Sys ID

a8de4a9707511110e72bb5100ad300db

Offical Documentation

Official Docs: