Acumatica - Method Override Error - acumatica

I tried to override an exisiting method but after i published I get this error.
Attempt by method 'Wrapper.PX.Objects.AR.Cst_ARPaymentEntry.ARPayment_RowSelectedGeneratedWrapper(PX.Objects.AR.ARPaymentEntry, PX.Data.PXCache, PX.Data.PXRowSelectedEventArgs)' to access method 'PX.Objects.AR.ARPaymentEntry_Extension.ARPayment_RowSelected(PX.Data.PXCache, PX.Data.PXRowSelectedEventArgs)' failed.
when I tried to remove the PXOverride attribute no error occured. I'm using 5.10.072 version.
[PXOverride]
protected void ARPayment_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
}

The problem is that you try to override an event handler - not a common virtual method of the BLC. To do this one has to use a different approach. Namely, you need to declare the event handler without the PXOverride attribute, but with an additional argument of type PXRowSelected and then either call it or not based on your internal logic. Here is an example of such a declaration:
protected void ARPayment_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected invokeBaseHandler)
{
/* your custom event handling logic here */
if(/* your custom condition may go here */)
invokeBaseHandler(cache, e);
/* some more of your logic here if needed */
}
Note that if you simply want your handler be executed along with the base one, you don't need the additional argument - simply declare the handler with your code and it will be called after the original handlers.
You may find much more information and explanatiions on this topic in the help article located under Help > Customization > Examples of Functional Customization > Adding or Altering BLC Event Handler in any instance of Acumatica.

Related

Question on Overriding a method in Customization

What if I override a method on a particular screen.
For example: let's say Journal Transactions Screen, I've overridden the method Release(), I've made it to stop Posting Transactions on the General Ledger with that customization applied, when releasing a document on a screen that produces Journal Transaction Documents that also triggers auto-release, will the customization, the overriden method, will apply first?
From what I've seen, extensions are called first followed by base calls.
If you think the call order ambiguity might lead to errors with your specific code in the handler I'd recommend to explicitly declare and call the base method in the overridden method.
Using Acumatica customization project editor is the easiest way to get the declaration syntax down:
That way there's no doubt with the calling order:
public delegate IEnumerable ReleaseDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
// Put your code before calling base
return baseMethod(adapter);
/* Or after calling base
IEnumerable returnValue = baseMethod(adapter);
// put your code to be executed after base here
return returnValue;
*/
}

How to add custom code to the 'Post' action from the GL Post Transactions screen

I need to add custom code to the logic which posts transactions on the GL 'Post Transactions' screen. After going through the T300 documentation and looking at the override of 'Release' to use as an example, I cannot find anything in the 'BatchPost' BLC that remotely resembles a posting process event/method that I can override. Where would I find that logic and what's the best way to add my custom code to the Posting process, batch by batch?
I think the best way to override posting process is to override PX.Objects.GL.PostGraph.PostBatchProc(Batch b, bool createintercompany)
All logic related to posting are located there.
Here is an example:
public class PostGraphExt : PXGraphExtension<PostGraph>
{
public delegate Batch PostBatchProcDelegate(Batch b, bool createintercompany);
[PXOverride]
public virtual void PostBatchProc(Batch b, bool createintercompany, PostBatchProcDelegate baseMethod)
{
//your code here
baseMethod(b, createintercompany);
//or here
}
}

Extend existing event

I need to perform more action after the existing action is performed. For example, After Distribution > Sales Orders > Shipment > Action > Confirm Shipment, I need to populate all tracking numbers into another text box.
Please suggest.
The best thing here in my opinion would be to override the logic of the stock method. That will allow you to add your needed code without touching the base method as well as you being able to validate information before and after the base method is called.
In the case of your example, "Confirm Shipment" action ultimately executes the method "ConfirmShipment" which is defined as below:
public virtual void ConfirmShipment(SOOrderEntry docgraph, SOShipment shiporder)
{
.....
}
In order to customize the logic in here you have a few options.
Create an override method (added to the method queue, base called first then all 'override' methods)
Create an method that calls the stock one first, then your code. - this will in essence "replace" the stock logic but allow you to still call the base method. in doing this, you can run some checks before calling the base.
To do the second you would do the following
Create first the delegate in your code:
public delegate void ConfirmShipmentDelegate(SOOrderEntry docgraph, SOShipment shiporder)
Then define your override method:
[PXOverride]
public virtual void ConfirmShipment(SOOrderEntry docgraph, SOShipment shiporder, ConfirmShipmentDelegate baseMethod = null)
{
// Call our base method first if it exists
if (baseMethod != null)
{
baseMethod(docgraph,shiporder);
}
// Do my stuff here
}
Couple items to note here.
The definition has a third param to our delegate, this allows us to call the stock method and then do further work. It also tells the Acumatica framework our method should take priority over the stock method.
The stock method is called from the baseMethod call in the actual code.
Creating the extension this way allows for upgrades to occur without you having to totally redefine your method every time.
The second method would be just be an override of the stockcode. That is done with the following syntax
[PXOverride]
public virtual void ConfirmShipment(SOOrderEntry docgraph, SOShipment shiporder)
{}
When taking this approach, the stock method is first called, then your override method is called.
both of these would be handled in a graph extension defined as:
public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
Before attempting either, I would look at the articles in the Wiki on PXOverride as they give further examples/situations for these

