Extend Map CustVendTrans

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…)]
[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.


Posted

in

,

by

Tags:

Comments

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.