Change tracking through AIFChangeTrackingTable in X++

 

Change tracking through AIFChangeTrackingTable in x++ 

This document demonstrates how to get changes done in tables through data entity. You need changed records from multiple tables and save those records in our custom table.

For this, you need to create a data entity containing the tables, views or query to include required tables.

Then,

Navigate to Modules -> System Administration -> Data Management.



Click on Data Entities




Search for your entity. Then click the three dots on action pane and select Change tracking. It will show three options, select enable custom query.








After selecting the option, you will get these Infolog messages and change tracking will be changed to custom.










This is needed to functionally enable the change tracking for required entity.

The requirement is to get the  records that are created or modified in actual tables. For this you have to create a query same as data entity and with calling AIF change tracking code, you have to add ranges inside your query to get only those Recid(s) which are created or modified in original tables.

Now, the code required to get the changes:

         AifChangeTracking       aifChangeTracking;

        AifChangeTrackingTable  changeTrackingTable;

        new AifChangeTrackingPermission().assert();

        // entity name is specified in dictEntity.

        DictDataEntity dictEntity   = new DictDataEntity(tableNum(yourEntityName));

 

        aifChangeTracking = AifChangeTracking::constructFromDataEntityV2(dictEntity, DMFChangeTrackingType:        :CustomQuery, '', AifChangeTrackingType::SqlChangeTracking);

        changeTrackingTable = aifChangeTracking.getChanges(DateTimeUtil::utcNow());

 

        while select changeTrackingTable

        {

            hasRecord = true;

            if (changeTrackingTable.ChangedTableId == tableNum(VendTrans))

            {

                qbdsVendTrans.addRange(fieldNum(VendTrans, RecId)).value(queryValue(changeTrackingTable.Key                Field_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(Vendsettlement))

            {

                qbdsVendSettlement.addRange(fieldNum(vendSettlement, RecId)).value(queryValue(changeTrackin                gTable.KeyField_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(bankChequeTable))

            {

                qbdsBankChequeTable.addRange(fieldNum(BankChequeTable, RecId)).value(queryValue(changeTrack                ingTable.KeyField_RecId));

            }

           

        }

Now, running the query through QueryRun class and saving the list of records from AIF Change tracking.

        new AifChangeTrackingPermission().assert();

        // entity name is specified in dictEntity.

        DictDataEntity dictEntity   = new DictDataEntity(tableNum(yourEntityName));

 

        aifChangeTracking = AifChangeTracking::constructFromDataEntityV2(dictEntity, DMFChangeTrackingType:        :CustomQuery, '', AifChangeTrackingType::SqlChangeTracking);

        changeTrackingTable = aifChangeTracking.getChanges(DateTimeUtil::utcNow());

 

        while select changeTrackingTable

        {

            hasRecord = true;

            if (changeTrackingTable.ChangedTableId == tableNum(VendTrans))

            {

                qbdsVendTrans.addRange(fieldNum(VendTrans, RecId)).value(queryValue(changeTrackingTable.Key                Field_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(Vendsettlement))

            {

                qbdsVendSettlement.addRange(fieldNum(vendSettlement, RecId)).value(queryValue(changeTrackin                gTable.KeyField_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(bankChequeTable))

            {

                qbdsBankChequeTable.addRange(fieldNum(BankChequeTable, RecId)).value(queryValue(changeTrack                ingTable.KeyField_RecId));

            }

           

        }

In the end your method would be like:

        Query                       query;

        QueryRun                    qr;

        QueryBuildDataSource        qbdsVendTrans;

        QueryBuildDataSource        qbdsVendSettlement;

        QueryBuildDataSource        qbdsBankChequeTable;

        VendTrans                   vendTrans;

        VendSettlement              vendSettlement;

        BankChequeTable             bankChequeTable;

        FromDateTime                today;

        boolean                     hasRecord = false;

        BYRPaymentInformation       paymentInformation;

        vendTrans                   invoiceNumber;

       

        query = new Query(queryStr(BYRHylandPaymentInformationQuery));

        qbdsVendTrans = query.dataSourceTable(tablenum(VendTrans));

        qbdsVendSettlement = query.dataSourceTable(tablenum(VendSettlement));

        qbdsBankChequeTable = query.dataSourceTable(tablenum(BankChequeTable));

 

        today = DateTimeUtil::getSystemDateTime();

  

        DictDataEntity dictEntity   = new DictDataEntity(tableNum(BYRHylandPaymentInformationExportEntity))        ;

 

        AifChangeTracking       aifChangeTracking;

        AifChangeTrackingTable  changeTrackingTable;

 

        new AifChangeTrackingPermission().assert();

 

        aifChangeTracking = AifChangeTracking::constructFromDataEntityV2(dictEntity, DMFChangeTrackingType:        :CustomQuery, '', AifChangeTrackingType::SqlChangeTracking);

        changeTrackingTable = aifChangeTracking.getChanges(DateTimeUtil::utcNow());

 

        while select changeTrackingTable

        {

            hasRecord = true;

            if (changeTrackingTable.ChangedTableId == tableNum(VendTrans))

            {

                qbdsVendTrans.addRange(fieldNum(VendTrans, RecId)).value(queryValue(changeTrackingTable.Key                Field_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(Vendsettlement))

            {

                qbdsVendSettlement.addRange(fieldNum(vendSettlement, RecId)).value(queryValue(changeTrackin                gTable.KeyField_RecId));

            }

            else  if (changeTrackingTable.ChangedTableId == tableNum(bankChequeTable))

            {

                qbdsBankChequeTable.addRange(fieldNum(BankChequeTable, RecId)).value(queryValue(changeTrack                ingTable.KeyField_RecId));

            }

           

        }

 

        qr = new QueryRun(query);

     

        if (hasRecord)

        {

            RecordInsertList recordList = new RecordInsertList(tableNum(CustomTableName));

 

            while (qr.next())

            {

                vendTrans = qr.get(tableNum(VendTrans));

                vendSettlement = qr.get(tableNum(VendSettlement));

                bankChequeTable = qr.get(tableNum(BankChequeTable));

                BYRHylVendTransInvoiceView vendTransInvoiceView = qr.get(tableNum(BYRHylVendTransInvoiceVie                w));

 

                paymentInformation.clear();

                paymentInformation.AccountNum = vendTrans.AccountNum;

                paymentInformation.Invoice = vendTransInvoiceView.Invoice;

                paymentInformation.ChequeNum = bankChequeTable.ChequeNum;

                paymentInformation.SettlementAmount = (vendSettlement.SettleAmountCur) * -1;

                paymentInformation.PaymMode = vendTrans.PaymMode;

                paymentInformation.PaymentDate = vendTrans.TransDate;

                paymentInformation.ChequeStatus = vendTrans.PaymMode == 'CHECK' ? enum2Value(bankChequeTabl                e.ChequeStatus) : 'Paid';

                paymentInformation.ExportStatus = NoYes::No;

                recordList.add(paymentInformation);

            }

            ttsbegin;

            recordList.insertDatabase();

            ttscommit;

        }


Comments

Popular posts from this blog

How to customize segmented entry control

Integration from azure blob through x++