How to selectively forbid deleting of tasks in SharePoint 2010?

I am new to SharePoint, sorry if answer to my question is obvious.
I want to forbid deleting some tasks for users.
I can use event receiver for my purpose:
public override void ItemDeleting(SPItemEventProperties properties)
{
if (...)
{
properties.ErrorMessage = "The task can not be deleted";
properties.Cancel = true;
}
}
But I can't pass data for checking if I can delete the task.
I've tryed to use
properties.ListItem.Properties["ForbidDeleting"].ToString().Equals("true")
in the receiver's condition but is there any posibility to pass such propterty in the CreateTask invoking method? I've tryed using ExtendedProperties for it, but this approach doesn't work.
....
task.ExtendedProperties["ForbidDeleting"] = "true"
I can create my class for keeping task Guids and it ForbidDeleting property, but I think it is not a solution but workaround.
Could you help me please? How can I set some task properties (in the CreateTask invoking method) and get it in the event receiver. Is there any built in way to do it?
Thank you in advance.
PS: Sorry for my writing. English is not my native language.
You can override another method in your event receiver: ItemAdding. You would set a field that you could use later in the deletion condition:
public override void ItemAdding(SPItemEventProperties properties)
{
// Decide if this task should be deletable.
properties.AfterProperties["ForbidDeleting"] = true;
}
You have to make sure that the boolean ForbidDeleting field exists in the task list; either by using your template to create it or by using a list event receiver to do the same or by doing it manually before you add the first task.
If you want to set the ForbidDeleting flag first after the task (list item) is really (successfully) created you could override ItemAdded but then update the list item explicitly after the change.
--- Ferda
I've found a solution. I have to use code like this in the Event Receiver to retreive extended properties:
Hashtable extendedProperties = SPWorkflowTask.GetExtendedPropertiesAsHashtable(taskItem);
var value = extendedProperties[key].ToString();
Thanks to Alexander: https://sharepoint.stackexchange.com/questions/32341/how-to-selectively-forbid-deleting-of-tasks-in-sharepoint-2010

BluetoothChat synchronized onResume Activity lifecycle method, why?

I'm studying right now the bluetooth Android API, and I ran into the BluetoothChat example.
http://developer.android.com/resources/samples/BluetoothChat/index.html
It contains many errors, first of all the simple fact that it uses API 11 but manifest does not force this minimum API.
Other interesting thing is the use of synchronized keyword on Activity lifecycle methods, like on onResume:
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
Why this keyword is used there? Is there any reasonable explanation, or simply the one who wrote the code didn't know that onResume will be called always by the same thread? Or I miss something?
Thank you in advance!
This seems to be a pretty old question, but here's what I think may be going on:
My guess is that it wants to be careful about when "dialogs" return. The BluetoothChat example uses dialogs (as well as an overlay dialog-like activity) for enabling Bluetooth, enabling discovery, and initiating pairing/connections.
I don't know this for sure but I suspect there was a bug where different threads were returning to the main Activity and caused confusion as to how to handle onResume.
What they probably should have done is synchronize a block on an object and used flags to determine the state. That way the intention, state and functionality are more clear -- and the app knows what it should do in onResume;
something like this maybe:
//class fields
private Object myLockObj = new Object();
private boolean isPausedForPairing = false;
public void onResume()
{
super.onResume();
synchronized (myLockObj)
{
if (isPausedForPairing)
{
//handle a "pairing" onResume
}
}
}
However, due to it being an example app, they may have decided to go with something more simple. Example apps don't always follow convention because the idea is to demonstrate the particular code needed for the example. Sometimes following convention might add a lot of "distracting" code. Whether or not you agree with that is up to you though.

Resources