Name

global.pwdEnrollmentReminderHelper

Description

No description available

Script

var pwdEnrollmentReminderHelper = Class.create();
pwdEnrollmentReminderHelper.prototype = {
  ENROLL_REMINDER_CHILD_SCHEDULED_JOB_PREFIX: "pwd_",
  EMAIL_BATCH_SIZE_PROPERTY: "password_reset.enrollment_reminder.email_batch_size",
  EMAIL_BATCH_EXECUTION_DELAY: 900, //child schedule jobs will be scheduled to run 15 mins after current time
  TO_EMAIL_ADDRESS: "do-not-reply@servicenow.com",
  SYS_TRIGGER_JOB_ID: "81c92ce9c0a8016400e5f0d2f784ea78",
  ENROLLMENT_EVENT_NAME_FOR_VA: "sn_pwdreset_va.enrollment_reminder",
  
  initialize: function() {
  },
  
  sendReminderToNotEnrolledUsersForProcess: function(processId) {
  	var limit = GlidePropertiesDB.get(this.EMAIL_BATCH_SIZE_PROPERTY);
  	var currentTime = new GlideDateTime();
  	this._createRunOnceChildScheduledJob(0, limit, processId, currentTime);
  },
  
  sendReminderInBatch: function(start, limit, processId) {
  	var process = this._getProcessGr(processId);
  	if(gs.nil(process)) {
  		gs.info("Process not found");
  		return false;
  	}
  	if(process.apply_to_all_users) {
  		this.processAllUsers(start, limit, process);
  	} else {
  		this.processUsersFromGroup(start, limit, process);
  	}
  },
  	
  processAllUsers: function(start, limit, process) {
  	var userIds = [];
  	var users = this.getUsersInBatch(start, limit);
  	if(!gs.nil(users)) {
  		do {
  			var userId = users.getValue("sys_id");
  			if(this.getEnrollmentStatusForProcess(userId, process))
  				continue;
  			userIds.push(userId);
  		} while(users.next());

  		var newStart = start+limit;
  		this.sendNotificationAndSetUpNextBatch(userIds, newStart, start, limit, process.sys_id);
  	}
  },
  
  processUsersFromGroup: function(start, limit, process) {
  	var userIds = [];
  	var users = this.getUserListFromGroupsInBatch(start, limit, process);
  	if(!gs.nil(users)) {
  		do {
  			var userId = users.getValue("user") + '';
  			if(this.getEnrollmentStatusForProcess(userId, process))
  				continue;
  			userIds.push(userId);
  		} while(users.next());
  		//start for new batch.. 
  		// Last index is included in GlideAggregate query that's why new start is start + limit + 1 instead start + limit. 
  		var newStart = start + limit + 1;
  		this.sendNotificationAndSetUpNextBatch(userIds, newStart, start, limit, process.sys_id);
  	}
  },
  
  sendNotificationAndSetUpNextBatch: function(userIds, newStart, start, limit, processId) {
      if (userIds.length) {
          var procGr = this._getProcessGr(processId);
          var toRecipients = procGr.getValue("sender_alias");
          if (gs.nil(toRecipients))
              toRecipients = this.TO_EMAIL_ADDRESS;
          gs.eventQueue("pwd.enrollment_reminder.trigger", null, toRecipients, userIds.join(","));
          this._sendEnrollmentEventsToGCF(userIds.length);
          var gr = GlideRecord("sysevent_register");
          gr.addQuery("event_name", this.ENROLLMENT_EVENT_NAME_FOR_VA);
          gr.query();
          if (gr.next()) {
              for (var i = 0; i < userIds.length; i++) {
                  gs.eventQueue(this.ENROLLMENT_EVENT_NAME_FOR_VA, null, userIds[i], null);
              }
          }
      }

      var currentTime = new GlideDateTime();
      currentTime.addSeconds(this.EMAIL_BATCH_EXECUTION_DELAY);
      //create new child job for next batch of users
      this._createRunOnceChildScheduledJob(newStart, limit, processId, currentTime);
  },
  
  getUserListFromGroupsInBatch: function(start, limit, process) {
  	var userGroups = [];
  	var end = start + limit;
  	
  	var gr = new GlideRecord("pwd_map_proc_to_group");
  	gr.addQuery("process", process.getValue("sys_id"));
  	gr.query();
  	while(gr.next()) {
  		userGroups.push(gr.getValue("user_group"));
  	}
  	var userGrpMemGr = new GlideAggregate("sys_user_grmember");
  	userGrpMemGr.addQuery("group", "IN", userGroups.join());
  	userGrpMemGr.addQuery("user.active", true);
  	userGrpMemGr.addQuery("user.notification", 2);
  	userGrpMemGr.addNotNullQuery("user.email");
  	userGrpMemGr.addAggregate('COUNT(DISTINCT', 'user');
      userGrpMemGr.orderBy("user.sys_created_on");
  	userGrpMemGr.groupBy('user');
  	userGrpMemGr.chooseWindow(start, end, true);
  	userGrpMemGr.query();
  	if(userGrpMemGr.next())
  		return userGrpMemGr;
  	return null;
  },
  
  getUsersInBatch: function(start, limit) {
  	var end = start + limit;
  	var gr = new GlideRecord("sys_user");
  	gr.addActiveQuery();
  	gr.addQuery("notification", 2); //notification is enabled
  	gr.addNotNullQuery("email");
  	gr.chooseWindow(start, end, true);
  	gr.orderBy("sys_created_on");
  	gr.query();
  	if(gr.next())
  		return gr;
  	return null;
  },
  		
  getEnrollmentStatusForProcess: function(userId, process) {

  	var verificationsEnrolled = 0;
  	var minimumVers =  process.getValue("min_verifications");
  	//Check if user is enrolled in all mandatory verifications
  	var result = this.getUserEnrollmentstatusForMandatoryVerifications(userId, process);
  	if(!result.enrolled){
  		return false;
  	}

  	verificationsEnrolled = result.enrolledVerificationCount;
  	if(verificationsEnrolled >= minimumVers)
  		return true;

  	result = this.getUserEnrollmentstatusForNonMandatoryVerifications(userId, process, false);
  	verificationsEnrolled = verificationsEnrolled + result.enrolledVerificationCount;
  	if(verificationsEnrolled >= minimumVers)
  		return true;

  	return false;
  },
  		
  getUserEnrollmentstatusForMandatoryVerifications: function(userId, process) {
  	return this.getUserEnrollmentStatusForVerifications(userId, process, true);
  },

  getUserEnrollmentstatusForNonMandatoryVerifications: function(userId, process) {
  	return this.getUserEnrollmentStatusForVerifications(userId, process, false);
  },

  getUserEnrollmentStatusForVerifications: function(userId, process, mandatory) {
  	var result = {enrolled: false, enrolledVerificationCount:0 };
  	var verificationIds = new SNC.PwdProcessManager().getProcessVerificationIdsByMandatoryFlag(process.getValue("sys_id"), mandatory);
  	var versArr = [];
  	for (var i = 0; i != verificationIds.size(); ++i)
  		versArr.push(verificationIds.get(i));
  	
  	var pwdEnrollmentMgr = new SNC.PwdEnrollmentManager();
  	for (var j  = 0; j < versArr.length; j++) {
  		if(pwdEnrollmentMgr.isUserEnrolledByVerificationId(userId, versArr[j]))
  			result.enrolledVerificationCount++;
  	}
  	result.enrolled =  result.enrolledVerificationCount == versArr.length;
  	return result;
  },
  
  _getProcessGr : function(processId) {
  	var gr = new GlideRecord("pwd_process");
  	if(gr.get(processId))
  		return gr;
  	return null;
  },

  _createRunOnceChildScheduledJob: function(start, limit, processId, startTime) {
  	var gr = new GlideRecord("sys_trigger");
  	gr.setValue("name", this._getChildScheduleJobName(processId, start));
  	gr.setValue("trigger_type", "0"); // run once
  	gr.setValue("state", "0"); // ready
  	gr.setValue("next_action", startTime);
  	gr.setValue("script", this._getChildScheduleJobScript(start, limit, processId));
  	gr.setValue("job_id", this.SYS_TRIGGER_JOB_ID);
  	return gr.insert();
  },
  
  _getChildScheduleJobScript: function(start, limit, processId) {
  	return "new global.pwdEnrollmentReminderHelper().sendReminderInBatch("+ start +", " + limit + ", \'" + processId + "\');";
  },
  
  _getChildScheduleJobName: function(processId, start) {
  	return this.ENROLL_REMINDER_CHILD_SCHEDULED_JOB_PREFIX + processId + "_" + start;
  },
  
  deleteChildScheduleJob: function(processId){
  	var gr = new GlideRecord("sys_trigger");
  	gr.addQuery("name", "STARTSWITH" , this.ENROLL_REMINDER_CHILD_SCHEDULED_JOB_PREFIX + processId);
  	gr.query();
  	if(gr.next())
  		gr.deleteRecord();
  },

  _sendEnrollmentEventsToGCF: function(numEvents) {
  	var collectionPointObj = PwdResetGCFConstants.CollectionConstants.PasswordResetApp;
  	var collectionEventObj = collectionPointObj.PasswordResetNotifications;
  	var dimensionsObj = collectionEventObj.Dimensions;
  	for (var i = 0; i < numEvents; i++) {
  		new PwdResetUsageInstrumentation(collectionPointObj.COLLECTION_POINT_VALUE, collectionEventObj.COLLECTION_EVENT_VALUE)
  			.addBucket(dimensionsObj.TYPE, 'Enrollment Reminder')
  			.buildUsageEvent();
  	}
  },
  
  type: 'pwdEnrollmentReminderHelper'
};

Sys ID

0c7c54b00b06030031a567bff6673ac0

Offical Documentation

Official Docs: