Name

sn_hr_core.hr_Task

Description

No description available

Script

var hr_Task = Class.create();

hr_Task.prototype = {
  initialize: function(_gr, _gs) {
      //this._log = new GSLog(hr.LOG, this.type).setLog4J();
      this._gr = _gr;
      this._gs = _gs || gs;

  },

  isClosed: function(record) {
      return (record.state == hr_Constants.TASK_CLOSED_COMPLETE) || (record.state == hr_Constants.TASK_CLOSED_INCOMPLETE) || (record.state == hr_Constants.TASK_CANCELLED);
  },

  clearDependencies: function(taskRecord) {
      // TODO: clear dependencies
  },

  /**
   * Return true if:
   *   the user has case writer role
   *   the task status is assigned or ready
   *   the task isn't already assigned to the user
   *   if there is an assignment group, the user is in the assignment group
   * @return boolean user can assign the task to self
   */
  canAssignToSelf: function() {
      if (!this._gr)
          return false;

      if (this._gr.assigned_to == gs.getUserID())
          return false; // already assigned to user so return false

      var assignableState = this._gr.state == hr_Constants.TASK_ASSIGNED || this._gr.state == hr_Constants.TASK_PENDING_DISPATCH;
      if (!assignableState)
          return false;

      var hasRole = this._gs.hasRole("sn_hr_core.case_writer");
      if (!hasRole)
          return false;
  	
  	if (!this._gr.canWrite())
  		return false;

      if (this._gr.assignment_group.nil()) // no longer requiring an assignment group to be set
          return true;

      var user_group = new GlideRecord("sys_user_grmember");
      user_group.addQuery("user", this._gs.getUserID());
      user_group.addQuery("group", this._gr.assignment_group.toString());
      user_group.query();
      var userIsAgentForGroup = user_group.hasNext();

      return userIsAgentForGroup;
  },

  // helper method for read/write ACLs
  canEditTask: function(userId) {
      var user;
      var parentCaseGr;
      if (!gs.nil(this._gr.parent))
          parentCaseGr = this._gr.parent.getRefRecord();
      if (gs.nil(userId)) {
          if (new hr_Utils().checkUserHasRole(hr.ROLE_HR_CASE_WRITER)) {
              if (!gs.nil(parentCaseGr) && parentCaseGr.canWrite() && parentCaseGr.canRead())
                  return true;
          }

          userId = this._gs.getUserID();
          user = this._gs.getUser();
      } else {
          // getUserByID API is not available in scope
          var grHasRole = new GlideRecord('sys_user_has_role');
          grHasRole.addQuery('state', 'active');
          grHasRole.addQuery('user', userId);
          grHasRole.addQuery('role.name', hr.ROLE_HR_CASE_WRITER);
          grHasRole.setLimit(1);
          grHasRole.query();
          if (grHasRole.hasNext()) {
              if (!gs.nil(parentCaseGr) && parentCaseGr.canWrite() && parentCaseGr.canRead())
                  return true;
          }
      }

      // Check if it's the user who opened the case
      if (!gs.nil(this._gr.parent) && this._gr.parent.opened_by == userId)
          return true;

      // Check if it's the user the case is opened for
      if (!gs.nil(this._gr.parent) && this._gr.parent.opened_for == userId)
          return true;

      // Check if the user belongs to the assignment group
  	if (user) {
  		if (!gs.nil(this._gr.assignment_group) && user.isMemberOf(this._gr.assignment_group.toString()))
  			return true;
  	} else {
  		if (!gs.nil(this._gr.assignment_group) && new global.HRSecurityUtils().isMemberOfGroup(userId, this._gr.assignment_group.toString()))
  			return true;
  	}
  	
      // Check if the task is assigned to the user
      if (!gs.nil(this._gr.assigned_to) && new hr_Delegation().isAssignedOrDelegated(this._gr, userId))
          return true;

      // Check if it's a user in the watch list field
      if (!gs.nil(this._gr.watch_list) && this._gr.watch_list.indexOf(userId) > -1)
          return true;

      return false;
  },
  
  _arrayContains : function(ary, seed) {
  	for (var i = 0; i < ary.length; i++)
  		if (ary[i].trim() === seed)
  			return true;
  	return false;
  },
  
  updateAttachments: function(current) {
      var taskAttachments = new GlideSysAttachment().copy(current.sys_class_name, current.sys_id, current.parent.sys_class_name, current.parent.sys_id);

      if (taskAttachments.length > 0) {

          if (new GlidePluginManager().isActive('com.sn_employee_document_management')) {
              for (var i = 0; i < taskAttachments.length; i++) {
                  var IDs = taskAttachments[i].split(',');
                  var attachmentCopyRecord = new GlideRecord('sn_hr_ef_attachment_tracking');
                  attachmentCopyRecord.initialize();
                  attachmentCopyRecord.original = IDs[0];
                  attachmentCopyRecord.copy = IDs[1];
                  attachmentCopyRecord.insert();
              }
          }

          current.comments = gs.getMessage('The task attachments have been copied to the parent case.');
          current.update();
      }
  },

  canSignDocument: function() {
      //Task must be active, assigned to user, and e_signature type
      if (!this._gr.active || this._gr.hr_task_type != 'e_signature' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS)
          return false;

      //There must be a published Document Revision
      var docRev = new GlideRecord('dms_document_revision');
      docRev.addQuery('document', this._gr.hr_task_document);
      docRev.addQuery('stage', 'published');
      docRev.addActiveQuery();
      docRev.query();

      return docRev.hasNext();
  },

  canSignGeneratedDocument: function() {
      //Task must be active, assigned to user, and has the proper type
      if (!this._gr.active || this._gr.hr_task_type != 'sign_document' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS)
          return false;

      //The task must have a PDF template
      if (this._gr.parent.ref_sn_hr_core_case.pdf_template == '')
          return false;

      //Task must have an associated Pdf_draft or draft_document
      if (!this.hasDraftDocument())
          return false;

      return true;
  },
  
  canESign: function() {
      if (!this._gr.active || this._gr.hr_task_type != 'e_sign' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;
  	if(!this._gr.sn_esign_esignature_configuration) 
  		return false;
  	if(this._gr.sn_esign_esignature_configuration.document_type == "document_template")
  		return this.canESignDocumentTemplate();
  	else
  		return new sn_esign.esign_task(this._gr,this._gs).canSignDocument();
  },		
  
  canESignDocumentTemplate: function() {
      //Task must be active, assigned or delegated to user, and has the proper type
      if (!this._gr.active || this._gr.hr_task_type != 'e_sign' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS && this._gr.state != hr_Constants.TASK_IN_PROGRESS)
          return false;

  	if(!this._gr.sn_esign_esignature_configuration) 
  		return false;

  	
  	if(!(this._gr.sn_esign_esignature_configuration.document_type == "document_template" && this._gr.sn_esign_esignature_configuration.signature_type == "signature"))	
  		return false;	
  	
      //The task must have a PDF template
      if (!this._gr.parent.ref_sn_hr_core_case.pdf_template)
          return false;

      //Task must have an associated Pdf_draft or draft_document
      if (!this.hasDraftDocument())
          return false;

      return true;
  },	

  hasDraftDocument: function() {
      var hasDraftDocument = new GeneralHRForm().hasDraftDocument(this._gr.sys_class_name, this._gr.getUniqueValue());
      var hasDraftPDF = new hr_PdfUtils().isValidPdfTemplate(this._gr.sys_class_name, this._gr.getUniqueValue());
      return (hasDraftPDF || hasDraftDocument);
  },

  canAuthenticate: function() {
      //Task must be active, assigned or delegated to user, and credential type
      if (!this._gr.active || this._gr.hr_task_type != 'credential' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS )
          return false;

      //There must be a published Document Revision
      var docRev = new GlideRecord('dms_document_revision');
      docRev.addQuery('document', this._gr.hr_task_document);
      docRev.addQuery('stage', 'published');
      docRev.addActiveQuery();
      docRev.query();

      return docRev.hasNext();
  },

  canCompleteURLTask: function() {
      //Task must be active and assigned or delegated to user
      if (!this._gr.active || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS )
          return false;

      //The URL must be defined
      return this._gr.url != '';
  },

  canCompleteSurveyTask: function() {
      //Task must be active and assigned to user
      if (!this._gr.active  || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS )
          return false;

      //The Survey Instance must be defined
      return this._gr.survey_instance != '';
  },

  canCompleteAttachmentTask: function() {
      //Task must be active, assigned or delegated to user, and URL type
      if (!this._gr.active || this._gr.hr_task_type != 'upload_documents' || !new hr_Delegation().isAssignedOrDelegated(this._gr, this._gs.getUserID()))
          return false;

      //State must be Ready or Work In Progress
      if (this._gr.state != hr_Constants.TASK_QUALIFIED && this._gr.state != hr_Constants.TASK_WORK_IN_PROGRESS )
          return false;

      return true;
  },

  //This method is being kept for backwards compatibility for a previous release
  getMyTasks: function(userId) {
  	var gr = new GlideRecordSecure("sn_hr_core_task");
  	gr.addQuery("state", "!=", hr_Constants.TASK_DRAFT);
  	gr.addQuery("parent.state", "!=",hr_Constants.CASE_DRAFT);
  	gr.addQuery("parent.active", "true");
  	var query = gr.getEncodedQuery();
  	gr.addQuery("assigned_to", userId).addOrCondition('sys_id', 'IN', new hr_Delegation().getDelegatedTasks({ tables: ['sn_hr_core_task'], encoded_query: query }, userId));
  	gr.orderBy('due_date');
  	gr.orderByDesc('sys_created_on');
  	gr.query();
  	var now = new GlideDateTime();
  	var offset = now.getTZOffset();
  	now = now.getNumericValue() + offset;
  	var tasks = [];
  	while (gr.next()) {
  		var task = {};
  		task.sys_id = gr.getValue("sys_id");
  		task.case_id = gr.getValue("parent");
  		if (gr.template && gr.template.show_translated_fields)
  			task.short_description = String(gr.template.short_description_for_employee); 
  		else
  			task.short_description = gr.getValue("short_description");
  		task.number = gr.getValue("number");
  		task.order = gr.getValue("order");
  		task.template = gr.getValue("template");
  		task.state = gr.getValue("state");
  		task.finished = gr.getValue("active") == "0";
  		task.opened_by = gr.getValue("opened_by");
  		task.assigned_to = gr.getValue("assigned_to");
  		task.updated = gr.getValue("sys_updated_on");
  		task.due_date = gr.getValue("due_date");
  		task.closed_at = gr.getValue("closed_at");
  		task.hr_task_type = gr.getValue("hr_task_type");
  		task.url = gr.getDisplayValue("url");
  		task.parent = gr.getValue("parent");
  		task.isOverDue = now > new GlideDateTime(gr.due_date).getNumericValue();
  		task.assigned_to_me = gr.getValue("assigned_to") == userId;
  		tasks.push(task);
  	}
  	
  	return tasks;
  },

  cloneTask: function(original, cloneAsFollowOn) {
      var className = original.sys_class_name + '';
      // Clone this task to a new, mostly identical, task
      cloneAsFollowOn = cloneAsFollowOn === undefined ? false : cloneAsFollowOn;

      var includedFields = ['parent', 'location', 'hr_task_type', 'hr_service', 'sc_cat_item', 'order_guide', 'hr_task_document', 'survey', 'url', 'short_description', 'description', 'rich_description', 'optional', 'assignment_group', 'task_support_team', 'parent_case_users', 'groups', 'queue', 'skills', 'sys_domain'];

      var clone = new GlideRecord(className);
      clone.cloned_from = original.sys_id;
      clone.state = hr_Constants.TASK_DRAFT; // Default state is Draft
      clone.work_notes = gs.getMessage("Cloned from HR Task {0}", original.number);
      includedFields.forEach(function(field) {
          clone[field] = original[field];
      });
      clone.insert();

      // If the original was to be cloned as a follow on, set the "has follow on" flag
      if (cloneAsFollowOn) {
          original.has_follow_on = true;
          original.update();
      }

      // Return the newly cloned record
      return clone;

      // The following fields are not copied
      /*
  	Acknowledged on
  	Active
  	Activity Due
  	Actual duration
  	Actual Travel Duration
  	Actual Travel Start
  	Actual Service end
  	Actual Service start
  	Approval
  	Approval History
  	Approval Set
  	Close Notes
  	Closed
  	Closed By
  	cmdb_ci
  	Comments and Service notes
  	Company
  	Contact Type
  	Contract
  	Correlation ID
  	Correlation display
  	Created
  	Created By
  	Delivery Plan
  	Delivery task
  	Dispatched On
  	Due Date
  	Escelation
  	Followup
  	Group List
  	Impact
  	Knowledge
  	Made SLA
  	Number
  	Opened
  	Opened By
  	Order
  	Priority
  	Reassignment count
  	SLA Due
  	task type
  	Time serviced
  	Updated
  	Updated By
  	Updates
  	Upon approval
  	Upon reject
  	Urgency
  	User input
  	Watch List
  	Work Notes
  	Work Notes list
  	*/
  },

  getDueDays: function(dueDate) {
      if (!dueDate)
          return 'later'; //Assuming task with no due date can be done later

      var due_date = new GlideDateTime(dueDate);
      var gdTaskDueDate = due_date.getLocalDate();
      var gdLocal = new GlideDateTime().getLocalDate();
      return GlideDate.subtract(gdLocal, gdTaskDueDate).getDayPart();
  },
  
  /* Generate a URL link for a given to-do either in native UI or service portal
  @param : string - table name
  @param: string - sys id of the record associated with the table
  @output : string - url
  */
  getToDoURL: function(tableName, recordSysId) {
  	if(gs.nil(tableName) || gs.nil(recordSysId))
  		return null;
  	var gr = new GlideRecord(tableName);
  	if (!gr.get(recordSysId))
  		return null;
  	
  	// Display the to-do on service portal if HR SP plugin is active
  	if (new GlidePluginManager().isActive("com.sn_hr_service_portal")) 
  		return new sn_hr_sp.todoPageUtils().getTodoURL(gr);
  	// If not, display the to-do in native UI
  	return gs.getProperty("glide.servlet.uri") + 'nav_to.do?uri=' + gr.getTableName() + '.do?sys_id=' + recordSysId + '&sysparm_stack=' + gr.getTableName() + '_list.do';
  },

  type: "hr_Task"
};

/* Get an sn_hr_core_task record based on sys_id, ignoring Query BR's. Cannot setWorkflow(false) on sn_hr_core_task outside of sn_hr_core scope
* @param sysId {String} - The sys_id of a potential test
* @return {GlideRecord} - The record that is queried, or null
*/
hr_Task.getHrTask = function(sysId) {
  if (!gs.hasRole('sn_hr_core.case_reader'))
  	return null;
  
  var grTask = new GlideRecord('sn_hr_core_task');
  grTask.setWorkflow(false);
  if (grTask.get('sys_id', sysId)) {
  	grTask.setWorkflow(true);
  	return grTask;
  }
  
  return null;
};

Sys ID

765370019f22120047a2d126c42e7000

Offical Documentation

Official Docs: