Altering BLC Virtual Methods
In a BLC extension, you can override virtual methods defined within a business logic controller (BLC, also referred to as graph). As with the event handlers, you have two options:
- You can define the override method with exactly the same signature—that is, the return value, the name of the method, and all method parameters—as the overridden base virtual method. As a result, the method is added to the queue of all override methods. When the system invokes the base method, all methods in the queue are executed sequentially, from the first to the last one. The lower the level the BLC extension has, the earlier the system invokes the override method.
- You can define the override method with an additional parameter, which
represents the delegate for one of the following:
- The override method with an additional parameter from the extension of the previous level, if such a method exists.
- The base virtual method, if no override methods with additional parameters declared within lower-level extensions exist.
In both cases, you should attach the PXOverrideAttribute to the override method declared within the BLC extension. See the topics below for details.
Override Method That is Added to the Override Method Queue
By declaring an override method with exactly the same signature as the overridden base virtual method, you extend the base method execution. The base BLC method is replaced at run time with the queue of methods that starts with the base BLC method. When the system invokes the base method, all methods in the queue are executed sequentially, from the first to the last one. The lower the level the BLC extension has, the earlier the system invokes the override method. If the system has invoked the base method, you have no option to prevent the override method queue from execution. To prevent the base method executions, see Override Method That Replaces the Original Method below.
Suppose that you need to modify the behavior of the Journal Transactions (GL301000) form.
Open the form and explore its original behavior. Start by adding a new journal entry, selecting an account, and setting the Debit Amount to 2000.00. Then add one more journal entry and select a different account. Notice that the Credit Amount is set by default to 2000.00 to balance the batch, as the following screenshot illustrates.
Suppose that you need this form to work differently, so that if the user first enters
a debit entry, by default, the Credit Amount value is
0.00, and the user must add the required value manually. If the user
first enters a credit entry, the Debit Amount value should
also be 0.00 by default, so that the user must enter the needed value. You
can implement this behavior in the PopulateSubDescr method that
you have to override in a BLC extension for the JournalEntry
class.
To select the business logic controller for customization, on the Customization menu, select Inspect Element and click any element on the form, for example, the form area. The system should retrieve the following information that appears in the Element Properties dialog box:
- Business Logic: JournalEntry. The business logic controller that provides the logic for the Journal Transactions form.
Select Select Customization Project dialog box, specify the project to which you want to add the customization item for the business logic controller of the form and click OK.
in the Element Inspector. In theThe Code Editor opens for customization of the business logic code of the form (see the screenshot below). The system generates the BLC extension class in which you can develop the customization code. (See Graph Extensions for details.)
To the BLC extension class for JournalEntry, add the code that is listed below.
[PXOverride]
public void PopulateSubDescr(PXCache sender, GLTran row, bool externalCall)
{
decimal difference = (Base.BatchModule.Current.CuryCreditTotal ?? decimal.Zero)
(Base.BatchModule.Current.CuryDebitTotal ?? decimal.Zero);
if (difference != 0)
{
if (row.CuryCreditAmt == Math.Abs(difference))
{
row.CuryCreditAmt = 0;
}
else if (row.CuryDebitAmt == Math.Abs(difference))
{
row.CuryDebitAmt = 0;
}
}
}
In the code, you override the PopulateSubDescr
method of the
original BLC by adding the new method to the queue of override methods to be
executed. The system invokes the base method first, and then executes the override
method. The override method resets the value of the Credit Amount
or the Debit Amount to 0.00.
Click Save in Code Editor to save the changes.
To view the result of the customization, publish the customization project and open the Journal Transactions (GL301000) form.
Test the modified behavior of Journal Transactions. Add a new journal transaction, select an account, and set the Debit Amount to 2000.00. Then add one more journal transaction and select a different account, and notice that the Credit Amount is set by default to 0.00. You must manually specify the amount for every journal entry to make the batch balanced. Otherwise, you will not be able to save the batch with the Balanced status, and you will see the appropriate error message on the Debit Total box.
Override Method That Replaces the Original Method
The override method with an additional parameter replaces the base BLC virtual method. When the virtual method is invoked, the system invokes the override method with an additional parameter of the highest-level BLC extension. The system passes a link to the override method with an additional parameter from the extension of the previous level, if such a method exists, or to the base virtual method.
public class BaseBLCExt : PXGraphExtension<BaseBLC>
{
[PXOverride]
public int ExecuteInsert(string viewName, IDictionary values, object[] parameters,
Func<int, string, IDictionary, object[]> del)
{
if (del != null)
{
del(viewName, values, parameters)
}
}
}
You can decide whether to call the method pointed to by the delegate. By invoking the base method, you also start the override method queue execution.
Suppose that you need to modify the logic of generating batches on release of Accounts Receivable documents.
For example, open the Invoices and Memos (AR301000) form and explore its original behavior. Create and save an invoice. On the More menu (under Processing), click Remove Hold and then Release. Notice that a new GL batch has been generated by the system while the system releases the invoice. You can see the batch number on the Financial Details tab of the Invoices and Memos form, as the following screenshot shows.
Suppose that you need to prevent generation of batches during release of Accounts
Receivable documents. You can implement the new behavior in the
Persist
method that you have to override in a BLC extension for
the JournalEntry class. In the override method, you need to
handle execution of the Persist
method of the original BLC.
Therefore, you have to implement the override method with an additional parameter,
as described below.
To the BLC extension class for JournalEntry, add the code that is
listed below. For example, you can add the override method to the
JournalEntry_Extension
BLC extension class generated by the
system, as described above in Override Method That is Added to the Override Method Queue.
[PXOverride]
public void Persist(Action del)
{
if (Base.BatchModule.Current != null &&
Base.BatchModule.Cache.GetStatus(Base.BatchModule.Current) == PXEntryStatus.Inserted &&
Base.BatchModule.Current.Module == "AR")
return;
if (del != null)
del();
}
The code modifies the logic so that the system will not invoke the base virtual method if the batch is being generated from accounts receivable; otherwise, the system executes the base business logic.
To view the result of the customization, publish the customization project and open the Invoices and Memos form.
To test the modified behavior of the Invoices and Memos form, add and save a new invoice, and on the More menu (under Processing), click Remove Hold and then Release. Notice that no new GL batch is generated by the system while it releases the invoice. Open the Financial Details tab. No batch number is displayed, as the following screenshot illustrates.