Search This Blog

Thursday, June 25, 2015

AIF Inheritance Extending AXD classes AX2012


Scenario:

I have multiple ledgerTransaction files coming from different source systems to AX, so each file import must have different business logic,business handlings regarding the dimensions, type of files ex ledger,cust,bank,vend.

I build the whole logic in the standard AXDLEdgerGeneralService class in deserializeEntity method with journalNames I handled, but its becoming more complex and to maintain the functionality and growing business requirements, its getting messing in the code.

I designed the inheritance for AIF documents, For each inbound we can have different axdclass with their own business logic implemented and I defined which axdclass that you want to run on that inbound port. It became easier to maintain the code and standard class is same as Standard.

I thought to share as it may be useful for lot of people.

abstract class AifDocument extends AfStronglyTypedDataContainer
{
    classId             axdClassId;
    AxdBase             axdInstance;

    AifXml              documentXml;
    boolean             documentXmlExists;
    boolean             deserializeNow;
}

public classId parmAXDClassId(classId _classId=axdClassId)
{
    axdClassId=_classId;

    return axdClassId;
}

Add field ClassId in table AIFInboundPort which extends classID EDT.
Create an Edit method in this table
edit className name(boolean set, Classname value)
{
     classid classID;
     if(set)
     {
         classid=classname2id(value);
         this.classid=classid;
     }
     else
    {
           value = classid2name(this.classid);
     }
}


Create an inMemmory table AifAxdClassLookup with the field ClassName of EDT Name.
Edit the form aifinboundPort and add a method at element level
Declare a variable at form level as AifAxdClassLookup aifAxdClassLookup;

Add AXDClass string edit control on details header group. define Datamethod Name

Add progress control under details header  group and name it as progress.

Create element level method as below, we will use this method in the lookup of the AXDclass string edit control.

void generateAXDClassesLookupTable()
{
    AXDBase componentInstance;
    Dictionary dictionary;
    SysDictClass dictClass;
    int i;
    int classCount;
    classId componentInterfaceId,componentInterfaceId1;

    SysTableLookup              sysTableLookup;
    ;

    dictionary = new Dictionary();
    componentInterfaceId1=classNum(AxdLedgerGeneralJournal);

    classCount = dictionary.classCnt();

    progress.rangeLo(1);
    progress.rangeHi(classCount);
    progress.pos(1);
    progress.step(1);
    progress.visible(true);
    for (i=1; i <= classCount; i++)
    {
        progress.pos(i);
        dictClass = new SysDictClass(dictionary.classCnt2Id(i));
        if (dictClass.isImplementing(componentInterfaceId1))
        {
            componentInstance = dictClass.makeObject();
            AifAxdClassLookup.clear();
            AifAxdClassLookup.ClassName = dictClass.name();
            AifAxdClassLookup.insert();
        }
    }
    progress.visible(false);
    componentLookupGenerated = true;
}

Override the lookup method of AXDClass string edit control and add below code

public void lookup()
{
   SysTableLookup          tableLookup;
    Query                   query;
    QueryBuildDataSource    queryBuildDataSource;
    ;

    if (componentLookupGenerated == false)
    {
        element.generateAXDClassesLookupTable();
    }

    query = new Query();
    queryBuildDataSource = query.addDataSource(tablenum(AifAxdClassLookup));

    tableLookup = SysTableLookup::newParameters(tablenum(AifAxdClassLookup), this);
    tableLookup.addLookupfield(fieldnum(AifAxdClassLookup, ClassName));
    tableLookup.parmQuery(query);
    //BP Deviation Documented.
    tableLookup.parmTmpBuffer(AifAxdClassLookup);
    tableLookup.parmUseLookupValue(false);

    tableLookup.performFormLookup();
}

Modify the service class ex: ledgerGeneralService class in my case its ledgerGeneralJournalService
[AifDocumentCreateAttribute, SysEntryPointAttribute(true)]
public AifEntityKeyList create(LedgerGeneralJournal _ledgerGeneralJournal)
{
    AifInboundPort aifInboundPort;
    ClassId AxdClassId;
    ;
    //Assign inheritance extension AXDclass for each port defined on the inboundPort added by krishna.
    if (operationContext != null)
    {
        AxdClassId=aifInboundPort::find(operationContext.getPortName()).ClassId;
        if(AxdClassId!=0)
        {
            _ledgerGeneralJournal.parmAXDClassId(AxdClassId);
        }
    }

    //assign inheritance extension AXDclass for each port defined on the inboundPort added by krishna.
    return this.createList(_ledgerGeneralJournal);

}

Now we will create a class which extends AXDclass ex: AXDLedgerGeneralJournal

