WorkItems getting Expired Early

Which IIQ version are you inquiring about?

8.4

Please share any images or screenshots, if relevant.

[Please insert images here, otherwise delete this section]

Please share any other relevant files that may be required (for example, logs).

[Please insert files here, otherwise delete this section]

Share all details about your problem, including any error messages you may have received.

Dear Team,

We have configured reminders for pending workitems and below are the configuration details from the provisioning approval workflow:

2 reminders should be sent to the owners with 1hr difference and then item should get expired after 10hrs but workitems were getting expired after 3hrs. (not even considering expiration value)

Am doing anything wrong?

  <Variable input="true" name="workItemDescription">
    <Description>String &amp;quot;template&amp;quot; that will be used as the workitem description.</Description>
  </Variable>
  <Variable input="true" name="workItemEscalationTemplate">
    <Description>The email template that should be used when sending out reminders.</Description>
  </Variable>
  <Variable initializer="1" input="true" name="workItemHoursBetweenReminders">
    <Description>The number of hours to wait between sending reminders to approvers.</Description>
  </Variable>
  <Variable initializer="1" input="true" name="workItemHoursTillEscalation">
    <Description>The number of hourse to wait until an approval should be escalated.</Description>
  </Variable>
  <Variable initializer="both" name="workItemEscalationStyle">
    <Description>drives the escalation behavior. Can be:
      none: No reminders and no escalations at all - default
      both: Issue reminders and escalations according to the config if no config is given, defaults are used
      escalation: do escalations only
      reminder: do reminders only
    </Description>
  </Variable>
  <Variable initializer="Normal" input="true" name="workItemPriority">
    <Description>The String version of a WorkItem.Priority. This variable is
      used to set the priority on all of the workitems generated
      as part of this workflow and also set on the IdentityRequest
      object.</Description>
  </Variable>
  <Variable initializer="10" input="true" name="workItemHoursTillExpiration"/>
  <Variable initializer="Work Item Reminder" input="true" name="workItemReminderTemplate">
    <Description>The email template that should be used when sending out reminders.</Description>
  </Variable>
  <Variable input="true" name="workItemEscalationRule">
    <Description>The rule used to assign a new ownder during escalation.</Description>
  </Variable>
  <Variable initializer="2" input="true" name="workItemMaxReminders">
    <Description>The maximum number of reminder emails that will be sent before we begin the escalation process.</Description>
  </Variable>

After script:
----------
 <Step icon="Approval" name="Approval" posX="158" posY="22">
    <Approval mode="ref:approvalMode" owner="call:buildCommonApprovals" renderer="lcmWorkItemRenderer.xhtml" send="identityDisplayName,identityName,approvalSet,flow,policyViolations,identityRequestId">
      <AfterScript>
        <Source>
          import sailpoint.workflow.IdentityRequestLibrary;

          import sailpoint.object.ApprovalItem;
          import sailpoint.object.ApprovalSet;
          import sailpoint.object.WorkItem;
          import sailpoint.object.Comment;

          if ( item == null ) 
          return;

          WorkItem.State state = item.getState();
          if(state.equals(WorkItem.State.Expired)){
          List approvalItems = approvalSet.getItems();
          for (ApprovalItem approvalItem : approvalItems) {
          approvalItem.reject();
          List listOfComments = approvalItem.getComments();
          approvalItem.add(new Comment("Auto reject item due to lack of approval", "system"));
          item.addComment("Auto reject item by system due to lack of approval", "system");
          item.setCompletionComments("Auto reject item by system due to lack of approval");
          }
          }

          assimilateWorkItemApprovalSet(wfcontext, item, approvalSet);          
          auditDecisions(item);  
          IdentityRequestLibrary.assimilateWorkItemApprovalSetToIdentityRequest(wfcontext, approvalSet);
        </Source>

