Solved

Call Void action for Checks and Payment item


Userlevel 4
Badge +2

Hi,

I need to add to my application logic that will Void Checks and Payments items which have “closed” state

When I try to do this programmatically via this code

I get error in this event, which is called when I try to call Void action 

This event is located in this path : C:\Program Files\Acumatica ERP\AcumaticaDB_new\App_Data\CodeRepository\PX.Objects\AP\APPaymentEntry.cs

The reason why I get object reference in this event is that NewValue filed is null and can’t look from which place we transfer PXFieldVerifyingEventArgs object to this event, because thought all call stack from my code to this Class I receive these errors

So I can’t investigate from which place null is coming to the event

Besides, this is Acumatica code, change it in any way will be bad idea, maybe there is something that must be added in my code and will help to fix object reference in the event.

The version of Acumatica is 2021R2

Thanks in advance.

icon

Best answer by markusray17 6 July 2022, 00:00

View original

42 replies

Userlevel 6
Badge +5

You are trying to view the source of the call stack for the Acumatica code which you don’t really need to do. The call stack will show the method calls leading up to the error. Attempting to inspect the source of the method calls won’t work unless you are decompiling Acumatica code. 

Presumably you already checked that the field isn’t null on the APAdjust object so something would have to be setting it to null. You can put a debug point on the DAC setter and then look at the call stack to determine where it is getting set to null. You could also create your own event and intercept it there(again looking at the call stack).

I would also verify that manually triggering the action isn’t causing the same error. That would indicate that something is going wrong when you are initiating the graph before calling the action.

Also I’m probably repeating myself but Voiding and Reversing the Application are not the same thing. Reversing applications will re-open the payment but not void it. Voiding the payment will reverse applications as well as cancel the payment. You are saying you want to void the payment yet you are calling ReverseApplication above. 

Userlevel 4
Badge +2

You are trying to view the source of the call stack for the Acumatica code which you don’t really need to do. The call stack will show the method calls leading up to the error. Attempting to inspect the source of the method calls won’t work unless you are decompiling Acumatica code. 

Presumably you already checked that the field isn’t null on the APAdjust object so something would have to be setting it to null. You can put a debug point on the DAC setter and then look at the call stack to determine where it is getting set to null. You could also create your own event and intercept it there(again looking at the call stack).

I would also verify that manually triggering the action isn’t causing the same error. That would indicate that something is going wrong when you are initiating the graph before calling the action.

Also I’m probably repeating myself but Voiding and Reversing the Application are not the same thing. Reversing applications will re-open the payment but not void it. Voiding the payment will reverse applications as well as cancel the payment. You are saying you want to void the payment yet you are calling ReverseApplication above. 

Hi @markusray17 

Thanks for detailed description 

I need to clarify this moment, that you mentioned in last paragraph - “Voiding and Reversing the Application are not the same thing”.

The goal that I am trying to achieve is to implement the cancelation of releasing of the payment.

I need to process case in which the payment was mistakenly released, it means that I return it back as it was before the release. Which action is suitable for it reverse or void ? I think that reverseApplication should work for that.

According to this part : “you can put a debug point on the DAC setter and then look at the call stack to determine where it is getting set to null.” what is DAC ?, I did not understand what I should do

Userlevel 6
Badge +5

You can’t turn a payment back to before it was released. You would need to void it and re-create it in that scenario, once it goes from Balanced → Open you can’t reverse that. Reversing Applications will open the payment back up by creating reversing applications, but the payment will still be released(Open status).  

DAC refers to Data Access Class which in this case would be the APAdjust class. I would strongly caution you to go through the training, at least the quickstart (T190). It’s a little dangerous to write and publish code based customizations if you don’t know the fundamentals of the platform. 

Also just a quick thought if you just need to either reverse applications or void AP payments an import scenario might be an easier solution. 

Userlevel 4
Badge +2

You can’t turn a payment back to before it was released. You would need to void it and re-create it in that scenario, once it goes from Balanced → Open you can’t reverse that. Reversing Applications will open the payment back up by creating reversing applications, but the payment will still be released(Open status).  

DAC refers to Data Access Class which in this case would be the APAdjust class. I would strongly caution you to go through the training, at least the quickstart (T190). It’s a little dangerous to write and publish code based customizations if you don’t know the fundamentals of the platform. 

Also just a quick thought if you just need to either reverse applications or void AP payments an import scenario might be an easier solution. 

@markusray17 

So for result that I described, I will need to use Void Action and after that make it open after it will be balanced, according to your first paragraph, right ?

I tried to make Void and then remove from hold in this way

B

But the error remains the same and in same place

Userlevel 6
Badge +5

No, you can’t make a released payment balanced. You would have to void it and then create a new payment. 

Userlevel 4
Badge +2

No, you can’t make a released payment balanced. You would have to void it and then create a new payment. 

