Tuesday, July 6, 2021

Create XML with data from CustTrans table

 static void Create_XML(Args _args)
{
    XmlDocument doc;
    XmlElement  nodeXml;
    XmlElement  nodeTable;

    CustTrans   _custTrans;
    #define.filename(@"D:\Output\TEST_CREATE.xml")
    ;
    doc     = XmlDocument::newBlank();
    nodeXml = doc.createElement('CustomerVoucher');
    doc.appendChild(nodeXml);

    while select * from _custTrans
    where _custTrans.AccountNum == '10002'
    {
        nodeTable = doc.createElement('DocumentNumber');
        nodeXml.appendChild(nodeTable);
        nodeTable.appendChild(doc.createTextNode(
_custTrans.DocumentNum) );

        nodeTable = doc.createElement('VoucherNumber');
        nodeXml.appendChild(nodeTable);
        nodeTable.appendChild(doc.createTextNode(_custTrans.Voucher) );
    }
    doc.save(#filename);

}

Create LedgerJournalTrans with Marked Settlement Vendor for AX 2009

 
static void Create_AP_JournalSettlement_AX(Args _args)
{
    /** Add Ledger type : Vendor lines with marking of open vendor transaction to existing Journal Table for AX 2009 **/
    /** Using custom class to create LedgerJournalTrans **/
    
    LedgerJournalTrans              _ljt, _ljt2;
    VendTransOpen                   _vto;
    VendTrans                       _vt;

    CustVendOpenTransManager    manager;
    container                   conVchx;
    JournalId                   jourNumx;
    TransDate                   transDatex, docDatex, dueDatex;
    Amount                      totSettledx;
    Str 20                      invoiceNumx;
    RecId                       ljtRecIdx;
    AccountNum                  accNumx;
    ;
    jourNumx = '20-0002940';
    transDatex = today();
    invoiceNumx = '12345';
    accNumx     = 'V0008';
   
    if(!LedgerJournalTable::find(jourNumx).Posted)
    {
        delete_from _ljt where _ljt.JournalNum == jourNumx;
    }

    _ljt = AX_LedgerJournal::createJournalLines(jourNumx, '', transDatex, docDatex, dueDatex,
                    'Vendor',accNumx,0,0,'Ledger','','','','','','1.PRO');

    ljtRecIdx = _ljt.RecId;
    manager = CustVendOpenTransManager::construct(_ljt);
    manager.resetMarkedTrans();

    while select * from _vto
    join Invoice from _vt
    where _vto.RefRecId == _vt.RecId
       && _vto.AccountNum == _vt.AccountNum
       && _vt.AccountNum == accNumx
       && _vt.Invoice == _invoiceNumx
    {
        manager.updateTransMarked(_vto, true);
        totSettledx = manager.getMarkedTotalDisplayCur();
        info(strfmt('%1 %2 %3', _vto.AccountNum, _vt.Invoice, totSettledx));
    }

    ttsBegin;
    _ljt.MarkedInvoice = '';//ctcheck.Invoice;
    _ljt.SettleVoucher = SettlementType::SelectedTransact;
    _ljt.Txt = strfmt('Invoicing %1',transDatex);
    //_ljt.DocumentNum = strfmt('%1',invoiceNumx);

    if(totSettledx > 0)
    { _ljt.AmountCurCredit =  abs(totSettledx); }
    else
    { _ljt.AmountCurDebit =  abs(totSettledx); }
    _ljt.update();
    ttsCommit;
    
    _ljt2 = AX_LedgerJournal::createJournalLines(jourNumx, _ljt.Voucher,transDatex, docDatex, dueDatex,
                    'Vendor',accNumx,0,abs(totSettledx),'Ledger','','',invoiceNumx,'',_ljt.Txt, '2.INV');


}

Friday, July 3, 2020

Add custom button to run existing MenuItemButton on Dynamics 365FO and related event handler behaviour

In this example, in AX 2012, we write this code to override process a menu item button in PurchTable form (buttonUpdatePackingSlip) .

clicked()
{   
        //Process Before
        super();

       //Process After
}




In D365FO we could handling with Extension within these steps:
1. Create Extension of PurchTable form, add new button




2. Create new class for handling PurchTable event handler
  

 





3.  Copy Event handler method from new created button on PurchTable



 
4. Paste to the created class



 

5. Update the class


6. Create new class for handling PurchEditLines event handler


7. Copy event handler from form PurchEditLines Extension



 

8. Paste to the class
 
9. View Result









 









Sunday, November 3, 2019

Understanding Class SysDatabaseTransDelete on Microsoft Dynamics AX 2012 R3 CU 8













Settle all cutomer transaction open within sum of AmountMST is zero for Microsoft Dynamic AX 2009 SP1 RU8

    static void MyCode_Cust_Settlement_Settle_Zero(Args _args)
    {
        CustTrans                       _custTransMark;
        CustTable                       _custTable, _custTableMark;
        MyCode_CustTransOpenSumZeroView    _transOpenZero;
        CustTransOpen                   _custTransOpen;
        AmountCur                       amountCur,netSettledAmt;
        AccountNum                      custNum;
        TransDate                       asOfDate,settleDate;
        CustVendTransData               custVendTransData;
        CustVendOpenTransManager        manager;
        Boolean                         goProcess, isInfolog;
        int                             countCust,countTrans;
        ;
        netSettledAmt = 0;
   
        isInfolog   = true;
        goProcess   = false;
   
        asOfDate    = str2date('30-09-2019', 123);
        settleDate  = str2date('01-10-2019', 123);
   
        /** 1. Get list from customer open transaction view (customized), summarized by AccountNum, having sum AmountMST = 0  **/
        while select _transOpenZero
        join _custTable
        where _transOpenZero.MaxOfTransDate <= asOfDate
           && _custTable.AccountNum == _transOpenZero.AccountNum
           && _custTable.CustGroup == 'CORPORATE'
           && _custTable.AccountNum == 'CUST01'
        {
            //1.a. Reset marked settlement per customer
            countCust++;
            if(goProcess)
            {
                _custTableMark  = CustTable::find(_transOpenZero.AccountNum);
                manager         = CustVendOpenTransManager::construct(_custTableMark);
   
                if (manager.getSpecTransCount() > 0)
                    manager.resetMarkedTrans();
            }
   
            /** 2. Get list customer open transaction per customer **/
            while select _custTransOpen
            where _custTransOpen.AccountNum == _transOpenZero.AccountNum
            {
                /** 3. Get CustTrans based on CustTransOpen**/
                countTrans++;
                select firstonly _custTransMark
                where _custTransMark.RecId == _custTransOpen.RefRecId;
                //netSettledAmt += _custTransMark.remainAmountCur();
   
                if(isInfolog) info(strfmt("CustTrans %1 %2 %3 %4 %5", _custTransMark.AccountNum,_custTransMark.Voucher, _custTransMark.remainAmountCur(), _custTransMark.Txt, _custTransMark.RecId));
   
                if(goProcess) custVendTransData = CustVendTransData::construct(_custTransMark);
                if(goProcess) custVendTransData.markForSettlement(_custTableMark);
            }
   
            if(goProcess) CustTrans::settleTransact(_custTableMark, null, true,SettleDatePrinc::SelectDate, settleDate);
        }
        info(strfmt('Settled done! Customers: %1 Transactions: %2', countCust, countTrans ));
        info(strfmt('As of date: %1', asOfDate));
    }

List all tables, include Table group description and company status for Microsoft Dynamics AX 2012 R3

static void Z_ListTable(Args _args)
{
    TextIo file;
    FileName filename = @"F:\TableList.txt";
    container con;
    FileIoPermission permission;
    #File

    TableId         tableId;
    SysDictTable    sysDictTable;
    TableGroup      tableGroupx;
    NoYes           isPerComp;
    String255       tableName;
    int             tablecounter;
    Dictionary      dict = new Dictionary();
    EnumId   Id        = enumNum(TableGroup);
    DictEnum dictEnum  = new DictEnum(Id);
    int             EnumValue;
    ;

    try
    {
    permission = new FileIoPermission(filename, #io_write);
    permission.assert();
    file = new TextIo(filename, #io_write);
    if (!file)
    throw Exception::Error;
    file.outRecordDelimiter(#delimiterCRLF);
    file.outFieldDelimiter(";");

        for (tablecounter=1; tablecounter<=dict.tableCnt(); tablecounter++)
        {
            tableId         = dict.tableCnt2Id(tablecounter);
            sysDictTable    = new SysDictTable(tableId);

            if (sysDictTable && !sysDictTable.isTmp() && !sysDictTable.isMap())
            {
                tableGroupx  = sysDictTable.tableGroup();
                EnumValue = enum2Int(tableGroupx);

                isPerComp   = sysDictTable.dataPrCompany();
                tableName   = sysDictTable.name();

                con = connull();
                con = conins(con, 1, tableName);
                con = conins(con, 2, tableGroupx);
                con = conins(con, 3, dictEnum.index2Symbol(EnumValue));
                con = conins(con, 4, isPerComp);

                file.writeExp(con);
            }
        }

    }
    catch(Exception::Error)
    {
        error("You do not have access to write the file to the selected folder");
    }
    CodeAccessPermission::revertAssert();

    info('File Created!');

}

Monday, August 20, 2018

Marking Customer Transaction with Specific Amount - Unposted Settlement for AX 2012 R3

static void Create_CustSettleOpen(Args _args)
{
    CustVendOpenTransManager manager;
    LedgerJournalTrans ljt;
    CustTransOpen ctoselect,cto;
    CustTrans ctselect,ct;
    AccountNum accnnumx;
    Voucher vchx1,vchx2,vchx3,vchx4;
    Amount toBeSettlex,selectSettlex,selectSettleEndx,diffSettlex,totSettledx;
    ;
    accnnumx    = '3';
    vchx1       = 'ARCI00000001';
    vchx2       = 'ARCI00000002';
    vchx3       = 'ARCI00000004';
    vchx4       = 'ARCI00000005';
    toBeSettlex = 200000000; // Specifict amount to be settled to multiple voucher
    selectSettlex = 0;
   

    //Check existing CustTrans with criteria
    select count(RecId) from ctselect
    where ctselect.AccountNum == accnnumx
          && ctselect.TransDate == str2Date('01/07/2018',123)
          ;

    if(ctselect.RecId > 0)
    {
        // Fetch the added LedgerJournalTrans
        ljt = LedgerJournalTrans::find('G000001521', 'RINV1000011910', true);
        manager = CustVendOpenTransManager::construct(ljt);

        //loop find any open CustTrans based on criteria

        while select * from ctoselect join ct
        where ct.AccountNum == ctoselect.AccountNum
        && ct.RecId == ctoselect.RefRecId
        && ct.AccountNum == accnnumx
        && ct.TransDate == str2Date('01/07/2018',123)
        {
            if (ctoselect.AmountCur != ct.AmountCur)
            {
                throw error('invoice has been partially paid');
            }
            // Mark the invoice.
            selectSettlex = selectSettlex + ctoselect.AmountCur;
            diffSettlex = selectSettlex - toBeSettlex;

            //info(strFmt('%1 %2 %3',selectSettlex,toBeSettlex,ct.Voucher));

            if( selectSettlex > toBeSettlex)
            {
                manager.updateTransMarked(ctoselect, true);
                manager.updateSettleAmount(ctoselect, toBeSettlex-selectSettleEndx);
                //info(strFmt('IF %1 %2 diff %3 %4',selectSettlex,toBeSettlex,diffSettlex,ct.Voucher));
                break;
            }

            manager.updateTransMarked(ctoselect, true);
            selectSettleEndx = selectSettlex;
            //info('marked');

        }

        totSettledx = manager.getMarkedTotalDisplayCur();

        ttsBegin;
            // Update journal trans.
            ljt.MarkedInvoice = ct.Invoice;
            ljt.SettleVoucher = SettlementType::SelectedTransact;

            if(totSettledx > 0)
            { ljt.AmountCurCredit =  abs(totSettledx); }
            else
            { ljt.AmountCurDebit =  abs(totSettledx); }

            ljt.update();
        ttsCommit;      

    }
    else
    {
        throw error('voucher could not be found');
    }
    info(strFmt('done. total %1',totSettledx));
}