Thursday, June 19, 2025

Create API JSON Using Newtonsoft dll file on AX 2012 R3 CU8

 CLASS METHOD:

static str bodyJsonTransferSKN(    Amount amtValuex=0,

str currencyx='',

                                    str beneficiaryAccNox='',                                    

                                    str remarx='',

                                    str sourceAccountNox='', 

                                    str senderAccountNox='',

                                    str senderNamex=''

                               )

{

    str bodyRawJson;

    Counter                                 test;

    Newtonsoft.Json.Linq.JTokenWriter       writer;

    Newtonsoft.Json.Linq.JObject            jObject;

    ClrObject                               clrObject;

    TextIo                                  textIo;

    str                                     jsonStr, strDate, strTime;


    str amtValueStrx;

    str transDateStrx;


    ;


    amtValueStrx    = num2str(amtValuex,1,2,1,0);

    transDateStrx   = MyClass::getDateTimeZone();


    writer = new Newtonsoft.Json.Linq.JTokenWriter();


    writer.WriteStartObject();


    writer.WritePropertyName("sourceAccountNo");

    writer.WriteValue(sourceAccountNox);


    writer.WritePropertyName("beneficiaryAccountNo");

    writer.WriteValue(beneficiaryAccNox);


    writer.WritePropertyName("amount");


    writer.WriteStartObject();


        writer.WritePropertyName("value");

        writer.WriteValue(amtValueStrx);


        writer.WritePropertyName("currency");

        writer.WriteValue(currencyx);


    writer.WriteEndObject();


    writer.WritePropertyName("transactionDate");

    writer.WriteValue(transDateStrx);


    writer.WritePropertyName("remark");

    writer.WriteValue(remarx);


    writer.WritePropertyName("additionalInfo");


    writer.WriteStartObject();

       

        writer.WritePropertyName("senderAccountNo");

        writer.WriteValue(senderAccountNox);


        writer.WritePropertyName("senderName");

        writer.WriteValue(senderNamex);


    writer.WriteEndObject();


    writer.WriteEndObject();


    clrObject   = writer.get_Token();

    jObject     = clrObject;


    jsonStr     = jObject.ToString();


    bodyRawJson = jsonStr;


    return bodyRawJson;

}

CLASS METHOD:

static str getDateTimeZone()

{

    str         transDateStrx;

    utcDateTime systemDateTimex, currentDateTimex;

    Timezone    tzUserx;

    int         diffTimeMinutex, diffTimeHourx;


    ;


    systemDateTimex     = DateTimeUtil::getSystemDateTime();

    tzUserx             = DateTimeUtil::getUserPreferredTimeZone();


    diffTimeMinutex     = DateTimeUtil::getTimeZoneOffset(currentDateTimex, tzUserx);

    diffTimeHourx       = diffTimeMinutex/60;


    currentDateTimex    = DateTimeUtil::applyTimeZoneOffset(systemDateTimex, tzUserx);

    transDateStrx       = DateTimeUtil::toStr(currentDateTimex);


    transDateStrx       = strfmt('%1+0%2:00', transDateStrx, diffTimeHourx) ;


    return transDateStrx;

}


RESULT:

json result: 

{

  "sourceAccountNo": "",

  "beneficiaryAccountNo": "",

  "amount": {

    "value": "250000.00",

    "currency": "AAA"

  },

  "transactionDate": "2025-06-20T11:03:44+07:00",

  "remark": "",

  "additionalInfo": {

    "senderAccountNo": "",

    "senderName": ""

  }

}


Thursday, May 11, 2023

Extension button confirm purchase order on D365FO

[ExtensionOf(formControlStr(PurchTable, buttonConfirm))]

final class PurchTable_buttonConfirm_Extension

{

    public void clicked()

    {

        FormControl callerButton = any2Object(this) as FormControl;

        FormRun formRun = callerButton.formRun();

        FormDataSource purchTable_ds = formRun.dataSource(tablestr(PurchTable));

        PurchTable purchTable = purchTable_ds.cursor();

              

        info(strFmt('Before next PurchId %1', purchTable.PurchId ));


        next clicked();

        

        info(strFmt('After next PurchId %1', purchTable.PurchId ));

    }

}

Monday, September 26, 2022

Can not delete Main Account in D365FO. Main account XXXXXX is used 10 times as a default account on the Item groups(InventItemGroupForm) table in the Main account field.

When You try to delete Main Account and got error log as below: 



Main account Z116101 is used 10 times as a default account on the Item groups(InventItemGroupForm) table in the Main account field.

A financial dimension value is based on the Z116101 record and has been used on a transaction. You cannot delete the Z116101 record

But in Item Group setup form (or in Inventory posting) the Main account is not exist (not used by any Item group).


Solution for my case, 

 I had customized table : InventItemGroupForm, then show (visible) field: ItemGroupId.



Item Group Id: STG02A, is not shown on form. 

To delete the data in table InventItemGroupForm, create Item group Id with form InventItemGroup, use value: STG02A.

After you created item group id, all records related to Item group Id is deleted, then you can delete the Item group Id and delete the Main account related. 

 

Monday, August 29, 2022

Compare event handler when close child form with record value from caller form for D365FO

 class CustOpenTrans_form_Exthandler

{

    [PreHandlerFor(formStr(CustOpenTrans), formMethodStr(CustOpenTrans, close))]

    public static void CustOpenTrans_Post_close(XppPrePostArgs args)

    {        

        FormRun sender = args.getThis();

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

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

        info('Event: CustOpenTrans_Post_close');

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

    }


    [FormControlEventHandler(formControlStr(CustOpenTrans, Save), FormControlEventType::Clicked)]

    public static void Save_OnClicked(FormControl sender, FormControlEventArgs e)

    {

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

        info('Event: Save_OnClicked');

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

        

    }


    [FormEventHandler(formStr(CustOpenTrans), FormEventType::Closing)]

    public static void CustOpenTrans_OnClosing(xFormRun sender, FormEventArgs e)

    {

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

        info('Event: CustOpenTrans_OnClosing');

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

    }

}

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');

    }

}