Wednesday, 1 February 2017

Approval Workflow Customization

Hi Everyone,

Today I want to share with you one important point about customization of automation approval workflow.

Firs of all please read this article on Stack Overflow to understand how Acumatica Approval works.
But here I would take Purchase Orders screen as example, because there we already have automation workflow configured.

In the article below, you may notices that all approval logic is encapsulated into the special Data View - EPApprovalAutomation. On the Purchase Orders form it is designed like this:
[PXViewName(Messages.Approval)]
public EPApprovalAutomation<POOrder, POOrder.approved, POOrder.rejected, POOrder.hold, POSetupApproval> Approval;

EPApprovalAutomation is just a class with multiple virtual methods that you can override and customize. 
So we can create our own approval workflow and define it in the graph or graph extension.
public class MyAppprovalAutomation
: EPApprovalAutomation<POOrder, POOrder.approved, POOrder.rejected, POOrder.hold,
       POSetupApproval>
{ }

public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
       #region DataViews
       [PXViewName(Messages.Approval)]
       public MyApprovalAutomation Approval;
       #endregion
}

However, here we have one issue.
To encapsulate business logic, data view automatically subscribe for some events during initialization:
automatically subscribe acumatica
But because we have added new Approval Automation view, all events will be subscribed twice. That may lead to sending notifications twice or assigning approve twice.
Approval Automation view acumatica
To fix that issue, we need to unsubscribe base events manually. For this task we can use Initialize event of extension. But because some events are private, we have to use reflection.

public override void Initialize()
{
       Type type = Base.Approval.GetType();
       MethodInfo mi = type.GetMethod("Approved_FieldUpdated",
 System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                  Base.FieldUpdated.RemoveHandler(BqlCommand.GetItemType(typeof(POOrder.approved)),
       typeof(POOrder.approved).Name,
       (PXFieldUpdated)mi.CreateDelegate(typeof(PXFieldUpdated), Base.Approval));
}
After that, only ours events would be executes.

Full code snippet is here:

Have a nice development!

3 comments:

Unknown said...

Hi Sergey,

My name is Andrey, I'm from Acronis and I'm implementing Acumatica for T&E.

You topic is somewhat related to the issue I'm having, I hope you can help me resolve it.

We have approval workflow with the possibility of multiple rejections and resubmits of expense claims.

When I implemented automation notifications to send "You claim has been approved" notification using Status as a tracked field on Fields tab, I found that such notification emails are sent only once - on the first approval. If employee resubmits the claim and it is approved again, 2nd and all subsequent notifications are not sent.

As we understood, this happened because of the automation notification logic which tracks changes in the fields defined on the Fields tab by comparing them to the previous values. If there was at least one occurrence when tracked field obtained certain value, it will never be considered as modified again.

To overcome that we:
1) Implemented custom field usrApprovalCntr, which is incremented in EPApproval_RowUpdated any time approval is done.
2) Changed "You claim has been approved" automation notifications to track field usrApprovalCntr in Fields tab and use Status = "Approved" as a condition.

This actually works fine except one strange behavior - if somebody sets value Post to Period field on already approved claim and saves it, "You claim has been approved" notification is triggered again - although no changes in Status or usrApprovalCntr occurred. The same happens in some other cases, for example if somebody would accidentally click SUBMIT button in Expense Claims grid with approved claim selected.

Why does this happen? Is there a way to instruct automation notification engine to ignore any other updates in the claim which do not related to the tracked fields and conditions?

Sergey Marenich said...

Hi Andrey,
Actually I have faced the issues you had described several time in my experience. And I personally think it is imperfection in Acumatica that should be fixed.
Could I ask you please create a support case for that issue, so I can have an argument to dev team that it is real issue and other face it too. Than we need to fix it.
In parallel I'll try to debug it and see if I find the reason why period triggers notification.
Thank you very much in advance.

Unknown said...

Hi Sergey,
This is Andrey again. I’ve created support request for Acumatica. Will see what they will reply