Three level cascade approval process

Goal:

We need to have 3 level of approval process for the Financial department.

  • 1st approver will be the users direct manager (we are storing this info into user preferencies)
  • 2nd approver will be the role from Financial department
  • 3rd and final approve will be the role from Financial department

After all approvals, ticket will continue to common workflow process.

Nice to have: Log of approval process.

Predispositions:

  1. We have information about user direct manager stored in User Properties (key manager, value name.surname@domain.com).
  2. There will occur a situations, that direct manager will not be logged into Jira before, so solution must handle this.
  3. Direct managers will not have Service Desk license. 

Solution:

  1. Create two new Project Roles (2nd Approver and 3rd Approver).
  2. Get and store user managers email from User Property to Custom Field.
  3. This will be used in "Reset Approval" transition, so proper manager can assign approval himself via transition. 
  4. Use JMWE plugin with scripted Conditions, Post Functions.
  5. Customize mails sent from Jira to be more user friendly.
  6. Protect "Waiting for Approval" status from editing.

Details for Resolution notification:

New Custom fields:

NameTypeScreen
Managers e-mailSingle line textFinancial View Screen
1st ApproverSingle User PickerFinancial View Screen
2nd ApproverSingle User PickerFinancial View Screen
3rd ApproverSingle User PickerFinancial View Screen
Rejected bySingle User PickerFinancial View Screen

Reused Custom fields:

NameTypeScreen
Manager (Supervisor)Single User PickerFinancial View Screen

Workflow:

Waiting for Approval
  1. ADDED Property jira.issue.editable=false

Create issue

Post functions
  1. ADDED The value of field Manager (Superior)will be set to the value of the user's managerproperty.
  2. ADDED The value of field Managers e-mail will be set to the value of the user's managerproperty.
  3. ADDED The value of field Assigneewill be set to the value of the user's managerproperty.
  4. ADDED A notification email will be sent with the following contents:

    The following email template will be used: Blank Template

    Subject
    New credit/debit card request from <%= issue.get("reporter")?.displayName %>.
    Text Body
    Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. 
    This request was received from <%= issue.get("reporter")?.displayName %>. 
    I am assigning this request based on the automation rules to <%= issue.get("assignee")?.displayName %>. 
    The status of issue is <%= issue.get("status")?.name %>, so please take a care about the approval process.
    Request URL: <%= issue.getServiceDeskUrl() %>
    HTML Body
    <p>Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. </p>
    <p>This request was received from <b> <%= issue.get("reporter")?.displayName %>.</b> </p>
    <p>I am assigning this request based on the automation rules to<b> <%= issue.get("assignee")?.displayName %>.</b></p> 
    <p>The status of issue is <b><%= issue.get("status")?.name %></b>, so please take a care about the approval process.</p>
    <p><a href="<%= issue.getServiceDeskUrl() %>">View request in Jira</a></p>


    Recipients:

    Issue members:
    • Assignee

    Run as user jira@//CUSTOMER//.com.

    Run this post-function only if the following condition is true:

    issue.get("customfield_14018")?.isActive()
  5. ADDED A notification email will be sent with the following contents:

    The following email template will be used: Blank Template

    Subject
    New credit/debit card request from <%= issue.get("reporter")?.displayName %>.
    Text Body
    Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. 
    This request was received from <%= issue.get("reporter")?.displayName %>. 
    I can not assign this request based on the automation rules, because you never log-in to Jira. 
    The status of issue is <%= issue.get("status")?.name %>, so please take a care about the approval process.
    Request URL: <%= issue.getServiceDeskUrl() %>
    ATTENTION! As you never log into Jira before, you have to hit the "Restart Approval" button, to gain proper permission for the approval!
    HTML Body
    <p>Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. </p>
    <p>This request was received from <b> <%= issue.get("reporter")?.displayName %>.</b> </p>
    <p>I can not assign this request based on the automation rules, because you never log-in to Jira.</b></p> 
    <p>The status of issue is <b><%= issue.get("status")?.name %></b>, so please take a care about the approval process.</p>
    <p><a href="<%= issue.getServiceDeskUrl() %>">View request in Jira</a></p>
    <p><b>ATTENTION!</b> As you never log into Jira before, you have to hit the <b>"Restart Approval"</b> button, to gain proper permission for the approval!</p>


    Recipients:

    Email addresses:
    <%= issue.getAsString("customfield_14372") %>

    Run as user jira@//CUSTOMER//.com.

    Run this post-function only if the following condition is true:

    issue.get("customfield_14018") == null
  6. REMOVED Fire a Issue Created event that can be processed by the listeners.
  7. ADDED A comment will be added to the issue with the following Groovy Template: WARNING! This user does NOT have any manager set in his properties. The approval process can not be started. Notifications will be sent. Run as user jira@//CUSTOMER//.com.

    Run this post-function only if the following condition is true:

    !issue.get("customfield_14372")

