Ledger Settlement is very slow

This problem can be done when you do a migration of data of Ax. Why is it slow ? I don’t know, but you can increase the speed by modifying these piece of code :

Class CustVendPaymNote.buildPaymNote()

[...]
    CustVendTransOpen   custVendTransOpenSelect;
    CustVendTrans       custVentTransSelect;
    ;
[...]

// BEGIN
//    while select crossCompany RecId from specTrans
//        where specTrans.SpecCompany == _specCompany
//           && specTrans.SpecTableId == _specTableId
//           && specTrans.SpecRecId   == _specRecId
//        join RecId from custVendTransOpen
//            where custVendTransOpen.DataAreaId == specTrans.RefCompany
//               && custVendTransOpen.TableId == specTrans.RefTableId
//               && custVendTransOpen.RecId   == specTrans.RefRecId
//        join TransDate, DocumentNum, Invoice, PaymId, Voucher from custVentTrans
//            where custVentTrans.RecId == custVendTransOpen.RefRecId

    while select crossCompany RecId from specTrans
        index   hint SpecIdx
        where specTrans.SpecCompany                     == _specCompany
           && specTrans.SpecTableId                     == _specTableId
           && specTrans.SpecRecId                       == _specRecId
        join RecId from custVendTransOpenSelect
            where custVendTransOpenSelect.DataAreaId    == specTrans.RefCompany
            && custVendTransOpenSelect.TableId          == specTrans.RefTableId
            && custVendTransOpenSelect.RecId            == specTrans.RefRecId
        exists join TransDate, DocumentNum, Invoice, PaymId, Voucher
            from    custVentTransSelect
            where   custVentTransSelect.RecId           == custVendTransOpenSelect.RefRecId
    {
        select  firstonly custVendTransOpen
        where   custVendTransOpen.TableId   == specTrans.RefTableId
        &&      custVendTransOpen.RecId     == specTrans.RefRecId;

        select  firstonly custVendTrans
        index   RecId
        where   custVendTrans.RecId == custVendTransOpen.RefRecId;
// END

Class LedgerJournalTransUpdateVend.checkSettleVoucher()

...
    VendTrans               vendTransSelect;
    VendTable               vendTransVendorSelect;
    ;
...

// BEGIN
//        while select crossCompany specTrans
//            where specTrans.SpecCompany == _ledgerJournalTrans.company() &&
//                specTrans.SpecTableId == _ledgerJournalTrans.TableId &&
//                specTrans.SpecRecId == _ledgerJournalTrans.RecId
//            join vendTransOpen
//                where specTrans.RefCompany == vendTransOpen.DataAreaId &&
//                    specTrans.RefTableId == vendTransOpen.TableId &&
//                    specTrans.RefRecId == vendTransOpen.RecId
//            join vendTrans
//                where vendTransOpen.RefRecId == vendTrans.RecId
//            join vendTransVendor
//                where vendTrans.AccountNum == vendTransVendor.AccountNum
        while select crossCompany specTrans
            where   specTrans.SpecCompany   == _ledgerJournalTrans.company()
            &&      specTrans.SpecTableId   == _ledgerJournalTrans.TableId
            &&      specTrans.SpecRecId     == _ledgerJournalTrans.RecId
        join RefRecId
            from    vendTransOpen
            where   vendTransOpen.DataAreaId    == specTrans.RefCompany
            &&      vendTransOpen.TableId       == specTrans.RefTableId
            &&      vendTransOpen.RecId         == specTrans.RefRecId
        exists join vendTransSelect
            where   vendTransSelect.RecId       == vendTransOpen.RefRecId
        exists join vendTransVendorSelect
            where   vendTransVendorSelect.AccountNum    == vendTrans.AccountNum
// END
        {
// BEGIN
            vendTrans       = VendTrans::find(vendTransOpen.RefRecId);
            vendTransVendor = VendTable::find(vendTrans.AccountNum);
// END

Last class : LedgerJournalTransUpdateCust.checkSettleVoucher

...
    CustTable               CustTransCustomerSelect;
    CustTrans               custTransSelect;
    ;
...

// BEGIN
//        while select crossCompany specTrans
//            where specTrans.SpecCompany == _ledgerJournalTrans.company() &&
//                specTrans.SpecTableId == _ledgerJournalTrans.TableId &&
//                specTrans.SpecRecId == _ledgerJournalTrans.RecId
//            join custTransOpen
//                where specTrans.RefCompany == custTransOpen.DataAreaId &&
//                    specTrans.RefTableId == custTransOpen.TableId &&
//                    specTrans.RefRecId == custTransOpen.RecId
//            join custTrans
//                where custTransOpen.RefRecId == custTrans.RecId
//            join custTransCustomer
//                where custTrans.AccountNum == custTransCustomer.AccountNum
        while select crossCompany specTrans
            where   specTrans.SpecCompany       == _ledgerJournalTrans.company()
            &&      specTrans.SpecTableId       == _ledgerJournalTrans.TableId
            &&      specTrans.SpecRecId         == _ledgerJournalTrans.RecId
        join AmountCur, RefRecId
            from    custTransOpen
            where   specTrans.RefCompany        == custTransOpen.DataAreaId
            &&      specTrans.RefTableId        == custTransOpen.TableId
            &&      specTrans.RefRecId          == custTransOpen.RecId
        exists join custTransSelect
            where   custTransOpen.RefRecId      == custTransSelect.RecId
        exists join custTransCustomerSelect
            where   custTransSelect.AccountNum  == custTransCustomerSelect.AccountNum
// END
        {
// BEGIN
            custTrans           = CustTrans::find(custTransOpen.RefRecId);
            custTransCustomer   = CustTable::find(custTrans.AccountNum);
// END

Lettrer une facture

Applicable pour la version 2009

Première manière

Voici comment lettrer une facture (client ou fournisseur).

Nous avons besoin du record dans LedgerJournalTrans et CustTransOpen ou VendTransOpen ou encore, comme l’exemple ci-dessous, la Map CustVendTransOpen. Ce qui est une meilleur solution.

Ici j’ai également rajouté un boolean pour voir si l’on devait lettrer ou pas.

protected void settle()
{
    SpecTrans           specTrans;
    ;

    if (!settle)
    {
        return;
    }

    if (!this.custVendTransOpen())
    {
        return; 
    }

    settle                  = false;

    //init table id and recid
    specTrans.SpecTableId   =  ledgerJournalTrans.TableId;
    specTrans.SpecRecId     =  ledgerJournalTrans.RecId;
    specTrans.SpecCompany   =  ledgerJournalTrans.dataAreaId;

    //init table id and recid
    specTrans.RefTableId    =  this.custVendTransOpen().TableId;
    specTrans.RefRecId      =  this.custVendTransOpen().RecId;
    specTrans.RefCompany    =  this.custVendTransOpen().dataAreaId;

    //init currency and amount
    specTrans.Code          =  ledgerJournalTrans.CurrencyCode;
    specTrans.Balance01     =  ledgerJournalTrans.AmountCurCredit
                            ?  ledgerJournalTrans.AmountCurCredit
                            : (ledgerJournalTrans.AmountCurDebit) * -1;

    //add line
    specTrans.insert();
}

Seconde manière

Achat
static void settleVend(Args _args)
{
    VendTrans      vendTrans1, vendTrans2;
    VendTable      vendTable;
    ;

    while select vendTrans1
    where vendTrans1.PaymReference != ""
    {
            select firstOnly vendTrans2
            where vendTrans2.PaymReference == vendTrans1.PaymReference
            &&    vendTrans2.AmountCur == vendTrans1.AmountCur * -1;
            if(vendTrans2 && (vendTrans1.AmountCur + vendTrans2.AmountCur == 0))
            {
                vendTable = VendTable::find(vendTrans1.AccountNum);
                vendTrans1.transData().markForSettlement(vendTable);
                vendTrans2.transData().markForSettlement(vendTable);
                vendTrans::settleTransact(vendTable);
            }
 
    }
}
Vente
static void settleCust(Args _args)
{
    CustTrans      custTrans1, custTrans2;
    CustTable      custTable;
    ;

    while select custTrans1
    where custTrans1.PaymReference != ""
    {
       if(custTrans1.isPayment())
       {
            select firstOnly custTrans2
            where custTrans2.PaymReference == custTrans1.PaymReference
            &&    custTrans2.AmountCur == CustTrans1.AmountCur * -1;
            if(custTrans2 && (custTrans1.AmountCur + custTrans2.AmountCur == 0))
            {
                custTable = CustTable::find(CustTrans1.AccountNum);
                custTrans1.transData().markForSettlement(custTable);
                custTrans2.transData().markForSettlement(custTable);
                CustTrans::settleTransact(custTable);
            }
        }
    }
}

Applicable pour la version 3 et 4

Pour la version 3 et 4 d’Ax. C’est le même code SAUF qu’il n’y a pas de champ specTrans.RefCompany et specTrans.SpecCompany utilisé pour l’intersociété.