InterceptorScript:
--------------
          import sailpoint.object.Workflow.Approval;
          import sailpoint.object.ApprovalItem;
          import sailpoint.object.ApprovalSet;
          import sailpoint.object.Workflow;
          import sailpoint.object.WorkItem;
          import sailpoint.tools.Util;
          import java.util.Iterator;
          import java.util.ArrayList;
          import java.lang.Boolean;
          import sailpoint.object.Attributes;
          import sailpoint.object.WorkItem;
          import sailpoint.object.Workflow;
          import sailpoint.tools.Util;


          Date expirationDate = new Date();
          if (method != null &amp;&amp; method.equals(Workflow.INTERCEPTOR_OPEN_WORK_ITEM)) {
          if (workflow != null) {
          Attributes configAttrs = item.getAttributes();
          log.error(" configAttrs: " + configAttrs);
          if (configAttrs != null) {
          String hoursTillExpiration = (String) configAttrs.get("workItemHoursTillExpiration");
          log.error(" hoursTillExpiration: " + hoursTillExpiration);
          if (hoursTillExpiration != null) {
          int hoursTillExpirationInt = Util.atoi(hoursTillExpiration);
          if (hoursTillExpirationInt != null &amp;&amp; hoursTillExpirationInt > 0) {
          int minutes = hoursTillExpirationInt * 60;
          Date dateExp = Util.incrementDateByMinutes(new Date(), minutes);
          log.error(" dateExp: " + dateExp);
          if (item != null &amp;&amp; item.getExpirationDate() == null &amp;&amp; context != null
          &amp;&amp; dateExp != null) {
          log.error("Before item.getExpirationDate(): " + item.getExpirationDate());
          item.setExpiration(Util.getEndOfDay(dateExp));
          item.setWakeUpDate(dateExp);
          context.saveObject(item);
          context.commitTransaction();
          log.error("After item.getExpirationDate(): " + item.getExpirationDate());
          }
          }
          }
          }
          }
          }
          // custom step ended

          if (Workflow.INTERCEPTOR_PRE_ASSIMILATION.equals(method)) {
          // promote completion state to Rejected if all items are rejected
          ApprovalSet aset = item.getApprovalSet();

Hi @harishabn

You don’t need to modify the interceptor script for your use case. Everything can be controlled using workflow variables. Please remove yourtype or paste code here custom code and try setting the following variables instead.

In the “Provisioning Approval Subprocess”, at the “Approval” step, set the following variables

<Arg name="workItemReminderTemplate" value="Work Item Reminder"/>
<Arg name="workItemHoursBetweenReminders" value="1"/>
<Arg name="workItemHoursTillEscalation" value="1"/>
<Arg name="workItemMaxReminders" value="2"/>

<Arg name="workItemExpirationHours" value="10"/>
<Arg name="workItemExpirationTemplate" value="Work Item Assignment Removal"/>

Hi @Arpitha1 ,

Thanks for the looking into it!

Arg details already present at approval step, please check below and let me know incase of any changes are required?


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Workflow explicitTransitions="true" libraries="Identity" name="Provisioning Approval Subprocess" type="Subprocess">
  <Variable initializer="serial" input="true" name="approvalMode">
    <Description>A string that specifies how we should handle the approvals.

      By default this is serial since most of these request with
      the exception of manager transfers will have only one approver.

      parallel
      Approvals are processed concurrently and there must be consensus,
      we wait for all approvers to approve.  The first approver that
      rejects terminates the entire approval.

      parallelPoll
      Approvals are processed concurrently but consensus is not required.
      All approvals will be processed, we don&amp;#39;t stop if there are any
      rejections.

      serial
      Approvals are processed one at a time and there must be consensus.
      The first approver that rejects terminates the entire approval.

      serialPoll
      Approvals are processed in order but consensus is not required.
      All approvals will be processed, we don&amp;#39;t stop if there are any
      rejections.  In effect we are &amp;quot;taking a poll&amp;quot; of the approvers.

      any
      Approvals are processed concurrently, the first approver to
      respond makes the decision for the group.</Description>
  </Variable>
  <Variable input="true" name="approvalScheme">
    <Description>A csv string that specifies how approval items should be generated 
      for the incoming request.

      The value can be &amp;quot;none&amp;quot;, in which case approvals are disabled.

      The value can also be a combination of any of the values below 
      in any order, separated by commas. The order in which they are 
      specified is the order in which they are processed:

      owner
      The object owner gets the approval item. 
      For Role approvals this is the Role object owner. 
      For Entitlement approvals this is the Entitlement object owner.

      manager
      The manager gets the approval item.

      securityOfficer
      The identity in the variable securityOfficerName gets the approval item.

      identity
      The identities/workgroups in the variable approvingIdentities get the approval item.</Description>
  </Variable>
  <Variable input="true" name="approvingIdentities">
    <Description>List of identities and/or workgroups names/ids that should be involved in the approval 
      process.</Description>
  </Variable>
  <Variable initializer="spadmin" input="true" name="fallbackApprover">
    <Description>A String that specifies the name of the Identity that will 
      be assigned any approvals where the owner of the approver 
      can&amp;#39;t be resolved. Example if the scheme is &amp;quot;owner&amp;quot; and the 
      application doesn&amp;#39;t specify and owner.</Description>
  </Variable>
  <Variable input="true" name="flow">
    <Description>The name of the LCM flow that launched this workflow.

      This is one of these values:

      AccountsRequest
      EntitlementsRequest
      RolesRequest
      IdentityCreateRequest
      IdentityEditRequest
      ForgotPassword
      ExpiredPassword
      PasswordRequest
      joiner
      mover
      leaver
      AttributeSync</Description>
  </Variable>
  <Variable input="true" name="identityName">
    <Description>The name of the identity being updated.</Description>
  </Variable>
  <Variable input="true" name="identityDisplayName">
    <Description>The displayName of the identity being updated.
      Query for this using a projection query and fall back to the name.</Description>
  </Variable>
  <Variable input="true" name="identityRequestId">
    <Description>The ID of the IdentityRequest for this request.</Description>
  </Variable>
  <Variable input="true" name="noTriggers">
    <Description>If true, then do no attempt to trigger lifecycle events.</Description>
  </Variable>
  <Variable input="true" name="policyViolations">
    <Description>List of policy violations that were found during our initial policy scan.
      This list is passed into each work item so the approvers can see
      pending violations.</Description>
  </Variable>
  <Variable input="true" name="managerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems
      are completed by a manager.</Description>
  </Variable>
  <Variable input="true" name="ownerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems
      are completed by object owners.</Description>
  </Variable>
  <Variable input="true" name="securityOfficerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems
      are completed by the security officer.</Description>
  </Variable>
  <Variable input="true" name="identityElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems
      are completed by object owners.</Description>
  </Variable>
  <Variable initializer="LCM Identity Update Approval" input="true" name="managerEmailTemplate">
    <Description>Name of the email template to use when manager of pending approvals.</Description>
  </Variable>
  <Variable initializer="LCM Identity Update Approval" input="true" name="ownerEmailTemplate">
    <Description>Name of the email template to use when notifying the owner of pending approvals.</Description>
  </Variable>
  <Variable initializer="LCM Identity Update Approval" input="true" name="securityOfficerEmailTemplate">
    <Description>Name of the email template to use when notifying the security officer of pending approvals.</Description>
  </Variable>
  <Variable initializer="LCM Identity Update Approval" input="true" name="identityEmailTemplate">
    <Description>Name of the email template to use when notifying the security officer of pending approvals.</Description>
  </Variable>
  <Variable initializer="false" name="trace">
    <Description>Used for debugging this workflow and when set to true trace
      will be sent to stdout.</Description>
  </Variable>
  <Variable input="true" name="workItemDescription">
    <Description>String &amp;quot;template&amp;quot; that will be used as the workitem description.</Description>
  </Variable>
  <Variable input="true" name="workItemEscalationTemplate">
    <Description>The email template that should be used when sending out reminders.</Description>
  </Variable>
  <Variable initializer="1" input="true" name="workItemHoursBetweenReminders">
    <Description>The number of hours to wait between sending reminders to approvers.</Description>
  </Variable>
  <Variable initializer="1" input="true" name="workItemHoursTillEscalation">
    <Description>The number of hourse to wait until an approval should be escalated.</Description>
  </Variable>
  <Variable initializer="both" name="workItemEscalationStyle">
    <Description>drives the escalation behavior. Can be:
      none: No reminders and no escalations at all - default
      both: Issue reminders and escalations according to the config if no config is given, defaults are used
      escalation: do escalations only
      reminder: do reminders only</Description>
  </Variable>
  <Variable initializer="Normal" input="true" name="workItemPriority">
    <Description>The String version of a WorkItem.Priority. This variable is
      used to set the priority on all of the workitems generated
      as part of this workflow and also set on the IdentityRequest
      object.</Description>
  </Variable>
  <Variable initializer="10" input="true" name="workItemHoursTillExpiration"/>
  <Variable initializer="Work Item Reminder" input="true" name="workItemReminderTemplate">
    <Description>The email template that should be used when sending out reminders.</Description>
  </Variable>
  <Variable initializer="Test-WorkItem Escalation Rule" input="true" name="workItemEscalationRule">
    <Description>The rule used to assign a new ownder during escalation.</Description>
  </Variable>
  <Variable initializer="2" input="true" name="workItemMaxReminders">
    <Description>The maximum number of reminder emails that will be sent before we begin the escalation process.</Description>
  </Variable>
  <Variable initializer="true" input="true" name="filterRejects">
    <Description>True to filter rejected items when running in Serial/SerialPoll mode.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="setPreviousApprovalDecisions">
    <Description>True to pre-populate approval decisions from previous approvals.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="clearApprovalDecisions">
    <Description>True to clear all decisions when generating approvals</Description>
  </Variable>
  <Variable initializer="true" input="true" name="dontUpdatePlan">
    <Description>True to skip updating the ProvisioningProject masterPlan when processing approval decisions.</Description>
  </Variable>
  <Variable input="true" name="approvalSet" output="true">
    <Description>ApprovalSet representing the things that were requested and come from
      the master provisioning plan.</Description>
  </Variable>
  <Variable input="true" name="project" output="true">
    <Description>ProvisioningProject which is just a compiled version of the ProvisioningPlan, the 
      master plan will be adjusted when approval decisions are applied and a new 
      revised provisiobion project will be returned.</Description>
  </Variable>
  <Variable input="true" name="plan" output="true">
    <Description>The provisioning plan.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="requireCommentsForApproval">
    <Description>When true we will require comments when an approval item is approved.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="requireCommentsForDenial">
    <Description>When true we will require comments when an approval item is denied.</Description>
  </Variable>
  <Description>Simple approval subrocess introduced into release 6.2 to make
    adding custom approvals easier.  This approval subprocess
    has a configuration form to make it easier to configure
    from the Business Process Editor.</Description>
  <RuleLibraries>
    <Reference class="sailpoint.object.Rule" name="LCM Workflow Library"/>
  </RuleLibraries>
  <Step icon="Start" name="Start" posX="20" posY="22">
    <Transition to="Approval"/>
  </Step>
  <Step icon="Approval" name="Approval" posX="158" posY="22">
    <Approval mode="ref:approvalMode" owner="call:buildCommonApprovals" renderer="lcmWorkItemRenderer.xhtml" send="identityDisplayName,identityName,approvalSet,flow,policyViolations,identityRequestId">
      <AfterScript>
        <Source>
          import sailpoint.workflow.IdentityRequestLibrary;

          import sailpoint.object.ApprovalItem;
          import sailpoint.object.ApprovalSet;
          import sailpoint.object.WorkItem;
          import sailpoint.object.Comment;

          if ( item == null ) 
          return;

          WorkItem.State state = item.getState();
          if(state.equals(WorkItem.State.Expired)){
          List approvalItems = approvalSet.getItems();
          for (ApprovalItem approvalItem : approvalItems) {
          approvalItem.reject();
          List listOfComments = approvalItem.getComments();
          approvalItem.add(new Comment("Auto reject item due to lack of approval", "system"));
          item.addComment("Auto reject item by system due to lack of approval", "system");
          item.setCompletionComments("Auto reject item by system due to lack of approval");
          }
          }

          assimilateWorkItemApprovalSet(wfcontext, item, approvalSet);          
          auditDecisions(item);  
          IdentityRequestLibrary.assimilateWorkItemApprovalSetToIdentityRequest(wfcontext, approvalSet);
        </Source>
      </AfterScript>
      <Arg name="launcher" value="ref:launcher"/>
      <Arg name="workItemDescription" value="ref:workItemDescription"/>
      <Arg name="workItemEscalationRule" value="ref:workItemEscalationRule"/>
      <Arg name="workItemEscalationTemplate" value="ref:workItemEscalationTemplate"/>
      <Arg name="workItemHoursTillExpiration" value="ref:workItemHoursTillExpiration"/>
      <Arg name="workItemHoursTillEscalation" value="ref:workItemHoursTillEscalation"/>
      <Arg name="workItemMaxReminders" value="ref:workItemMaxReminders"/>
      <Arg name="workItemEscalationFrequency" value="ref:workItemEscalationFrequency"/>
      <Arg name="workItemHoursBetweenReminders" value="ref:workItemHoursBetweenReminders"/>
      <Arg name="workItemEscalationStyle" value="ref:workItemEscalationStyle"/>
      <Arg name="workItemIdentityRequestId" value="ref:identityRequestId"/>
      <Arg name="workItemNotificationTemplate" value="ref:approvalEmailTemplate"/>
      <Arg name="workItemPriority" value="ref:workItemPriority"/>
      <Arg name="approvalMode" value="ref:approvalMode"/>
      <Arg name="approvalScheme" value="ref:approvalScheme"/>
      <Arg name="approvalSplitPoint" value="ref:approvalSplitPoint"/>
      <Arg name="clearApprovalDecisions" value="ref:clearApprovalDecisions"/>
      <Arg name="workItemReminderTemplate" value="ref:workItemReminderTemplate"/>
      <Arg name="workItemRequester" value="$(launcher)"/>
      <InterceptorScript>
        <Source>

          import sailpoint.object.Workflow.Approval;
          import sailpoint.object.ApprovalItem;
          import sailpoint.object.ApprovalSet;
          import sailpoint.object.Workflow;
          import sailpoint.object.WorkItem;
          import sailpoint.tools.Util;
          import java.util.Iterator;
          import java.util.ArrayList;
          import java.lang.Boolean;
          import sailpoint.object.Attributes;
          import sailpoint.object.WorkItem;
          import sailpoint.object.Workflow;
          import sailpoint.tools.Util;


          Date expirationDate = new Date();
          if (method != null &amp;&amp; method.equals(Workflow.INTERCEPTOR_OPEN_WORK_ITEM)) {
          if (workflow != null) {
          Attributes configAttrs = item.getAttributes();
          log.error(" configAttrs: " + configAttrs);
          if (configAttrs != null) {
          String hoursTillExpiration = (String) configAttrs.get("workItemHoursTillExpiration");
          log.error(" hoursTillExpiration: " + hoursTillExpiration);
          if (hoursTillExpiration != null) {
          int hoursTillExpirationInt = Util.atoi(hoursTillExpiration);
          if (hoursTillExpirationInt != null &amp;&amp; hoursTillExpirationInt > 0) {
          int minutes = hoursTillExpirationInt * 60;
          Date dateExp = Util.incrementDateByMinutes(new Date(), minutes);
          log.error(" dateExp: " + dateExp);
          if (item != null &amp;&amp; item.getExpirationDate() == null &amp;&amp; context != null
          &amp;&amp; dateExp != null) {
          log.error("Before item.getExpirationDate(): " + item.getExpirationDate());
          item.setExpiration(Util.getEndOfDay(dateExp));
          item.setWakeUpDate(dateExp);
          context.saveObject(item);
          context.commitTransaction();
          log.error("After item.getExpirationDate(): " + item.getExpirationDate());
          }
          }
          }
          }
          }
          }
          // custom step ended

          if (Workflow.INTERCEPTOR_PRE_ASSIMILATION.equals(method)) {
          // promote completion state to Rejected if all items are rejected
          ApprovalSet aset = item.getApprovalSet();
          if (aset != null) {
          List items = aset.getItems();
          if (items != null) {
          int rejectCount = 0;
          for (ApprovalItem item : items) {
          // note that isRejected can't be used since that
          // assumes no answer means rejected
          if (item.getState() == WorkItem.State.Rejected) {
          rejectCount++;
          }
          }
          if (rejectCount == items.size()) {
          item.setState(WorkItem.State.Rejected);
          }
          }
          }
          } else if (Workflow.INTERCEPTOR_START_APPROVAL.equals(method)) {

          ApprovalSet currentSet = approval.getApprovalSet();

          if (currentSet != null &amp;&amp; !Util.isEmpty(currentSet.getItems())) {
          //If filterRejects is true, filter any rejected items in the master ApprovalSet from the currentSet
          if (Boolean.valueOf(filterRejects)) {
          filterRejectsFromApprovalSet(approvalSet, currentSet);
          }

          //We've filtered all items from the approval set
          if (Util.isEmpty(currentSet.getItems())) {
          //Complete the approval if it contains no ApprovalItems
          approval.setComplete(true);
          } else {

          if (Boolean.valueOf(setPreviousApprovalDecisions)) {
          // If setPreviousApprovalDecisions is enabled, set the decision
          // on the items to that of the global item.
          setPreviousDecisionsOnApprovalSet(approvalSet, currentSet);
          }
          }
          }

          } else if (Workflow.INTERCEPTOR_END_APPROVAL.equals(method)) {
          // Owner children approvals need to propagate the rejection state if all children are rejected
          Approval parentApp = approval.getParent();
          // Never relay the state to the root approval
          // If we don't have an approvalSet, must be a container approval
          if (parentApp != null &amp;&amp; approval.getApprovalSet() == null) {
          boolean completeAndRejected = false;
          for (Approval child : Util.safeIterable(approval.getChildren())) {
          if (child.isComplete() &amp;&amp; child.getState() == WorkItem.State.Rejected) {
          completeAndRejected = true;
          } else {
          completeAndRejected = false;
          break;
          }
          }
          //If all children complete and rejected, set the status on the parent approval
          if (completeAndRejected) {
          approval.setState(WorkItem.State.Rejected);
          }
          }
          } else if (Workflow.INTERCEPTOR_OPEN_WORK_ITEM.equals(method)) {
          import sailpoint.workflow.IdentityRequestLibrary;

          //Sync IdentityRequestItems with the WorkItem
          IdentityRequestLibrary.assimilateWorkItemApprovalSetToIdentityRequest(wfcontext, item.getApprovalSet(), false);
          }

        </Source>
      </InterceptorScript>
    </Approval>
    <Transition to="Process Approval Decisions" when="script:(step.getApproval() != null &amp;&amp; step.getApproval().containsApprovalItems())"/>
    <Transition to="end"/>
  </Step>
  <Step action="call:processApprovalDecisions" icon="Task" name="Process Approval Decisions" posX="420" resultVariable="project">
    <Arg name="disableAudit" value="true"/>
    <Arg name="dontUpdatePlan" value="ref:dontUpdatePlan"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="recompilePlan" value="true"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="plan" value="ref:plan"/>
    <Transition to="end"/>
  </Step>
  <Step icon="Stop" name="end" posX="420" posY="225"/>
</Workflow>

Make sure that all five arguments are correctly passed to the Approval step. For example, based on the configAttrs output in your logs, I noticed that workItemNotificationTemplate is not set, and workItemExpirationTemplate is missing entirely.

These five arguments are essential for your use case, so you must ensure they are either:

  • Passed as static values directly in the Approval step, or
  • Initialize with values as workflow variables for all 5 of them.

Hi @harishabn

I missed one important variable: workItemHoursTillEscalation. I’ve updated the configuration to include it now.

To clarify:

  • The first four arguments are related to reminders.
  • The last two are for expiration.

Make sure to pass all six variables and test the workflow accordingly. Let me know if you encounter any issues.

Hello @Arpitha1 ,

I’ve tried suggested way but it’s not even creating a expirationdate on WorkItem level.

Do we need to use which varibale “workItemExpirationHours” or “workItemHoursTillExpiration”?

        </Source>
      </AfterScript>
      <Arg name="launcher" value="ref:launcher"/>
      <Arg name="workItemDescription" value="ref:workItemDescription"/>
      <Arg name="workItemEscalationRule" value="ref:workItemEscalationRule"/>
      <Arg name="workItemEscalationTemplate" value="ref:workItemEscalationTemplate"/>
      <Arg name="workItemExpirationHours" value="10"/>
      <Arg name="workItemExpirationTemplate" value="Work Item Assignment Removal"/>
      <Arg name="workItemHoursTillEscalation" value="1"/>
      <Arg name="workItemMaxReminders" value="2"/>
      <Arg name="workItemEscalationFrequency" value="ref:workItemEscalationFrequency"/>
      <Arg name="workItemHoursBetweenReminders" value="1"/>
      <Arg name="workItemEscalationStyle" value="ref:workItemEscalationStyle"/>
      <Arg name="workItemIdentityRequestId" value="ref:identityRequestId"/>
      <Arg name="workItemNotificationTemplate" value="ref:approvalEmailTemplate"/>
      <Arg name="workItemPriority" value="ref:workItemPriority"/>
      <Arg name="approvalMode" value="ref:approvalMode"/>
      <Arg name="approvalScheme" value="ref:approvalScheme"/>
      <Arg name="approvalSplitPoint" value="ref:approvalSplitPoint"/>
      <Arg name="clearApprovalDecisions" value="ref:clearApprovalDecisions"/>
      <Arg name="workItemReminderTemplate" value="Work Item Reminder"/>
      <Arg name="workItemRequester" value="$(launcher)"/>
      <InterceptorScript>
        <Source>

Hi @harishabn

I was able to reproduce the issue locally. I vaguely recall using an alternative method to set the expiry date and wake-up date in the interceptor script a while ago—similar to what you’re trying now. However, it seems that in the current version, the wake-up date might not be picked up by system when we set via the interceptor script. I’ll confirm this once I explore more and find a reliable alternative.

In the meantime, there’s another approach you can try: use an escalationRule. In the rule, return null if the wake-up date is more than 10 hours ahead, or return the current owner otherwise. Be sure to specify the rule name in the workItemEscalationRule.

I’ll also continue to look into other potential alternatives.

Thanks for checking!

I am doing something like below but still things are getting expired below the mentioned timeframe.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule  language="beanshell" name="Test-WorkItem Escalation Rule" type="Workflow">
  <Description>A rule used by a Workflow to determine a step action or variable value.

    Note that an Attributes map of all variables from the current WorkflowContext, merged with the arguments from the Step, is also passed into the workflow rule.</Description>
  <Signature returnType="Object">
    <Inputs>
      <Argument name="log" type="org.apache.commons.logging.Log">
        <Description>
          The log object associated with the SailPointContext.
        </Description>
      </Argument>
      <Argument name="context" type="sailpoint.api.SailPointContext">
        <Description>
          A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
        </Description>
      </Argument>
      <Argument name="wfcontext">
        <Description>
          The current WorkflowContext.
        </Description>
      </Argument>
      <Argument name="handler">
        <Description>
          The workflow handler associated with the current WorkflowContext.
        </Description>
      </Argument>
      <Argument name="workflow">
        <Description>
          The current Workflow definition.
        </Description>
      </Argument>
      <Argument name="step">
        <Description>
          The current Step.
        </Description>
      </Argument>
      <Argument name="approval">
        <Description>
          The current Approval.
        </Description>
      </Argument>
      <Argument name="item">
        <Description>
          The WorkItem being processed.
        </Description>
      </Argument>
    </Inputs>
    <Returns>
      <Argument name="Object">
        <Description>
          The result of the workflow rule; dependent on the rule itself.
        </Description>
      </Argument>
    </Returns>
  </Signature>
  <Source>
  import java.util.Date;
  import java.util.List;
  import java.util.concurrent.TimeUnit;
  import sailpoint.object.WorkItem;
  import sailpoint.object.ApprovalItem;
  import sailpoint.object.ApprovalSet;
  import sailpoint.tools.GeneralException;

  log.error("Test-WorkItem Escalation Rule Starts Here ::");

  if (item != null) {
    log.error("Test-WorkItem Escalation Rule 70::"+item);

    Date wakeUpDate = item.getWakeUpDate();

    if(wakeUpDate != null){      
      log.error("Test-WorkItem Escalation Rule 86::"+wakeUpDate);  

      Date now = new Date();      
      long diffMillis = now.getTime() - wakeUpDate.getTime();
      long diffInHours = TimeUnit.MILLISECONDS.toHours(diffMillis);

      if (diffInHours > 10) {
        return null;
        log.info("WorkItem expired due to no action.");
      }
    }
  }
  </Source>
</Rule>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.