As companies grow and develop, they may find the need to safeguard business processes within their system. Thankfully Acumatica comes with a native full approval suite that can be configured to a company’s specific needs.
For developers, the question that arises next is how to protect custom processes that are developed using the Acumatica Framework and want the same seamless functionality of Acumatica’s built-in system.
This article aims to provide you a path to accomplish this task.
In this case, we will be reviewing the time request page developed by ASI LLC that allows employees to request periods of time off and submit requests for approval. Time requests will then be reviewed per Acumatica’s built-in approval processing and reflect on the employees timecard based on the configuration.
As is common practice when extending or creating new functionality within the Acumatica Framework, we are going to create our own preferences page to handle configurations for our Time Request feature.
The page shown in the image below has a grid listing the entities for approval and a checkbox determining if approvals are enabled for the entities listed within the grid. A numbering sequence field is also defined that will later be utilized by the custom Time Request data entry page.
This class is being implemented as the setup Data-Access-Class for the Time Request functionality; it holds a single field utilized by the approval process TimeRequestApproval
The structure of this DAC mimics Acumaticas EPSetupApproval table in the database and should utilize both IBqlTable and the IAssignedMap interface.
The graph for the setup page is simple and straightforward, referencing two Data-Access-Classes and utilizing a single Event AATimeRequestSetup_FieldUpdated which when triggered will update all corresponding records within the AATimeRequestApproval view.
Data Entry Page
Creation of a data entry page is made more complex with the implementation of approval processes. The completed UI for the Time Request functionality can be seen in the image below. This page allows the creation of a time request by an employee with a detailed hour breakdown of the request. This document can now be taken off hold and submitted for approval.
This will be the standard Acumatica approve and reject actions under the Actions drop down, which we will define later in the article.
The primary Data-Access-Class we are defining for our approvals that enable custom data entry pages is AATimeRequest.
The Data-Access-Class must implement the IAssign interface. This will require including the fields OwnerID and WorkGroupID in the class declaration.
You will need to define the following status values for the status field of your DAC with the corresponding displays as shown below.
“H” – “On Hold”
“P” – “Pending Approval”
“A” – “Approved”
“R” – “Rejected”
We will need to declare two additional bit fields on our Data-Access-Class to keep track of if the record has been approved or rejected by the user. These will will name Approved and Rejected.
This is a non-DB backed field that is populated via graph events during the loading of a record and determines if the current user is a valid approver for the entity.
The graph for our data entry page is defined as AATimeRequestEntry. Though it’s a bit more complex than our setup page, its logic is utilized to update the statuses on the primary Data-Access-Class. This provides additional approval logic, encapsulated in the Acumatica helper classes.
Creating the graph for a custom data entry page with approvals is made less complex thanks to helper classes developed by Acumatica which consolidate logic into easy to use structures.
We will implement the EPApprovalAutomation helper with a view declaration name of Approval and the following arguments :
SourceAssign – Primary DAC
Approved – Primary DAC approved field
Rejected – Primary DAC rejected field
Hold – Primary DAC hold field
SetupApproval – SetupApproval DAC
You will need to create two additional actions as defined below:
Approve – Updates status of the entity to “Approved” and marks the “Approved” flag on the primary DAC as true.
Reject – Updates status of the entity to “Rejected” and marks the “Rejected” flag on the primary DAC as true.
Primary_DAC_RowSelecting – Determine if approvals are enabled, if enabled check that the current user is the set approver and populates IsApprover accordingly.
Primary_DAC_RowSelected – Enables Approve / Reject buttons when an entity goes to Pending Approval as well as disabling header fields except for Hold check-box for when the entity is off hold.
Primary_DAC_FieldUpdated – Sets entity to pending approval when taken off hold, or resets the other status fields when a document is put back on hold.
EPApproval_RowInserting – Used to set additional information on the approval record for the approver.
This additional information may also be populated by adding CacheAttached events in lieu of RowInserting as seen below.
A graph extension will need to be created from the Acumatica approval map maintenance graph EPApprovalMapMaint to allow the custom data entry page to show on the entity type list, implemented with the sample page AA306000 shown below.
Once the extension has been written and the page registered within the instances sitemap, the custom entity will now become available within the Entity Type dropdown list as seen below.
Once all steps above have been completed, you will be able to define an approval map for your custom entity and utilize the approvals process native to the Acumatica framework.
Though the use of advanced Acumatica features in custom pages can at times be daunting, I have tried to show how straightforward it can be by following these simple steps:
- Create a setup page that configures if approvals are active for the custom entity.
- Create a data entry page that utilizes and responds to approval workflows.
- Create an extension of the Acumatica approval mapping page to allow defined custom entities.
With the methodology I outlined for you to implement, you too will be able to easily utilize Acumatica’s built-in approval process for custom data entry pages. This will greatly enhance the protection and auditing capability of important client specific system data – a must have in any modern ERP system.