Sunday, August 28, 2022

Get caller datasource, click button closeOK in form CustOpenTrans, get caller record of form LedgerJournalTrans for D365FO

 class CustOpenTrans_form_Exthandler

{


    [PostHandlerFor(formStr(CustOpenTrans), formMethodStr(CustOpenTrans, closeOk))]

    public static void CustOpenTrans_Post_closeOk(XppPrePostArgs args)

    {

        FormRun sender = args.getThis();

        CustTransOpen custTransOpen = sender.dataSource(formdatasourcestr(CustOpenTrans, CustTransOpen)).cursor();


        LedgerJournalTrans ljt = sender.args().record();

        info(strFmt('Voucher: %1', ljt.Voucher ));

    }


}

Monday, August 15, 2022

Extension on modified form field for D365FO

 class PriceDiscAdmTable_ExtHandler

{

      [FormDataFieldEventHandler(formDataFieldStr(PriceDiscAdm, PriceDiscAdmTrans, relation), FormDataFieldEventType::Modified)]

    public static void relation_OnModified(FormDataObject sender, FormDataFieldEventArgs e)

    {

        FormDataSource priceDiscAdmTrans_ds = sender.datasource();

        PriceDiscAdmTrans _priceDiscAdmTrans = priceDiscAdmTrans_ds.cursor();


        if( _priceDiscAdmTrans.relation != PriceType::LineDiscPurch && 

            _priceDiscAdmTrans.relation != PriceType::PricePurch &&

            _priceDiscAdmTrans.relation != PriceType::LineDiscSales &&

            _priceDiscAdmTrans.relation != PriceType::PriceSales

          )

        {

            error('Relation: Only price or line discount is valid selection!');

            throw exception::Error;

        }

    }

}

Extension add table field method display name for D365FO

 public static class PriceDiscAdmTrans_Extension

{

    [SysClientCacheDataMethodAttribute(true)]  //This attribute will cache your display method.

    public static display Name My_ItemName(PriceDiscAdmTrans _this)

    {

        return InventTable::find(_this.ItemRelation).productDescription('en-us');

    }

}

Import file TXT using job class in D365FO

 class JOB_ImportUOM

{        

    public static void main(Args _args)

    {        

        UnitOfMeasure                       _uom;

        UnitOfMeasureConversion             _uomConvert;

        UnitOfMeasureTranslation            _uomTranslation;

        UnitOfMeasureClass                  uomClass;


        container                           rec;

        TextStreamIo                        file;

        FileUploadTemporaryStorageResult    fileUpload;


        str                                 fromUnitx,toUnitx,fromUnitNamex,toUnitNamex,classUnitx;

        int                                 sep;

        int                                 counterx,i;

        ;

        fileUpload = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

        file = TextStreamIo::constructForRead(fileUpload.openResult());


        try

        {

            if (file)

            {

                if (file.status())

                {

                    throw error("@SYS52680");

                }

                file.inFieldDelimiter('^');

                //file.inRecordDelimiter('\r\n');

            }


            while (!file.status())

            {

                rec = file.read();


                fromUnitx                          = conPeek(rec, 1);

                fromUnitNamex                      = conPeek(rec, 2);

                classUnitx                         = conPeek(rec, 3);


                _uom = UnitOfMeasure::findBySymbol(fromUnitx);


                if(!_uom)

                {


                    ttsBegin;

                    _uom.clear();

                    _uom.Symbol = fromUnitx;


                    switch(classUnitx)

                    {

                        case 'Length':

                            uomClass = UnitOfMeasureClass::Length;

                            break;


                        case 'Liquid volume':

                            uomClass = UnitOfMeasureClass::LiquidVolume;

                            break;


                        case 'Mass':

                            uomClass = UnitOfMeasureClass::Mass;

                            break;


                        case 'Quantity':

                            uomClass = UnitOfMeasureClass::Quantity;

                            break;


                        default:

                            uomClass = UnitOfMeasureClass::Quantity;

                            break;


                    }

                    _uom.UnitOfMeasureClass =   uomClass;

                    _uom.IsInventUnit = NoYes::Yes; // custom field

                    _uom.validateWrite();

                    _uom.insert();

                    ttsCommit;


                    ttsBegin;

                    _uomTranslation.clear();

                    _uomTranslation.UnitOfMeasure = _uom.RecId;

                    _uomTranslation.Description = fromUnitNamex;

                    _uomTranslation.LanguageId = 'en-us';

                    _uomTranslation.validateWrite();

                    _uomTranslation.insert();

                    ttsCommit;


                    //info(strFmt("%1 %2 %3 %4",fromUnitx,classUnitx,_uom.Symbol, _uomTranslation.Description));

                    counterx++;

                }


            }

            info('Import success!');            

        }

        //try

        catch

        {

            error("Error!");

            return;

        }

        info(strFmt("Done! %1 records is imported !",counterx));

    }

}

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