Previously you wrote the following 

All the same I need to use ReverseApplication ?

Maybe it is not possible to implement what I need.

I have released Payment and I need this payment to bring back as it was before released. Make it Open.

Is it possible to implement ? What appropriate way will be for it, using Void or reverseApplication ?

Userlevel 6
Badge +5

The payment is released when it goes from Balanced to Open, after that the “Release” action is actually releasing applications not the Payment itself(which is already released). You cannot bring a payment back to the Balanced state once it is released but you can “reverse” applications(essentially adding a negative application) to re open a closed payment.

It sounds like when you are saying “released payment” you mean an application was released that closed the payment and you just need to reverse that to re-open the payment. In which case ReverseApplication would do that. 

Presumably you have a local dev environment setup for testing so I would recommend trying the actions in the UI and seeing how they work before you start coding. 

Userlevel 4
Badge +2

Okay “revers applications seems to be what I need

The problem which is appeared can be caused by Acumatica environment or inappropriate algorithm of reverseApplication action call ?

I am looking at places from which null is coming to NewValue field 

It looks like something wrong with Acumatica instance or something missed in code sample that you shared with me, because I do not do anything additional during this process

                 string referenceNbr = "001991";
                APPaymentEntry graph = PXGraph.CreateInstance<APPaymentEntry>();
                graph.Document.Current = graph.Document.Search<APPayment.refNbr>(referenceNbr);                      graph.APPost.Current = graph.APPost.SelectSingle();
                graph.reverseApplication.Press();

Is there something that missed at that part of code ?

It is strange that calling of the action became so hard 

Userlevel 6
Badge +5

Do it manually in the UI and verify whether you are getting the same error or not. I would also double check your Currency settings.

It appears to be happening in the newly created adjustment so you can step through the ReverseApplication method in APPaymentEntry.cs to figure out what line is resulting in the null value. I would suspect it is happening in the Adjustments.Update call after the AdjgCuryInfoID value is set. As I said before if you set a breakpoint on the DAC field’s setter method it will trigger anytime a value is set so you can find exactly what code is setting the value to null. 

Userlevel 4
Badge +2

Hi @markusray17 

I checked manually in UI reverse application action and it worked.

You were right, the error happens after this part as you mentioned : “I would suspect it is happening in the Adjustments.Update call after the AdjgCuryInfoID value is set.”

You suggested me that DAC for my case will be APAdjust class, where exactly I should set a breakpoint ? I do not know which field is responsible for putting null to NewValue field 

Userlevel 6
Badge +5

Its the AdjdCuryRate field on the APAdjust DAC(in the APAdjust.cs file).

If it works in the UI I would recommend double checking the surrounding code. Make sure you are getting the correct APPayment set as current and the correct APAdjust set. Assuming those are correct calling the action from code should be almost identical to clicking the button in the UI. 

Also where exactly are you executing this code from?

Userlevel 4
Badge +2

Hi @markusray17 

Unfortunately debug does not show value for AdjdCuryRate : Cannot obtain value of the local variable or argument because it is not available at this instruction pointer, possibly because it has been optimized away.

I need to clarify this part : “Make sure you are getting the correct APPayment set as current and the correct APAdjust set.”

The Payment with which I am working is APPayment type, but what APAdjust type is responsible for ? I did not use this entity in my code which I sent.

The code is invoked via custom screen, with the help of which the payments will be reverted automatically (that is what I am trying to achieve)

After Adjustments.Update call this field was assigned to 1 

I tried  this with another payment and code worked without any errors

However item was not affected , it does not change anything 

 

Userlevel 6
Badge +5

You have to release the document afterwards, reverse application just creates the reversal under Documents to Apply. APAdjust is the adjustment that you are reversing(APPost is the view where you are setting the current APAdjust). 

You don’t really need to see the actual value, you just need to figure out what methods are changing the value(visible in the call stack).

Userlevel 4
Badge +2

Hi @markusray17 

I mistakenly sent Payments and Application item instead of Checks and Payment.

With Checks and Payments same error happens for any item in same place.

However, when I do it in UI it successfully changed it from “Closed” state to “Open”

you wrote in previous response the following : “You don’t really need to see the actual value, you just need to figure out what methods are changing the value(visible in the call stack).”

1)The first method where its value changed is this

2)The second

and after that I receive error in that event 

 

Userlevel 4
Badge +2

You have to release the document afterwards, reverse application just creates the reversal under Documents to Apply. APAdjust is the adjustment that you are reversing(APPost is the view where you are setting the current APAdjust). 

You don’t really need to see the actual value, you just need to figure out what methods are changing the value(visible in the call stack).

Hi @markusray17 

I mistakenly sent Payments and Application item instead of Checks and Payment.

With Checks and Payments same error happens for any item in same place.

However, when I do it in UI it successfully changed it from “Closed” state to “Open”

