Access Request not Close Even Approval Mode is Seriel

Which IIQ version are you inquiring about?

8.4

Please share any images or screenshots, if relevant.

Hi Sailors,

In my LCM Provisioning and its subprocess, all the approval mode is set to serial, but I found out when the first approval rejected the request, the work item is not automatically close, and it still route to second level approver.

In my ApproveAndProvisionSubprocess, it has an approval assignment rule applied for calculating and assign approver. By right it should not affect the approval mode and it should close after the first approver rejected it.

Wonder is the serial approval mode working that way. Seek for your advice and thanks in advance!

can you please check your provisioning approval subprocess workflow and check for step “Approval” and interceptorScript, and see your logic there??

import sailpoint.object.Workflow;
import sailpoint.object.Workflow.Approval;
import sailpoint.object.Identity;
import sailpoint.object.*;
import sailpoint.workflow.*;
import sailpoint.api.*;
import java.util.*;
import java.util.List;
import sailpoint.tools.xml.XMLObjectFactory;
 
public List calculateApprovalListforMA(ManagedAttribute ma, Identity targetIdentity) {
    List approvalList = new ArrayList();
    
    switch(ma.getAttribute("approvalType")) {
        case "Manager":
            if(targetIdentity.getManager() != null) {
                approvalList.add(targetIdentity.getManager().getName());
            } else {
                approvalList.add("spadmin");
            }
            break;
 
        case "Manager and Second Level Manager":
            if(targetIdentity.getManager() != null) {
                approvalList.add(targetIdentity.getManager().getName());
                if(targetIdentity.getManager().getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else {
                approvalList.add("spadmin");
            }
            break;
 
        case "Defined Approvers":
            if(ma.getAttribute("firstApproverWorkgroup") == null && ma.getAttribute("secondApproverWorkgroup") == null) {
                if(ma.getOwner() != null) {
                    approvalList.add(ma.getOwner().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else if(ma.getAttribute("firstApproverWorkgroup") != null && ma.getAttribute("secondApproverWorkgroup") == null) {
                approvalList.add(ma.getAttribute("firstApproverWorkgroup"));
            } else if(ma.getAttribute("firstApproverWorkgroup") != null && ma.getAttribute("secondApproverWorkgroup") != null) {
                approvalList.add(ma.getAttribute("firstApproverWorkgroup"));
                approvalList.add(ma.getAttribute("secondApproverWorkgroup"));
            } else if(ma.getAttribute("firstApproverWorkgroup") == null && ma.getAttribute("secondApproverWorkgroup") != null) {
                // FIXED: Changed from firstApproverWorkgroup to secondApproverWorkgroup
                approvalList.add(ma.getAttribute("secondApproverWorkgroup"));
            }
            break;
 
        case "Manager and Defined Approvers":
            if(ma.getAttribute("firstApproverWorkgroup") == null && ma.getAttribute("secondApproverWorkgroup") == null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
 
                if(ma.getOwner() != null) {
                    approvalList.add(ma.getOwner().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else if(ma.getAttribute("firstApproverWorkgroup") != null && ma.getAttribute("secondApproverWorkgroup") == null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(ma.getAttribute("firstApproverWorkgroup"));
            } else if(ma.getAttribute("firstApproverWorkgroup") != null && ma.getAttribute("secondApproverWorkgroup") != null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(ma.getAttribute("firstApproverWorkgroup"));
                approvalList.add(ma.getAttribute("secondApproverWorkgroup"));
            } else if(ma.getAttribute("firstApproverWorkgroup") == null && ma.getAttribute("secondApproverWorkgroup") != null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(ma.getAttribute("secondApproverWorkgroup"));
            }
            break;
    }
    return approvalList;
}
 
public List calculateApprovalListforBD(Bundle bd, Identity targetIdentity) {
    List approvalList = new ArrayList();
    
    switch(bd.getAttribute("approvalType")) {
        case "Manager":
            if(targetIdentity.getManager() != null) {
                approvalList.add(targetIdentity.getManager().getName());
            } else {
                approvalList.add("spadmin");
            }
            break;
            
        case "Manager and Second Level Manager":
            if(targetIdentity.getManager() != null) {
                approvalList.add(targetIdentity.getManager().getName());
                if(targetIdentity.getManager().getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else {
                approvalList.add("spadmin");
            }
            break;
            
        case "Defined Approvers":
            if(bd.getAttribute("firstApproverWorkgroup") == null && bd.getAttribute("secondApproverWorkgroup") == null) {
                if(bd.getOwner() != null) {
                    approvalList.add(bd.getOwner().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else if(bd.getAttribute("firstApproverWorkgroup") != null && bd.getAttribute("secondApproverWorkgroup") == null) {
                approvalList.add(bd.getAttribute("firstApproverWorkgroup"));
            } else if(bd.getAttribute("firstApproverWorkgroup") != null && bd.getAttribute("secondApproverWorkgroup") != null) {
                approvalList.add(bd.getAttribute("firstApproverWorkgroup"));
                approvalList.add(bd.getAttribute("secondApproverWorkgroup"));
            } else if(bd.getAttribute("firstApproverWorkgroup") == null && bd.getAttribute("secondApproverWorkgroup") != null) {
                // FIXED: Changed from firstApproverWorkgroup to secondApproverWorkgroup
                approvalList.add(bd.getAttribute("secondApproverWorkgroup"));
            }
            break;
            
        case "Manager and Defined Approvers":
            if(bd.getAttribute("firstApproverWorkgroup") == null && bd.getAttribute("secondApproverWorkgroup") == null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
 
                if(bd.getOwner() != null) {
                    approvalList.add(bd.getOwner().getName());
                } else {
                    approvalList.add("spadmin");
                }
            } else if(bd.getAttribute("firstApproverWorkgroup") != null && bd.getAttribute("secondApproverWorkgroup") == null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(bd.getAttribute("firstApproverWorkgroup"));
            } else if(bd.getAttribute("firstApproverWorkgroup") != null && bd.getAttribute("secondApproverWorkgroup") != null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(bd.getAttribute("firstApproverWorkgroup"));
                approvalList.add(bd.getAttribute("secondApproverWorkgroup"));
            } else if(bd.getAttribute("firstApproverWorkgroup") == null && bd.getAttribute("secondApproverWorkgroup") != null) {
                if(targetIdentity.getManager() != null) {
                    approvalList.add(targetIdentity.getManager().getName());
                } else {
                    approvalList.add("spadmin");
                }
                approvalList.add(bd.getAttribute("secondApproverWorkgroup"));
            }
            break;
    }
    return approvalList;
}
 
// MAIN PROCESSING SECTION - COMPLETELY RESTRUCTURED
List allNewApprovals = new ArrayList();
Identity targetUser = context.getObjectByName(Identity.class, identityName);
 
if(!approvalSet.isEmpty()) {
    List<ApprovalItem> approvalItemList = approvalSet.getItems();
    System.out.println("Total approval items to process: " + approvalItemList.size());
    
    // Process each approval item separately
    for (ApprovalItem approvalItem : approvalItemList) {
        System.out.println("Processing approval item: " + approvalItem.getDisplayableValue() +
                         ", Operation: " + approvalItem.getAttribute("operation"));
        
        List approvalChain = new ArrayList();
        
        // Determine approval chain for this specific item
        if(approvalItem.getAttribute("operation").startsWith("Entitlement")) {
            ManagedAttribute entitlement = context.getObjectById(ManagedAttribute.class, approvalItem.getAttribute("id"));
            
            if(entitlement.getAttribute().equals("workgroups.name")) {
                // Special handling for workgroups
                approvalChain.add(context.getObjectByName(Identity.class, entitlement.getValue()).getName());
            } else if(entitlement.getAttribute("approvalType") != null) {
                // Use custom approval logic
                approvalChain = calculateApprovalListforMA(entitlement, targetUser);
            } else {
                // Default to entitlement owner
                approvalChain.add(entitlement.getOwner().getName());
            }
        } else if(approvalItem.getAttribute("operation").startsWith("Role")) {
            Bundle role = context.getObjectById(Bundle.class, approvalItem.getAttribute("id"));
            
            if(role.getAttribute("approvalType") != null) {
                // Use custom approval logic
                approvalChain = calculateApprovalListforBD(role, targetUser);
            } else {
                // Default to role owner
                approvalChain.add(role.getOwner().getName());
            }
        }
        
        System.out.println("Approval chain for " + approvalItem.getDisplayableValue() + ": " + approvalChain);
        
        // Create approvals for this item's approval chain
        if (approvals != null && !approvalChain.isEmpty()) {
            for (Approval approval : approvals) {
                if (approval != null) {
                    for (String delegate : approvalChain) {
                        try {
                            Identity targetIdentity = context.getObjectByName(Identity.class, identityName);
                            Approval newApproval = XMLObjectFactory.getInstance().clone(approval.getChildren().get(0), context);
                            
                            // Create a new approval set with only this specific item
                            ApprovalSet newApprovalSet = new ApprovalSet();
                            ApprovalItem newApprovalItem = XMLObjectFactory.getInstance().clone(approvalItem, context);
                            newApprovalSet.add(newApprovalItem);
                            newApproval.setApprovalSet(newApprovalSet);
                            
                            newApproval.setOwner(delegate);
                            
                            // Set descriptive approval description
                            String itemDescription = newApprovalItem.getDisplayableValue();
                            String operation = newApprovalItem.getAttribute("operation");
                            newApproval.setDescription(operation + " Request \"" + itemDescription +
                                                     "\" for " + targetIdentity.getDisplayableName() +
                                                     " - approval assigned to " + delegate);
                            
                            allNewApprovals.add(newApproval);
                            System.out.println("Created approval for " + delegate + " - Item: " + itemDescription);
                            
                        } catch (Exception e) {
                            System.out.println("Error creating approval for delegate " + delegate + ": " + e.getMessage());
                        }
                    }
                }
            }
        }
    }
}
 
System.out.println("Total approvals created: " + allNewApprovals.size());
return allNewApprovals;
 

can you check this one please " provisioning approval subprocess workflow and check for step “Approval” and interceptorScript, and see your logic there??"

I think the code, which you have attached is approve assignment rule, which is not required.

Hi @naveenkumar3 ,

Nope, no script is the step mentioned.

" provisioning approval subprocess workflow and check for step “Approval”

Can you check from the debug page and check for InterceptorScript??

Hi @naveenkumar3 ,

Found this in provisioning approval subprocess workflow, below is the interceptor script

<InterceptorScript>
        <Source>
import sailpoint.api.ObjectUtil;
import sailpoint.api.Provisioner;
import sailpoint.api.SailPointContext; 
import sailpoint.object.ApprovalItem;
import sailpoint.object.EmailTemplate;
import sailpoint.object.Identity;
import sailpoint.object.NotificationConfig;
import sailpoint.object.NotificationConfig.ReminderConfig;
import sailpoint.object.NotificationConfig.EscalationConfig;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.object.Workflow; 
import sailpoint.object.WorkItem; 
import sailpoint.object.ApprovalSet;
import sailpoint.object.Bundle;
import sailpoint.object.ManagedAttribute;
import sailpoint.tools.GeneralException;
import sailpoint.tools.Util;
import sailpoint.workflow.IdentityRequestLibrary;
import org.apache.log4j.Logger;
import sailpoint.object.Workflow.Approval;
import java.util.*;
import java.util.List;
 
List approvalItems = approvalSet.getItems();
String approvalType = null;
 
switch (method) {
    case workflow.INTERCEPTOR_OPEN_WORK_ITEM:
        int maxExpirationDays = 7;
        List managerConfigs = new ArrayList();
        boolean isTwoTier = false;
 
        for (ApprovalItem approvalItem : approvalItems) {
            if (approvalItem == null) {
                log.debug("Encountered null ApprovalItem");
                continue;
            }
            String operation = approvalItem.getOperation();
            Object id = approvalItem.getAttribute("id");
            log.debug("Attribute 'id' for ApprovalItem: " + id);
            Object operationAttr = approvalItem.getAttribute("operation");
            if (id != null &amp;&amp; operationAttr != null) {
                String operationStr = operationAttr.toString();
                if (operationStr.startsWith("Role")) {
                    Bundle role = context.getObjectById(Bundle.class, id.toString());
                    if (role != null) {
                        approvalType = (String) role.getAttribute("approvalType");
                        log.debug("Role approvalType for ID " + id + ": " + (approvalType != null ? approvalType : "null"));
                    } else {
                        log.debug("Role not found for ID: " + id);
                    }
                } else if (operationStr.startsWith("Entitlement")) {
                    ManagedAttribute entitlement = context.getObjectById(ManagedAttribute.class, id.toString());
                    if (entitlement != null) {
                        approvalType = (String) entitlement.getAttribute("approvalType");
                        log.debug("Entitlement approvalType for ID " + id + ": " + (approvalType != null ? approvalType : "null"));
                    } else {
                        log.debug("Entitlement not found for ID: " + id);
                    }
                } else {
                    log.debug("Operation does not start with 'Role' or 'Entitlement': " + operationStr);
                }
            } else {
                log.debug("ID or operation attribute is null for ApprovalItem: ID=" + id + ", OperationAttr=" + operationAttr);
            }
 
            // Update approvalType and maxExpirationDays based on priority
            if (approvalType != null) {
                if ("Manager and Second Level Manager".equals(approvalType) || "Manager and Defined Approvers".equals(approvalType)) {
                    isTwoTier = true;
                    maxExpirationDays = 7;
                } else if ("Defined Approvers".equals(approvalType) || "Manager".equals(approvalType)) {
                    maxExpirationDays = 14;
                }
            }
        }
 
        log.debug("Here is the current approvalType: " + approvalType);
        int expirationDays = maxExpirationDays;
        long twoDayMillis = 2 * 24 * 60 * 60 * 1000;
 
        if (isTwoTier) {
            for (int day = 2; day &lt;= 6; day += 2) {
                ReminderConfig reminderConfig = new ReminderConfig();
                reminderConfig.setEnabled(true);
                long milliValue = day * 24L * 60 * 60 * 1000;
                reminderConfig.setMillis(milliValue);
                reminderConfig.setFrequency(twoDayMillis); // Repeat every 2 days
                reminderConfig.setEmailTemplateName("DMTM - LCM Identity Update Approval Reminder");
                managerConfigs.add(reminderConfig);
            }
        } else if ("Defined Approvers".equals(approvalType) || "Manager".equals(approvalType)) {
            for (int day = 2; day &lt;= 12; day += 2) {
                ReminderConfig reminderConfig = new ReminderConfig();
                reminderConfig.setEnabled(true);
                long milliValue = day * 24L * 60 * 60 * 1000;
                reminderConfig.setMillis(milliValue);
                reminderConfig.setFrequency(twoDayMillis);
                reminderConfig.setEmailTemplateName("DMTM - LCM Identity Update Approval Reminder");
                managerConfigs.add(reminderConfig);
            }
        } else {
            for (int day = 2; day &lt;= 6; day += 2) {
                ReminderConfig reminderConfig = new ReminderConfig();
                reminderConfig.setEnabled(true);
                long milliValue = day * 24L * 60 * 60 * 1000;
                reminderConfig.setMillis(milliValue);
                reminderConfig.setFrequency(twoDayMillis); // Repeat every 2 days
                reminderConfig.setEmailTemplateName("DMTM - LCM Identity Update Approval Reminder");
                managerConfigs.add(reminderConfig);
            }
        }
 
        EscalationConfig escalate = new EscalationConfig();
        escalate.setEnabled(true);
        escalate.setEscalationRuleName("DMTM - Escalation Do Nothing"); 
        //escalate.setEmailTemplateName("Alert Notification");
        escalate.setMillis(expirationDays * 24 * 60 * 60 * 1000);
        escalate.setFrequency(twoDayMillis);
        escalate.setMaxReminders(10);
        managerConfigs.add(escalate);
 
        NotificationConfig notifConfig = new NotificationConfig();
        notifConfig.setEnabled(true);
        notifConfig.setRemindersEnabled(true);
        Date currentDate = new Date();
        notifConfig.setStartDate(currentDate);
        long timeinMillis = currentDate.getTime();
        Date laterDate = new Date(timeinMillis + expirationDays * 24 * 60 * 60 * 1000);
        notifConfig.setEndDate(laterDate);
 
        notifConfig.setConfigs(managerConfigs);
        item.setupNotificationConfig(context, null, notifConfig);
        context.saveObject(item);
        context.commitTransaction();
 
        int hoursTillExpirationInt = expirationDays * 24;
        if (hoursTillExpirationInt > 0) {  
            int minutes = hoursTillExpirationInt * 60;  
            Date dateExp = Util.incrementDateByMinutes(new Date(), minutes);   
            if (item != null &amp;&amp; item.getExpirationDate() == null &amp;&amp; dateExp != null) {   
                item.setExpiration(dateExp); 
                Date wakeUpDate = Util.incrementDateByMinutes(new Date(), 2 * 24 * 60);
                item.setWakeUpDate(wakeUpDate);
                context.saveObject(item);   
                context.commitTransaction();  
            }  
        }
        break;
}
</Source>
      </InterceptorScript>

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