class AxdLedgerGeneralJournal_GeneralALL extends AxdLedgerGeneralJournal
{
}

Override the queryName method and use which query you are using for your inbound AIF
In my example I am using AXDLedgerGeneralJournal

public QueryName getQueryName()
{
    return querystr(AxdLedgerGeneralJournal);
}

Now you can override whatever the method you want to overiride, in my case I am overriding deserializeentity.
This method contains all my modification logic.

public void afterDeserializeEntity(AxInternalBase _axbc, tableId _tableId, str _dataSourceName)
{
    AxdBaseProperty axdBaseProperty = new AxdBaseProperty();
    container       dimensionValue, axdBasePropertyContainer, dimensionValueConverted,bankDimensionContainer;
    recId           dimensionFieldRecId,bankDimensionFieldRecid;
    int             containerElementIndex = 1;
    int             containerLength;
    int             fieldId;
    selectableDataArea company, offsetCompany;
    BankAccountTable localBankAccountTable;
    AccountStatementRules AccountStatementRules;

    JournalNameId localJournalName;
    LogisticsPostalAddressView    locallogisticsPostalAddressView;
    LogisticsLocationParty        logisticslocationParty;
    CustTable                     localCustTable;

    MappingText                localMappingText="";
    localJournalName="";
    dimensionFieldRecId=0;

    containerLength = conLen(fieldList);

    if (containerLength == 0)
    {
        return;
    }

    if(_tableId == tableNum(LedgerJournalTrans))
    {
        ledgerJournalName = LedgerJournalName::find(_axbc.parentAxBC().fieldId(fieldNum(ledgerJournalTable, JournalName)));

    }
    if(_tableId == tableNum(LedgerJournalTable))
    {
        ledgerJournalName = LedgerJournalName::find(_axbc.fieldId(fieldNum(ledgerJournalTable, JournalName)));
    }
    if(ledgerJournalName)
    {
        ateAccountDefinitionId = ATEAccountDefinitionTable::findRecId(
            ledgerJournalName.ATEAccountDefinitionTable
            ).DefinitionId;
    }
    if (_tableId == tableNum(LedgerJournalTrans))
    {
        company         = _axbc.fieldId(fieldNum(LedgerJournalTrans, Company));
        offsetCompany   = _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetCompany));

        company         = AifLookupEntry::findInternal(SystemParameters::find().LookupTableId,company);
        offsetCompany   = AifLookupEntry::findInternal(SystemParameters::find().LookupTableId,offsetCompany);

        if(LedgerJournalName::find(_axbc.parentAxBC().fieldId(fieldNum(ledgerJournalTable, JournalName))).JournalName=="1234")
        {
            company         =curext();
            offsetCompany   =curext();
        }

        if (company)
        {
            _axbc.fieldId(fieldNum(LedgerJournalTrans, Company), company);
        }
        else
        {
            company         =curext();
            _axbc.fieldId(fieldNum(LedgerJournalTrans, Company), company);
        }

        if (offsetCompany)
        {
            _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetCompany), offsetCompany);
        }
        else
        {
            offsetCompany   =curext();
            _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetCompany), offsetCompany);
        }
         // Validate the primary and offset companies.
        this.validateCompany(_axbc.currentRecord(), tableNum(LedgerJournalTrans), fieldNum(LedgerJournalTrans, Company), company);
        this.validateCompany(_axbc.currentRecord(), tableNum(LedgerJournalTrans), fieldNum(LedgerJournalTrans, OffsetCompany), offsetCompany);
    }
    do
    {
        axdBasePropertyContainer = conPeek(fieldList, containerElementIndex);
        axdBaseProperty.unpack(axdBasePropertyContainer);
        containerElementIndex++;
        dimensionValue = conPeek(fieldList, containerElementIndex);
        containerElementIndex++;

        fieldId = axdBaseProperty.parmImplementingFieldId();

        // If the Table number and Field number match then convert the field by calling axdDimensionUtil
        // and set the corresponding field through its parm method.
        if (_tableId == tableNum(LedgerJournalTable) &&
            fieldId == fieldNum(LedgerJournalTable, OffsetLedgerDimension))
        {
            // MultiTypeDefaultAccount requires an account type to be specified.
            //return AxdDimensionUtil::getMultiTypeDefaultAccountId(_accountTypeEnumId, _accountType, _dimensionValue);
            dimensionFieldRecId = AxdDimensionUtil::getMultiTypeDefaultAccountId(enumName2Id('LedgerJournalACType'),
                                                                                 _axbc.fieldId(fieldNum(LedgerJournalTable, OffsetAccountType)),
                                                                                 dimensionValue);
            _axbc.fieldId(fieldNum(LedgerJournalTable, OffsetLedgerDimension), dimensionFieldRecId);
        }
        else if (_tableId == tableNum(LedgerJournalTrans))
        {
            if (fieldId == fieldNum(LedgerJournalTrans, LedgerDimension))
            {

                if (ateAccountDefinitionId)
                {
                        dimensionValueConverted = this.ConvertLedgerdimension_PC(
                                _axbc.fieldId(fieldNum(LedgerJournalTrans, ExternalAccountString))
                            , _axbc.fieldId(fieldNum(LedgerJournalTrans, Company))
                            , _axbc.fieldId(fieldNum(LedgerJournalTrans, CurrencyCode))
                            , LedgerJournalName::find(_axbc.parentAxBC().fieldId(fieldNum(ledgerJournalTable, JournalName))).JournalName);
                        if (BankAccountTable::exist(conPeek(dimensionValueConverted,2)))
                        {
                            _axbc.fieldId(fieldNum(LedgerJournalTrans, AccountType), LedgerJournalACType::Bank);
                            _axbc.fieldId(fieldNum(LedgerJournalTrans,DefaultDimension),BankAccountTable::find(conPeek(dimensionValueConverted,2)).DefaultDimension);
                        }
                        dimensionFieldRecId = AxdDimensionUtil::getMultiTypeAccountId(enumName2Id('LedgerJournalACType'),
                                                                                        _axbc.fieldId(fieldNum(LedgerJournalTrans, AccountType)),
                                                                                        dimensionValueConverted,
                                                                                        company);
                }
                else  //Non ATE starts
                {
                    dimensionFieldRecId = AxdDimensionUtil::getMultiTypeAccountId(enumName2Id('LedgerJournalACType'),
                                                                                    _axbc.fieldId(fieldNum(LedgerJournalTrans, AccountType)),
                                                                                    dimensionValue,
                                                                                    company);
                }// Else Non ATE closed

                _axbc.fieldId(fieldNum(LedgerJournalTrans, LedgerDimension), dimensionFieldRecId);
            }// IF ledgerJournalTrans ledgerDimensionClosed field is closed
            else if (fieldId == fieldNum(LedgerJournalTrans, OffsetLedgerDimension))
            {

                if (ateAccountDefinitionId)
                {
                    dimensionValueConverted = this.ConvertLedgerdimension_PC(
                            _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetAccountString))
                        , _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetCompany))
                        , _axbc.fieldId(fieldNum(LedgerJournalTrans, CurrencyCode))
                        ,LedgerJournalName::find(_axbc.parentAxBC().fieldId(fieldNum(ledgerJournalTable, JournalName))).JournalName);
                    dimensionFieldRecId = AxdDimensionUtil::getMultiTypeAccountId(enumName2Id('LedgerJournalACType'),
                                                                                    _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetAccountType)),
                                                                                    dimensionValueConverted,//dimensionValue,
                                                                                    offsetCompany);
                }// ATE offset closed
                else
                {
                    dimensionFieldRecId = AxdDimensionUtil::getMultiTypeAccountId(enumName2Id('LedgerJournalACType'),
                                                                                    _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetAccountType)),
                                                                                    dimensionValue,
                                                                                    offsetCompany);
                }//ELse non ATE  offset closed

                _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetLedgerDimension), dimensionFieldRecId);
            }//Else if OffsetLedger dimension closed
            else if (fieldId == fieldNum(LedgerJournalTrans, DefaultDimension))
            {
                dimensionFieldRecId = AxdDimensionUtil::getDimensionAttributeValueSetId(dimensionValue, company);
                _axbc.fieldId(fieldNum(LedgerJournalTrans, DefaultDimension), dimensionFieldRecId);
            }//Else if Default dimension closed
            else if (fieldId == fieldNum(LedgerJournalTrans, OffsetDefaultDimension))
            {
                // OffsetDefaultDimension requires a Legal entity to be specified to support intercompany transactions.
                dimensionFieldRecId = AxdDimensionUtil::getDimensionAttributeValueSetId(dimensionValue, offsetCompany);
                _axbc.fieldId(fieldNum(LedgerJournalTrans, OffsetDefaultDimension), dimensionFieldRecId);
            }//Else if OffsetDefault dimension closed
        }//IF ledgerJournalTrans table check closed
    }//Do while closed
    while (containerElementIndex < containerLength);
    fieldList = conNull();
}




 If you guys likes this post please share it and like this post.


if you have any queries please contact and message me.




No comments:

Post a Comment

Thanks for visiting my blog,
I will reply for your comment within 48 hours.

Thanks,
krishna.