Under some circumstances we it’s not possible to design a regular solution with for example with event handlers or COC. For the ReturnTable form, we had a requirement to default the ReturnReasonCodeId for the RetailSalesLine datasource with that of the SalesTable datasource. Part of the requirement was that the defaulting should only performed on client (form) level, via the ReturnTable form and the SalesCopying form, which ruled out EventHandlers of extensions on table level.
At first sight the plan was to build an FormDataSourceEventHandler but this was not a feasible solution as the SalesLine and the RetailSalesLine datasource have a Outer Join relation.
Investigating the code learnt us that a RetailSalesLine buffer record is packed in the method retailPackRetailSalesLine(RetailSalesLine _retailSalesLine) is the best place to build or extension on. In this method we can see that the salesLine field of the buffer get defaulted with the SalesLine.RecId (this.RecId) before packed. We choose to extend this method and add the defaulting for the ReasonCodeId to it, because the writeRetailSalesLine(boolean _forceInsert = false) is not extensible. However we need to take into considerations the requirement which said that this action only should perform if the caller object of this method is the form SalesCopying or form ReturnTable. In both of these forms, Retail salesLine buffers are not available neither are delegates available.
The best way to achieve the requirement to default the RetailSalesLine.ReturnReasonCode with the SalesTable.ReturnReasonCode is using the xSession::xppCallStack() method. This method provides the current stack trace. We create a boolean method which is go through the stack and ticks only true if the desired object are called .
In this particular example we found out that our boolean method should return true if the stack calls objects method canCloseProcess from the SalesCopying form and the method ‘ItemModified’ from the form ReturnTable under the datasource SalesLine.
Example of a stracktrace when we place breakpint at the retailPackRetailSalesLine method of the SalesLine table
As below an example the code how to achieve this. It returns a boolean, which is used in the ‘if’ clause in the retailPackRetailSalesLine extension method.