Restart Approval

Conditions
  1. ADDED Scripted groovy condition 

    !issue.get("customfield_14018")
Post functions
  1. ADDED The value of field Assignee of the current issue will be set to the value of the following Groovy Expression:
    issue.get("customfield_14372")
    (replacing existing values).
  2. ADDED The value of field Manager (Superior) of the current issue will be set to the value of the following Groovy Expression:
    issue.get("customfield_14372")
    (replacing existing values).

1st Approve

Conditions
  1. Only the assignee of the issue can execute this transition.
  2. Not having 2nd approval (Groovy script)

    !issue.get("customfield_14367")
  3. Is manager of Reporter also current user? (Groovy script)

    issue.get("customfield_14018")?.name == currentUser.name
Post functions
  1. ADDED Assign the issue to the default user from the Financial 2nd Approver role.
  2. ADDED The value of field Financial 1st Approverof the current issue will be set to the value of the following Groovy Expression:
    currentUser
    (replacing existing values).
  3. ADDED A notification email will be sent with the following contents:

    The following email template will be used: Blank Template

    Subject
    New credit/debit card request from <%= issue.get("reporter")?.displayName %>.
    Text Body
    Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. 
    This request was received from <%= issue.get("reporter")?.displayName %>. 
    I am assigning this request based on the automation rules to <%= issue.get("assignee")?.displayName %>. 
    The status of issue is <%= issue.get("status")?.name %>, so please take a care about the approval process.
    Request URL: <%= issue.getUrl() %>
    HTML Body
    <p>Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. </p>
    <p>This request was received from <b> <%= issue.get("reporter")?.displayName %>.</b> </p>
    <p>I am assigning this request based on the automation rules to<b> <%= issue.get("assignee")?.displayName %>.</b></p> 
    <p>The status of issue is <b><%= issue.get("status")?.name %></b>, so please take a care about the approval process.</p>
    <p><a href="<%= issue.getUrl() %>">View request in Jira</a></p>


    Recipients:

    Issue members:
    • Assignee

    Run as user jira@//CUSTOMER//.com.

  4. REMOVED Fire a General Eventevent that can be processed by the listeners.

2nd Approve

Conditions
  1. Only the assigneeof the issue can execute this transition.
  2. Only users in project role Financial 2nd Approvercan execute this transition.
Post functions
  1. ADDED Assign the issue to the default user from the Financial 3rd Approver role.
  2. ADDED The value of field Financial 2st Approverof the current issue will be set to the value of the following Groovy Expression:
    currentUser
    (replacing existing values).
  3. ADDED A notification email will be sent with the following contents:

    The following email template will be used: Blank Template

    Subject
    New credit/debit card request from <%= issue.get("reporter")?.displayName %>.
    Text Body
    Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. 
    This request was received from <%= issue.get("reporter")?.displayName %>. 
    I am assigning this request based on the automation rules to <%= issue.get("assignee")?.displayName %>. 
    The status of issue is <%= issue.get("status")?.name %>, so please take a care about the approval process.
    Request URL: <%= issue.getUrl() %>
    HTML Body
    <p>Hi. I am the //CUSTOMER// Jira Bot and I just got this request for credit/debit card approval. </p>
    <p>This request was received from <b> <%= issue.get("reporter")?.displayName %>.</b> </p>
    <p>I am assigning this request based on the automation rules to<b> <%= issue.get("assignee")?.displayName %>.</b></p> 
    <p>The status of issue is <b><%= issue.get("status")?.name %></b>, so please take a care about the approval process.</p>
    <p><a href="<%= issue.getUrl() %>">View request in Jira</a></p>


    Recipients:

    Issue members:
    • Assignee

    Run as user jira@//CUSTOMER//.com.

  4. REMOVED Fire a General Event event that can be processed by the listeners.

3rd Approve

Conditions
  1. Only the assignee of the issue can execute this transition.
  2. Only users in project role FIN 3rd Approver can execute this transition.
Validators
  1. If a value is not provided during the transition for field(s) Financial 1st Approver, Financial 2st Approver,show the following error: 1st and 2nd approval must be done before final one!
Post functions
  1. ADDED The value of field Financial 3st Approverof the current issue will be set to the value of the following Groovy Expression:
    currentUser
    (replacing existing values).