Extension of Scan Components: To Add a New Scan Command for an Existing Form
This activity will walk you through the implementation of a new scan command for an existing MYOB Acumatica form.
Story
Suppose that you need to add the ability to cancel physical inventory count on the Scan and Count (IN305020) form.
Process Overview
You will add an additional scan command component. For details about the implementation of scan commands, see Barcode Scan Commands: General Information. You will then override the DecorateScanMode method by using the PXOverride attribute, and in this method, you will intercept the CreateCommands method. You will use the ByAppend override strategy, which does not affect the original component.
System Preparation
Before you begin performing the step of this activity, do the following:
- Prepare an MYOB Acumatica instance by performing the Test Instance: To Deploy an Instance prerequisite activity.
- Enable the following features on the Enable/Disable Features (CS100000) form, where they are in the Inventory and Order Management
group of features:
- Multiple Warehouse Locations
- Warehouse Management
- Fulfillment
- Inventory Operations
Step: Adding a Scan Command
To a scan command, do the following:
- In the
PhoneRepairShop_Code
Visual Studio project, add a reference to the PX.BarcodeProcessing.dll file. - Create the
CancelPIAbility
class, and make itpublic
. - Add the
using
directives shown in the following code to the file.using System; using PX.Data; using PX.BarcodeProcessing; using PX.Common; using PX.Objects.IN; using PX.Objects.IN.WMS;
- Make the class an extension of the
PX.Objects.IN.WMS.INScanCount scan mode
class.
public class CancelPIAbility : INScanCount.ScanExtension { }
- Define a ScanCommand component, and implement its
members.
public class CancelPIAbility : INScanCount.ScanExtension { public sealed class CancelPICommand : INScanCount.ScanCommand { // The code to be scanned to execute the command public override string Code => "CANCEL*PI"; // The name of the PXAction instance that is created for the command public override string ButtonName => "ScanCancelPI"; // The display name of the button for the PXAction instance that is created for the command public override string DisplayName => Msg.DisplayName; // The Boolean value that indicates when the command can be executed protected override bool IsEnabled => Basis.DocumentIsEditable; // The logic that is executed for the command protected override bool Process() { var countReview = PXGraph.CreateInstance<INPIReview>(); countReview.PIHeader.Current = countReview.PIHeader.Search<INPIHeader.pIID>(Basis.Document.PIID); countReview.cancelPI.Press(); // Clear the screen Basis.CurrentMode.Reset(fullReset: true); // Inform the user Basis.ReportInfo(Msg.Success); return true; } [PXLocalizable] public abstract class Msg { public const string DisplayName = "Cancel Count"; public const string Success = "Physical inventory count has been canceled."; } } }
- In the
CancelPIAbility
class, override the DecorateScanMode method.public class CancelPIAbility : INScanCount.ScanExtension { [PXOverride] public virtual ScanMode<INScanCount> DecorateScanMode( ScanMode<INScanCount> original, Func<ScanMode<INScanCount>, ScanMode<INScanCount>> base_DecorateScanMode) { return base_DecorateScanMode(original); } ... }
- Search for the mode you are looking for, and patch its
CreateCommands
method via the interception functionality.public class CancelPIAbility : INScanCount.ScanExtension { [PXOverride] public virtual ScanMode<INScanCount> DecorateScanMode( ScanMode<INScanCount> original, Func<ScanMode<INScanCount>, ScanMode<INScanCount>> base_DecorateScanMode) { var mode = base_DecorateScanMode(original); if (mode is INScanCount.CountMode countMode) { countMode .Intercept.CreateCommands.ByAppend(() => { // Though you have only one new command to append, you must wrap it in an array. return new[] { new CancelPICommand() }; }); } return mode; } ... }
- Optional: Extract the exact patching logic to a separate virtual method of the
extension so that you can suppress this patch in the
future.
public class CancelPIAbility : INScanCount.ScanExtension { [PXOverride] public virtual ScanMode<INScanCount> DecorateScanMode( ScanMode<INScanCount> original, Func<ScanMode<INScanCount>, ScanMode<INScanCount>> base_DecorateScanMode) { var mode = base_DecorateScanMode(original); if (mode is INScanCount.CountMode countMode) PatchCountMode(countMode); return mode; } protected virtual void PatchCountMode(INScanCount.CountMode countMode) { countMode .Intercept.CreateCommands.ByAppend(() => { return new[] { new CancelPICommand() }; }); } ... }
- Fix or suppress the PX1016 error that is displayed by Acuminator.
- Build the project, and test the new command on the Scan and Count (IN305020) form.