Tracking issue: https://github.com/Expensify/Expensify/issues/393839
Design doc section: Make sure optimistic Next Steps & report action are set correctly, for “Approve” (old term “Forward”) in NewDot
Goals:
- Set optimistic next steps for approvals, when policy is Control and on Advanced Approval mode
- Specifically new for mid-level approvers
- Need to build basic approval chain from policy
employeeList in order to be able to figure out who should optimistically be the next approval
- Also needs to optimistically add
Approved <total> report action to workspace chat
Background:
We currently generate optimistic Next Steps when approving a report in NewDot here. The current possible next steps are:
- “Finished! No further action required”
- “Next steps: Waiting for you to pay the expenses”
Problem:
There are now more possible cases when a report is getting approved!
When a Control policy has "Advanced Approvals" enabled, there can be multiple "mid-level" approvers. When these members approve the policy, we actually call this "forwarding" - because we "forward" the report to the next person in line. The final approver actually does the "approving".
Solution:
- Build the report's approval chain any time someone approves a report on a Control workspace with advanced approvals enabled
- Note: For v1 we will only consider
submitsTo, forwardsTo, and overLimitForwardsTo. Later, we'll add in rule approvers (tag & category)
- Optimistically add a report action saying
approved <total> even when forwarding the report
Approval Chain Logic:
When building out the approval chain logic, logic should look like this:
- Get policy's
employeeList
- Get report submitter, get their policy data with
employeeList[submitterEmail]
- The first member of the approval chain is the employee's
submitsTo - like submitsToEmail = employeeList[submitterEmail]?.submitsTo ?? policyOwnerEmail
- Next, get the submitsTo person's policy data with
submitsToEmployeeData = employeeList[submitsToEmail]
- From here on, we get the next approver by looking at
forwardsTo, overLimitForwardsTo, and approvalLimit
- If
submitsToEmployeeData has an approvalLimit and overLimitForwardsTo, do this:
- Get the report total
- If the report total is >
approvalLimit, then the next approver in line is the email address in submitsToEmployeeData?.overLimitForwardsTo
- If the report is <=
approvalLimit, then the next approver in line is submitsToEmployeeData?.forwardsTo
- If
submitsToEmployeeData doesn't have either approvalLimit or doesn't have overLimitForwardsTo, the next approver in line is submitsToEmployeeData?.forwardsTo
- Note: If we ever run into a missing approver here (a.k.a. if
submitsToEmployeeData doesn't have a forwardsTo), we're done!
- Now we get the
forwardsTo or overLimitForwardsTo's policy data with forwardsEmployeeData = employeeList[forwardsToEmail]
- Repeat steps 5 & 6 until you either:
- End up with an email address you already added to the approval chain
- Run into some employee's data that doesn't have a
forwardsTo
This looks something like this:

Where $policy->getForwardsTo looks like this:

Examples:
Say, for example, we have this Control employeeList policy setup (with advanced approvals enabled):
Each member's approval chain looks like this:
Tracking issue: https://github.com/Expensify/Expensify/issues/393839
Design doc section: Make sure optimistic Next Steps & report action are set correctly, for “Approve” (old term “Forward”) in NewDot
Goals:
employeeListin order to be able to figure out who should optimistically be the next approvalApproved <total>report action to workspace chatBackground:
We currently generate optimistic Next Steps when approving a report in NewDot here. The current possible next steps are:
Problem:
There are now more possible cases when a report is getting approved!
When a Control policy has "Advanced Approvals" enabled, there can be multiple "mid-level" approvers. When these members approve the policy, we actually call this "forwarding" - because we "forward" the report to the next person in line. The final approver actually does the "approving".
Solution:
submitsTo,forwardsTo, andoverLimitForwardsTo. Later, we'll add in rule approvers (tag & category)approved <total>even when forwarding the reportApproval Chain Logic:
When building out the approval chain logic, logic should look like this:
employeeListemployeeList[submitterEmail]submitsTo- likesubmitsToEmail = employeeList[submitterEmail]?.submitsTo ?? policyOwnerEmailsubmitsToEmployeeData = employeeList[submitsToEmail]forwardsTo,overLimitForwardsTo, andapprovalLimitsubmitsToEmployeeDatahas anapprovalLimitandoverLimitForwardsTo, do this:approvalLimit, then the next approver in line is the email address insubmitsToEmployeeData?.overLimitForwardsToapprovalLimit, then the next approver in line issubmitsToEmployeeData?.forwardsTosubmitsToEmployeeDatadoesn't have eitherapprovalLimitor doesn't haveoverLimitForwardsTo, the next approver in line issubmitsToEmployeeData?.forwardsTosubmitsToEmployeeDatadoesn't have aforwardsTo), we're done!forwardsTooroverLimitForwardsTo's policy data withforwardsEmployeeData = employeeList[forwardsToEmail]forwardsToThis looks something like this:
Where
$policy->getForwardsTolooks like this:Examples:
Say, for example, we have this Control
employeeListpolicy setup (with advanced approvals enabled):submitsToforwardsTooverLimitForwardsToapprovalLimitEach member's approval chain looks like this: