Asynchronous Operations: To Implement an Asynchronous Operation
The following activity will walk you through the process of implementing a long-running action and executing it asynchronously.
Story
Suppose that you need to create an action that allows users to validate the prices for the repair items added in the table on the Repair Items tab of the Services and Prices (RS203000) form, in the PhoneRepairShop customization project. Suppose that you need to validate the prices by using an external service. This action can potentially take a long time to finish its execution and hence it should be executed asynchronously. You need to define an action in the graph of the form and configure the associated button (on the table toolbar). You need to define the code that will be used to perform the validation of the prices and execute this code asynchronously by using the PXLongOperation.StartOperation method.
Process Overview
- Adding the
IsPriceValidatedfield, which you will add to the database during system preparation, to theRSSVRepairItemDAC, and updating the ASPX file of the Services and Prices (RS203000) form. This will make this field visible as the Price Validated column, in the table on the Repair Items tab of the form. - Defining the logic needed to validate the prices of the repair items in a
method called
ValidatePrices, implementing theValidateItemPricesaction and setting it up the to run theValidatePricesmethod asynchronously, and creating the associated Validate Prices button on the table toolbar. - Testing the Validate Prices button and the underlying action.
System Preparation
Before you begin performing the steps of this activity, do the following:
- Prepare an MYOB Acumatica instance by performing the Test Instance for Customization: To Deploy an Instance with Custom Maintenance and Data Entry Forms prerequisite activity.
- In SQL Server Management Studio, execute the
T230_AddColumn_RSSVRepairItem.sql script.Tip: The script is provided in the Customization\T230\SourceFiles\DBScripts folder, which you have downloaded from Acumatica GitHub.
- To update the customization project, do the following:
- In the Customization Project Editor, open the PhoneRepairShop project.
- In the navigation pane, click Database Scripts.
- On the More menu of the Database Scripts page, which opens, click Reload from Database.
Step 1: Updating the Services and Prices (RS203000) form to Display the Price Validated Column and the Validate Prices Button
To add the IsPriceValidated field to the
RSSVRepairItem DAC and update the corresponding ASPX file to
respectively show the Price Validated column in the table,
and the Validate Prices button on the table toolbar of the
Repair Items tab, do the following:
- Add the following code to the
RSSVRepairItem.csfile after theBasePricefield definition.#region IsPriceValidated [PXDBBool] [PXDefault(false)] [PXUIField(DisplayName = "Price Validated", Enabled = false)] public virtual bool? IsPriceValidated { get; set; } public abstract class isPriceValidated : PX.Data.BQL.BqlBool.Field<isPriceValidated> { } #endregionNote that the field is set to be disabled on the UI because this field is meant to be updated by an external service. The field is set to
falseby default. - In the RS203000.aspx file, do the following:
- Add the following code inside the
<Columns>tag of the<px:PXGridLevel DataMember="RepairItems" >tag.<px:PXGridColumn Type="CheckBox" DataField="IsPriceValidated" Width="100" > </px:PXGridColumn>This code has added the Price Validated column, which is represented by the
IsPriceValidatedDAC field, to the table on the Repair Items tab. - Add the following code in the
<px:PXTabItem Text="Repair Items">tag after theLevelsclosing tag.<ActionBar> <CustomItems> <px:PXToolBarButton Text="ValidateItemPrices"> <AutoCallBack Command="ValidateItemPrices" Target="ds" /> </px:PXToolBarButton> </CustomItems> </ActionBar>In this code, you have defined an action bar on the table toolbar of the Repair Items tab and have added the Validate Prices button to it.
- Add the following code inside the
- Save your changes.
Step 2: Defining the Logic Used to Validate Prices
You should define the method in which the repair items prices are validated, and then
you can call this method in the PXLongOperation.StartOperation
method.
Since the objective of this activity is to execute a long-running operation
asynchronously by using the PXLongOperation.StartOperation
method, you will not be focusing on the specifics of the logic of the long-running
operation itself —that is, you will not be writing the code for connecting to
an actual external service, making a request and parsing the received result.
Instead, you will use the Thread.Sleep() method to create a delay
in the execution of the method to simulate connecting to an external service. You
will simply pass the repair items to the ValidatePrices method and
set the IsPriceValidated field for each repair item to
true. This will change the state of the check box in the
Price Validated column of the Repair
Items tab to be selected for each repair item and simulate a
successful validation from an external service.
To define the method in which the repair items prices are validated, do the following:
- Add the following
usingdirectives to theRSSVRepairPriceMaint.csfile (if they have not been added yet).using System.Collections; using System.Collections.Generic; using System.Threading;
Tip: Instead of adding theusingdirectives manually, you can add them with the help of the Quick Actions and Refactorings feature of Visual Studio after you define the method in the next instruction. - Add the following static method,
ValidatePrices, to theRSSVRepairPriceMaintgraph. TheValidatePricesmethod validates the repair items prices for the selected record on the Services and Prices (RS203000) form.private static void ValidatePrices(RSSVRepairPrice repairPriceItem) { // Create an instance of the RSSVRepairPriceMaint graph // and set the Current property of its RepairPrices view. var priceMaint = PXGraph.CreateInstance<RSSVRepairPriceMaint>(); priceMaint.RepairPrices.Current = priceMaint.RepairPrices. Search<RSSVRepairPrice.serviceID, RSSVRepairPrice.deviceID> (repairPriceItem.ServiceID, repairPriceItem.DeviceID); // Set a delay to mimic connecting to an external service to validate the // repair item prices. // In a real world scenario, you would connect to an actual external // service and make an API request to validate the prices for // the repair items. Thread.Sleep(3000); // Update the Price Validated field for each repair item on // the Repair Items tab: // Here we are assuming that the validation was successful from the // external service and are setting IsPriceValidated to true for // each repair item. foreach (RSSVRepairItem item in priceMaint.RepairItems.Select()) { // Set IsPriceValidated to true for each repair item. item.IsPriceValidated = true; // Update the cache with the above change for each repair item. priceMaint.RepairItems.Update(item); } // Trigger the Save action to save the changes stored in the cache // to the database. priceMaint.Actions.PressSave(); }
In the method above, you first create an instance of the
RSSVRepairPriceMaint graph. You then set the current property
of the RepairPrices view of this graph instance to the parameter of
type RSSVRepairPrice that was passed into the
ValidatePrices method.
You then use the Thread.Sleep(3000) method call to pause the
execution of the method to simulate a long-running operation that is connecting to
an external service. You then loop through each repair item of the selected record
on the Services and Prices form and set its IsPriceValidated
property to true to indicate that its price has been validated.
Finally, you update the cache and save the changes to the database.
Step 3: Defining the ValidateItemPrices Action
The ValidateItemPrices action defines the underlying action for the
Validate Prices button on the table toolbar of the
Repair Items tab, and invokes the
PXLongOperation.StartOperation method that executes the
ValidatePrices method added in Step 2, asynchronously.
To define the ValidateItemPrices action, add the following code to
the RSSVRepairPriceMaint graph.
#region Actions
public PXAction<RSSVRepairPrice> ValidateItemPrices = null!;
[PXButton(DisplayOnMainToolbar = false, CommitChanges = true)]
[PXUIField(DisplayName = "Validate Prices", Enabled = true)]
protected virtual IEnumerable validateItemPrices(PXAdapter adapter)
{
// Populate a local list variable.
List<RSSVRepairPrice> list = new List<RSSVRepairPrice>();
foreach (RSSVRepairPrice repairItemPrice in adapter.Get<RSSVRepairPrice>())
{
list.Add(repairItemPrice);
}
// Trigger the Save action to save changes in the database.
Actions.PressSave();
var repairPriceItem = RepairPrices.Current;
// Execute the ValidatePrices method asynchronously by
// using PXLongOperation.StartOperation
PXLongOperation.StartOperation(this, () => ValidatePrices(repairPriceItem));
// Return the local list variable.
return list;
}
#endregion
In the ValidateItemPrices method, you compose a list of services and
prices by using the adapter.Get method, and invoke the
Actions.PressSave action. Because the return of the
adapter.Get method does not include data that has not been
saved on the form, by calling the PressSave method, you update
the records in the composed list.
Then you use the PXLongOperation.StartOperation() method to validate
the prices of the repair items on the Repair Items tab for
the record that is selected on the Services and Prices (RS203000) form. You do this
by invoking the ValidatePrices method within the method that you
pass to StartOperation().
Finally, you return the list of services and prices.
Step 4: Testing the Validate Prices Button and the Associated Action
To test the Validate Prices button and the underlying action, do the following:
- Rebuild the
PhoneRepairShop_Codeproject in Visual Studio, and publish the customization project in the Customization Project Editor. - In MYOB Acumatica, open the Services and Prices (RS203000) form.
- Open any services and prices record —that is, any services
and prices record that does not have the check box selected in the
Price Validated column for any of the repair items on
the Repair Items tab.
Notice that the Validate Prices button is available on the table toolbar of the Repair Items tab.
- On the table toolbar, click Validate Prices.
A notification appears indicating the status of the processing, as shown in the following screenshot.
Figure 1. Validation of the prices of repair items 
When the process is complete, the check box for each repair item is selected in the Price Validated column of the Repair Items tab, as shown in the following screenshot.
Figure 2. Update of the Price Validated column 
