Page 2 of 2

Re: Apply Latest Exchange Rates

PostPosted: Thu Apr 01, 2021 11:22 am
by Mike.Sheen
It doesn't do anything.

1. Because it was not enabled
2. Because there are no forms on the forms tab - by looking at your code it looks like maybe the creditor cheque / eft payment form is supposed to be there? But you have a method "PurchaseInvoiceForm_Toolbar_ToolClick".

Can you provide a plugin which all I need to do is import it and follow some steps to reproduce the problem?

AERP-EFTUI.png

Re: Apply Latest Exchange Rates

PostPosted: Thu Apr 01, 2021 1:16 pm
by pricerc
Apologies, I am a bit distracted today (on a completely different project). And it's easy to forget things you haven't done in a while...

This one should work a bit better.

Re: Apply Latest Exchange Rates

PostPosted: Thu Apr 01, 2021 5:13 pm
by Mike.Sheen
Thanks for the plugin.

I'm not seeing anything that I'd call abnormally slow. Our demo data doesn't have 250 invoices outstanding for payment, so I couldn't see any issue when trying with demo data... so I tried on a customers data with 2,701 invoices outstanding and the update function your plugin had processed 250 of those after about 10 seconds.

I'm assuming your customer is reporting something much slower than that?

There's some crufty goings on in that area of the software and could be improved upon - we'd have to log an improvement for a service release to get that done - but I really would like a set of data I can run on and see the issue, because to me 10 seconds to do 250 invoices isn't, in my opinion, something that I would classify as a problem.

So, if you get onto the support roundabout and upload a copy of some data which has the issue, and also mention how long the customer is reporting it to take.

Thanks

Re: Apply Latest Exchange Rates

PostPosted: Thu Apr 01, 2021 5:30 pm
by pricerc
you don't still have the one I uploaded a couple of weeks back?

Re: Apply Latest Exchange Rates

PostPosted: Tue May 04, 2021 11:35 am
by pricerc
So I was finally able to get back to this yesterday.

On my VM, using the customer's data (that you had for DEV-7704), a batch of 268 lines was taking several seconds per line to update.

I run VMware on a Ryzen 7 4800H, running at 3.something GHz. The VM is configured with 8 cores and 16GB of RAM. The single virtual hard drive is hosted on a SATA SSD, although the process is very much CPU-bound. So my VM is at least comparable to a customer's machine. If anything, it's probably got more grunt than most of my customers' systems.

So I don't know why it would be an order of magnitude slower than someone else's database.

Anyhoo.

Last night, I ended up reverse-engineering the code that lives in clsPayLineInvoice.set_CurrencyRateUsedOnBatch, and taking out the bits that don't apply to what I'm doing.

The whole batch now takes about a second.

On looking through the code, is seems, quite reasonably, to be geared towards a user editing a single transaction. It has a bunch of sanity checks, and bubbles changes up to the UI. There is also a bit of escalation in the mix, so that related values are getting updated correctly.

Stepping through the code. The biggest delay seemed to be when setting RecordMode, which triggered the UI update, which in turn causes some further sanity checking on the values so that error messages can be displayed to the user.

Including AutoAllocateCreditsSpecificCreditor also delayed the process a little, but not as much as setting RecordMode.

In my case, most of that doesn't matter - The exchange rate changes are being applied to an otherwise correct batch. So there are no changes happening to the FX values themselves, only to the local currency values that are being affected. This includes: PaymentAmount, OutstandingAmount, PaymentFromBankAmount, PaymentFromCreditsAmount, DiscountedAmount, DiscountAmount, GSTAmount.

So I don't need most of the safety checks. And I don't need any code that changes any of the FX versions of those amounts.

The customer also doesn't have credits in their FX payment batches, and so AutoAllocateCreditsSpecificCreditor doesn't apply to our situation and I was able to leave that out (as a safety check, I disable the change rates button if any exist in the batch).

So for each payment line, I now update the amounts mentioned above, using logic extracted from set_CurrencyRateUsedOnBatch, set_PaymentFXAmount, and set_DiscountedFXAmount.

I do the changes grouped by creditor, and run ReCalculateTotals for each creditor after processing all the lines for the creditor.

After all creditors have been processed, I run CalculateTotals on the payment batch.

Then I call DisplayBatch and CheckEditStatus on the form to refresh it.

Having suppressed most of the standard logic by setting the "IsReading" property on the batch and "SuppressCalculation" on the lines, I did have to resort to reflection to update the batch's ChangeFlag after doing the updates, otherwise the "Save" and "Cancel" buttons didn't get enabled.