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.