Scenario
New field MyNewField as NoYes on CustTrans and VendTrans
Simple solution
Obejcts
Create method parmMyNewField on CustVendTans, CustTrans and VendTrans using Table code extensions.
Usage
custVendTrans.parmMyNewField(NoYes::Yes) will work fine if the record hast been inserted.
Issue
If custVendTrans has not yet been inserted a call to custVendTrans.parmMyFlag(NoYes::Yes) will result in the errors
“Error executing code: CustTrans table does not have method ‘parmMyNewField’.“
or
“Error executing code: VendTrans table does not have method ‘parmMyNewField’.“
Full Solution
Extend the CustVendTransInterface class to properly handle mapped functions irrespective of the record being created or not.
Objects
- Create class MyCustVendTransInterface following plugin design pattern, decorated with [… ExportInterfaceAttribute]
- Create sub-class MyCustTransCustVendTrans
decorated with [… ExportMetadataAttribute(…CustTrans…), … ExportAttribute(…MyCustVendTransInterface…)] - Create sub-class MyVendTransCustVendTrans
decorated with [… ExportMetadataAttribute(…VendTrans…), … ExportAttribute(…MyCustVendTransInterface…)]
- Create sub-class MyCustTransCustVendTrans
[Microsoft.Dynamics.AX.Platform.Extensibility.ExportInterfaceAttribute] public abstract class MyCustVendTransInterface { CustVendTransInterface custVendTransInterface; private void initializeCustVendTransInterface(CustVendTransInterface _custVendTransInterface) { custVendTransInterface = _custVendTransInterface; } public CustVendTrans parmCustVendTrans() { return custVendTransInterface.parmCustVendTrans(); } protected void new() { } public static MyCustVendTransInterface createInstance(CustVendTransInterface _custVendTransInterface) { SysPluginMetadataCollection metadataCollection = new SysPluginMetadataCollection(); metadataCollection.SetManagedValue(classStr(MyCustVendTransInterface), tableId2Name(_custVendTransInterface.parmCustVendTrans().tableId)); MyCustVendTransInterface instance = SysPluginFactory::Instance(identifierStr(Dynamics.AX.Application), classStr(MyCustVendTransInterface), metadataCollection); instance.initializeCustVendTransInterface(_custVendTransInterface); return instance; } public NoYes parmMyNewField(NoYes _myNewField= NoYes::No) { return _myNewField; } }
[System.ComponentModel.Composition.ExportMetadataAttribute(classStr(MyCustVendTransInterface), tableStr(CustTrans)) ,System.ComponentModel.Composition.ExportAttribute('Dynamics.AX.Application.MyCustVendTransInterface')] public class MyCustTransCustVendTrans extends MyCustVendTransInterface { private CustTrans parmCustTrans() { return this.parmCustVendTrans(); } public NoYes parmMyNewField(NoYes _myNewField = this.parmCustTrans().MyNewField) { CustTrans custTrans = this.parmCustTrans(); custTrans.MyNewField = _myNewField; return custTrans.MyNewField; } }
[System.ComponentModel.Composition.ExportMetadataAttribute(classStr(MyCustVendTransInterface), tableStr(VendTrans)) ,System.ComponentModel.Composition.ExportAttribute('Dynamics.AX.Application.MyCustVendTransInterface')] public class MyVendTransCustVendTrans extends MyCustVendTransInterface { private VendTrans parmVendTrans() { return this.parmCustVendTrans(); } public NoYes parmMyNewField(NoYes _myNewField = this.parmVendTrans().MyNewField) { VendTrans vendTrans = this.parmVendTrans(); vendTrans.MyNewField = _myNewField; return vendTrans.MyNewField; } }
- Optional: create extenstion class CustVendTransInterface_My_Extension
to provide simple access to the newly created class MyCustVendTransInterface
[ExtensionOf(classStr(CustVendTransInterface))] final class MyCustVendTransInterfaceCls_Extension { private MyCustVendTransInterface MyCustVendTransInterface; public MyCustVendTransInterface MyCustVendTransInterface() { if (!MyCustVendTransInterface) { MyCustVendTransInterface = MyCustVendTransInterface::createInstance(this); } return MyCustVendTransInterface; } }
Usage
//if extension CustVendTransInterface_My_Extension implemented MyCustVendTransInterface myCustVendTransInterface = CustVendTransInterface::createInstance(custVendTrans).myCustVendTransInterface() //if extension CustVendTransInterface_My_Extension not implemented MyCustVendTransInterface myCustVendTransInterface = MyCustVendTransInterface::createInstance(CustVendTransInterface::createInstance(custVendTrans)) //access field myCustVendTransInterface.parmMyNewField(NoYes::Yes);
Final notes
Microsoft documents the extension of maps here:
Extend table maps that are used as interfaces
However the example SalesPurchTable they are using has a special attribute class to decorate the methods (SalesPurchTableInterfaceFactoryAttribute. The example here is both more generic and simpler.
Leave a comment