Hello!
I'd like to make a sales order "validation" class under Dynamics Ax 2009. Validation here means that a procedure of this class will check if all the fields on SalesTable and SalesLine tables are completed according to the current business logic just before posting an invoice based on this sales order. The class will be on the user layer, because it will be changed probably once in a month or two, as business logic changes, and I don't want to bring the whole SalesOrder form to user layer.
I thought that the procedure will be triggered by the OnClick event of buttonUpdateInvoice (SalesTable form \ Table group \ ButtonsHeader button group \ ButtonHeaderUpdate menu button). But I am unsure what kind of parameters should I pass to this class:
- should I pass SalesTable and SalesLine tables as parameters? This way I could even make small modifications on some values if needed.
- should I pass the SalesTable form itself as an argument?
- should I pass the SalesID of the order as paramater? This way I cannot make any modifications on the order, because they won't be visible for the caller.
I tried to pass SalesTable and SalesLine tables, but I'm facing two problems (probably they are related to each other) with this solution:
- the grid of SalesLine table on the form gets refreshed while looping through the table with while select, and this slows down the process
- the while select loop becomes infinite, because after the last record is reached instead of exiting the loop it starts over again from the first record.
My code:
void clicked() //here I call the procedure { ValidatorClass validator; ; validator = new ValidatorClass(); if ( !ValidatorClass.ValidateOrder( salesTable, salesLine ) ) { return; }
...
//the validator procedure: boolean ValidateOrder(SalesTable salesTable, SalesLine salesLine) { boolean ret; int i; ; ret = false; i = 0; while select salesLine { i++; info ( strFmt ( "%1. %2 > %3", salesLine.LineNum, salesLine.RecId, salesLine.ItemId ) ); } ret = true; return ret; }
Passing only the SalesID of the sales order would be the easiest, but this way I will need to query again all the needed values from both tables, and this affects performance. I thought I should use the already queried tables instead, if possible.
I tried to pass the form itself as argument, but got stuck when I tried to access the form's datasources, and loop them, because I don't know how to do it:
void clicked() { ValidatorClass validator; Args args = new Args(); ; //V1 args.caller(element.form()); validator = new ValidatorClass(); if ( !validator.CheckOrder(args) ) { return; } ...
boolean CheckOrder(Args args) { FormDataSource formDataSource; FormRun frm; SalesLine salesLine; ; frm = args.caller(); formDataSource = frm.dataSource(1); salesLine = formDataSource.getFirst(); //here's my error while (salesLine) { info ( strFmt ( "%1. %2 > %3", salesLine.LineNum, salesLine.RecId, salesLine.ItemId ) ); salesLine = formDataSource.getNext(); } return true; }
So my question is, which solution would be closest to best practices, or what other ways would you suggest?
Thank you!
*This post is locked for comments
Yes, you might be right.
Yes, I could use, but implies much work and attention on both sides. This is why we wanted to bring our code in a separate class.
Thanks!
Currently we are making only new functionalities, and try to avoid modifying existing modules of AX, because we are still getting modifications from our vendor. Everything that they send to us is on the VAR layer. Everything we make is on USER layer. If we both would modify the same objects than only our versions would be visible, because our version is on the higher layer. So we asked our vendor, to make a small modification on the necessary objects that will call our class before posting an invoice based on sales orders. This way we can make any modifications on our class without conflicting objects on different layers.
Everything that our vendor makes for us takes more time. This is the main reason, why we want to make these validations in house.
Hi!
I have wait with the validation of the order till invoice posting because:
- this is the moment when I can be sure, that the order is entered completely, and no additional data will be introduced
- this is the moment when I can process the order as a whole.
For example we are using supplementary items. The calculation of these items should be done when all the lines of the order are introduced. In some cases users forget to do this. And there are other fields which have to be completed only if some conditions are met on SalesTable and SalesLine too. Basically I need to check if the order may be invoiced.
Thanks!
Hi!
Thank you for your suggestion. ValidateWrite is triggered just before the record gets saved. Unfortunately this is not the moment, when I have to verify the order. The best timing is just before an invoice is posted based on the order, because at this point we know, that the order won't be completed with further salesline records. An order can be saved without certain fields completed, but may not be invoiced without them.
Thanks!
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,253 Super User 2024 Season 2
Martin Dráb 230,188 Most Valuable Professional
nmaenpaa 101,156