you wrote in previous response the following : “You don’t really need to see the actual value, you just need to figure out what methods are changing the value(visible in the call stack).”

1)The first method where its value changed is this

2)The second

and after that I receive error in that event 

 

Userlevel 4
Badge +2

You have to release the document afterwards, reverse application just creates the reversal under Documents to Apply. APAdjust is the adjustment that you are reversing(APPost is the view where you are setting the current APAdjust). 

You don’t really need to see the actual value, you just need to figure out what methods are changing the value(visible in the call stack).

Hi @markusray17 

I found that I missed that instruction that you provided previously

[GRAPH NAME].[VIEW NAME].Current = [Record]

I do not know what must be in VIEW NAME and Record

Please, suggest what I should add here

Userlevel 6
Badge +5

You already added that

graph.APPost.Current = graph.APPost.SelectSingle();

The Update and Insert methods aren’t changing the values, they raise events and event handlers modify the values. One of those event handlers is setting that value to null during:

Adjustments.Update(adj);

What I am saying is using the call stack and debugger you can see the method chain when that value is set to null and then figure out which event handler is the cause and why. 

That being said if it is working in the UI for the same record the issue is likely with the surrounding code or the context from which you are invoking the action. 

Userlevel 4
Badge +2

You already added that

graph.APPost.Current = graph.APPost.SelectSingle();

The Update and Insert methods aren’t changing the values, they raise events and event handlers modify the values. One of those event handlers is setting that value to null during:

Adjustments.Update(adj);

What I am saying is using the call stack and debugger you can see the method chain when that value is set to null and then figure out which event handler is the cause and why. 

That being said if it is working in the UI for the same record the issue is likely with the surrounding code or the context from which you are invoking the action. 

Hi @markusray17 

Previously, I checked in UI reverse application and it worked,

As I discovered now, it returns Closed state to Open, but it does not allow to save it in UI with this error 

How payment should be modified to resolve this error ?

Can this be the cause of my problem ?

Userlevel 6
Badge +5

That would seem to be a bug on 21R2, I’d check with Acumatica and see what they say. I was able to replicate it on my 21R2 instance. The same issue doesn’t seem to be happening with ARPayments. I’m guessing there is an issue with how they are checking for documents being out of balance for APPayments.

 

It could be related to your issue, but I would expect to get the same error via code as in the UI. 

Userlevel 4
Badge +2

That would seem to be a bug on 21R2, I’d check with Acumatica and see what they say. I was able to replicate it on my 21R2 instance. The same issue doesn’t seem to be happening with ARPayments. I’m guessing there is an issue with how they are checking for documents being out of balance for APPayments.

 

It could be related to your issue, but I would expect to get the same error via code as in the UI. 

Thank you for the response, I will write to Acumatica and let you know, when I get the response

Userlevel 4
Badge +2

Hi @markusray17 

The required logic has changed a little bit.

I need to use Void instead of Reverse Application.

I checked Void work in Acumatica UI for payment and it worked with no troubles, item was successfully saved.

However in code I receive same error in same place

Previously you advised to check this place : Adjustments.Update(adj);

Concerning Reverse Application it was right, the error appeared right after that place

However with Void the debug does not come here

Concerning that part : “using the call stack and debugger you can see the method chain when that value is set to null and then figure out which event handler is the cause and why.”

I cant see exactly from which place error comes due to Acumatica files are not available to view

I can only check the call stack, but it is not informative

This is my code

string referenceNbr = "001991";
 APPaymentEntry graph = PXGraph.CreateInstance<APPaymentEntry>();
  graph.Document.Current = graph.Document.Search<APPayment.refNbr>(referenceNbr);               
  graph.voidCheck.Press();

Userlevel 6
Badge +5

I was able to reproduce your issue locally and just debugged it myself.

            APPaymentEntry graph = PXGraph.CreateInstance<APPaymentEntry>();

graph.Document.Current = graph.Document.Search<APPayment.refNbr>(YourRefNbr);

graph.UnattendedMode = false;

try
{
graph.voidCheck.Press();
}
catch (PXRedirectRequiredException) { }


graph.release.Press();

So I had to set the UnattendedMode to false on the graph after instantiating it. There is an event handler that doesn’t set the value of the AdjdCuryRate field if the UnattendedMode is set to true(it interprets that as an internal call).

You will also want to catch the redirect exception and then release the document afterwards. 

Userlevel 4
Badge +2

Hi @markusray17 

Thanks for provided explanation and code sample.

Void action executes without any troubles, but during graph.release.Press(); row debug throws exception

it gives error at this location

Unfortunately the the debugger cant show current apdoc status value

What should I change in order to solve this ?

Userlevel 6
Badge +5

What is the status of the ap payment you are trying to void?

Userlevel 4
Badge +2

What is the status of the ap payment you are trying to void?

@markusray17 

“Closed” state

 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved