Processing Forms: Processing Delegate

If you use a workflow action for processing, you specify the workflow action that the processing form should use by invoking the SetProcessWorkflowAction<>() method, as described in Processing Forms: General Information. For a processing form that does not use workflow actions for processing, you specify the processing delegate, as described in this topic.

Processing Delegate

For a forms that does not use workflow actions for processing, in the graph constructor, you define the processing method as the processing delegate for the data view, as the following code shows.

public SalesOrderProcess()
{
    SalesOrders.SetProcessDelegate<SalesOrderEntry>(
        delegate(SalesOrderEntry graph, SalesOrder order) 
        {
            graph.Clear();
            graph.ApproveOrder(order, true);
        });
}
For a filtered processing form, you can specify a processing method as the processing delegate for the data view in the RowSelected event handler for the data access class (DAC) used in the PXFilter data view. This approach can be used to pass the selected filter parameters to the processing method. If a processing form contains a form area with a control to select a method to process the details, the usage of the RowSelected event handler for the main DAC of the primary view is the only way to specify the selected method as the processing delegate in the code.

Invocation of a Non-Static Processing Method

To invoke the non-static method on a processing form, in the graph constructor or the RowSelected event handler, you set the method as the processing delegate for the data view by using the generic SetProcessDelegate<Graph>() method, as shown in the following code.

public class SalesOrderProcess : PXGraph<SalesOrderProcess>
{
    public PXProcessing<SalesOrder> SalesOrders;
    ...
    public SalesOrderProcess()
    {
        // Set the processing delegate for a data view of 
        // the PXProcessing or derived type
        SalesOrders.SetProcessDelegate<SalesOrderEntry>(
            delegate(SalesOrderEntry graph, SalesOrder order) 
        {
            graph.Clear();
            graph.ApproveOrder(order, true);
        });
    }
}

In the SetProcessDelegate<Graph>() method, the processing method matches the following delegate type.

delegate void ProcessItemDelegate<Graph>(Graph graph, Table item)

Based on the ProcessItemDelegate type, you can use the specified graph and item objects within the processing method. When the processing of records is initiated, MYOB Acumatica Framework creates a graph instance of the specified type and invokes the delegate for each data record that should be processed. A single graph instance is used for the processing of all records. Therefore, you have to clear the graph state by calling the Clear() method before the invocation of the processing method within the delegate, as was shown in the code example earlier in this section.

Invocation of a Static Processing Method

To invoke a static method from a processing form, in the graph constructor or the RowSelected event handler, you set the method as the processing delegate for the data view by using the SetProcessDelegate() method, as shown in the code that follows.

public class ReorderProcess : PXGraph<ReorderProcess>
{
    public SelectFrom<ProductReorder>.
        ProcessingView.FilteredBy<ProductFilter> Records;

    public ReorderProcess()
    {
        Records.SetProcessDelegate(Process);
    }
}

In the SetProcessDelegate() method, the processing method matches the following delegate type.

delegate void ProcessListDelegate(List<Table> list, 
    CancellationToken ct);

Based on the delegate type, you can work with the list of processed records of the specified List<Table> type.

When you use a static processing method, you have to manually create a new graph object once and reuse it throughout the whole static method (see the following code).

public class ReorderProcess : PXGraph<ReorderProcess>
{
    ...
    public static void ReorderProducts(List<ProductReorder> products, 
        CancellationToken ct = default)
    {
        // Create a new graph object only once
        ReceiptEntry graph = PXGraph.CreateInstance<ReceiptEntry>();
        // Reorder the list
        List<ProductReorder> productsToProceed = 
            products.OrderBy(item => item.SupplierID).ToList();
        // Process the records
        foreach (ProductReorder product in productsToProceed)
        {
            ct.ThrowIfCancellationRequested();
            graph.Receipts.Insert(doc);
            // Save changes within the created graph object
            graph.Actions.PressSave();
            // Clear the created graph state and reuse the object
            graph.Clear();
        }
    }
}