Wednesday 23 January 2019

Foreign currency revaluation currencies not showing in drop down in dynamics 365 finance & Operations 8.0

In the previous versions you can see all currency codes in the currency drop down, but
Dynamics 365 finance and operations 8.0 you don't see all currency codes.

The reason Microsoft changed the logic to see the currency codes only for posted transactions.

In the below example I don't have GL transactions for the selected FROM- TO date. So , that's the reason the currency drop down is empty.





Now, we can see the currency codes as the transactions available in the system between the selected date range.




Below is the query filtering currency code.
Classes -> LedgerExchAdj -> constructCurrencySelectionQuery

private Query constructCurrencySelectionQuery()
    {
        Query query = new Query();

        this.setInternalDateRange();

        QueryBuildDataSource qbdsCurrency = query.addDataSource(tableNum(Currency));
        qbdsCurrency.addGroupByField(fieldNum(Currency, CurrencyCode));
        qbdsCurrency.addGroupByField(fieldNum(Currency, RecId));
        qbdsCurrency.addSortField(fieldNum(Currency, CurrencyCode));

        QueryBuildDataSource qbds = qbdsCurrency.addDataSource(tableNum(GeneralJournalAccountEntry));
        qbds.joinMode(JoinMode::ExistsJoin);
        qbds.addLink(fieldNum(GeneralJournalAccountEntry, TransactionCurrencyCode), fieldNum(Currency, CurrencyCode));

        QueryBuildDataSource qbdsHeader = qbds.addDataSource(tableNum(GeneralJournalEntry));
        qbdsHeader.joinMode(JoinMode::ExistsJoin);
        qbdsHeader.addLink(fieldNum(GeneralJournalAccountEntry, GeneralJournalEntry), fieldNum(GeneralJournalEntry, RecId));
        qbdsHeader.addRange(fieldNum(GeneralJournalEntry, Ledger)).value(SysQuery::value(Ledger::current()));

        QueryBuildRange qbr = qbdsHeader.addRange(fieldNum(GeneralJournalEntry, AccountingDate));
        qbr.value(SysQuery::range(fromDate, toDate));

        query.clearAllFields();
        qbdsCurrency.addSelectionField(fieldNum(Currency, CurrencyCode));

        return query;
    }

Debug batch jobs in Dynamics 365 Finance & Operation / AX 7.0

Sometimes we may need to debug batch jobs execution. In AX 2012 we have to attached Visual Studio to the 'AOS' process and debug the IL code. It's pretty much the same still and got even easier because X++ now is a .NET language. 

So navigate to Debug / Attach To Process in Visual Studio and make sure to select show processes from all users. The batch service has the obvious name Batch.exe (its location is C:\CustomerServiceUnit\DOBind\Packages\Cloud\AosWebApplication\
AosWebApplication.csx\roles\AosWeb\approot\bin – at least on locally deployed machines and this is only for informational purposes, usually you won’t need to know). 

Attach to that process and be able to debug the X++ code that is executed there.




Tuesday 22 January 2019

Allow multiple transactions within one voucher

General ledger -> Ledger setup -> General ledger parameters -> Ledger > Allow multiple transactions within one voucher.

General that are default set to "No". Set it to yes.



There can only be one vendor or customer transaction per voucher in Dynamics 365 finance and operations 8.0 version

I was getting below error while posting a GL transaction.

There can only be one vendor or customer transaction per voucher 

 To fix this error we need to Allow multiple transactions within one voucher.

General ledger -> Ledger setup -> General ledger parameters -> Ledger > Allow multiple transactions within one voucher.

General that are default set to "No". Set it to yes.






Tuesday 15 January 2019

Document type to keep attachments of ER configurations has not been defined in ER parameters dynamics 365 finance & Operations

I was getting the below error while generating electronic payment for vendor payments in d365 F&O with 8.0 version.

Document type to keep attachments of ER configurations has not been defined in ER parameters .
The payments cannot be generated

Reason: Documents types are not configures in the Electronic parameters.

Solution:

 Go to Organization administration -> work spaces -> Electronic reporting

Then click on "Electronic reporting parameters" (I'm using 8.0 version with PL 22)




Update "Documents types" in the attachments as shown below.



That's it.

@Rahul

Monday 14 January 2019

Call Stack in Visual Studio Dynamics 365 Finance & operations

To open the Call Stack window in Visual Studio, from the Debug menu, choose Windows>Call Stack  while debugging your code.




Wednesday 9 January 2019

How to get an invoice number of a payment in dynamics AX 2012 / D365 F&O X++

Below is the code I have written  in D365 F&O for getting the invoice numbers for payments which are settled with the invoices.

Please change the code according to your requirement.

class VendTransTest
{
    /// <summary>
    /// Runs the class with the specified arguments.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {
       
        VendTrans               vendTransPayment, vendTransinvoice;
        TransDate               fromTransDate = 01\01\2018;
        TransDate               toTransDate = str2Date("12/31/2018", 213);
        ;
        while select vendTransPayment where vendTransPayment.TransType == LedgerTransType::Payment
                                &&  vendTransPayment.TransDate >= fromTransDate
                                && vendTransPayment.TransDate <= toTransDate
        {
                         
                while select vendTransinvoice where vendTransinvoice.LastSettleVoucher == vendTransPayment.Voucher
                 {
                            info(vendTransinvoice.invoice);
                 }

            }
        }
       
    }

}

@Rahul 

Monday 7 January 2019

XppPrePostArgs : How to pass a value between Pre and Post event handler using XppPrePostArgs in D365 F&O / AX 7.0

Recently we came across a scenario where we needed to check if a field has changed after super() in update method of a table. Back in the days of AX 2012 you could easily compare original field’s value with current using orig() method before super() and call necessary logic after.
public void update()
{
    boolean myFieldHasChanged = this.MyField != this.orig().MyField;

    super();

    if (myFieldHasChanged)
    {
        this.doStuff();
    }
}
Now we want to do the same using extensions. We can create Pre and Post event handlers, but they are static, so we need a way to pass a value between them.
First option is to use static field, like it’s done in RunBase extension example
public static class MyTableEventHandler
{
    private static UnknownNoYes myFieldHasChanged;

    [PreHandlerFor(tableStr(MyTable), tableMethodStr(MyTable, update))]
    public static void MyTable_Pre_update(XppPrePostArgs _args)
    {
        MyTable myTable = _args.getThis() as MyTable;

        if (myTable.MyField != myTable.orig().MyField)
        {
            MyTableEventHandler::myFieldHasChanged = UnknownNoYes::Yes;
        }
        else
        {
            MyTableEventHandler::myFieldHasChanged = UnknownNoYes::No;
        }
    }

    [PostHandlerFor(tableStr(MyTable), tableMethodStr(MyTable, update))]
    public static void MyTable_Post_update(XppPrePostArgs _args)
    {
        MyTable myTable = _args.getThis() as MyTable;

        if (MyTableEventHandler::myFieldHasChanged == UnknownNoYes::Yes)
        {
            myTable.doStuff();
        }

        MyTableEventHandler::myFieldHasChanged = UnknownNoYes::Unknown;
    }
}
Another option is to use XppPrePostArgs as a vehicle for new parameter. XppPrePostArgs has collection of parameters under the hood, so nothing stops us to add one more and framework will take care of passing it between Pre and Post event handler!
XppPrePostArgs_collection.jpg
public static class MyTableEventHandler_XppPrePostArgs
{
    const static str myFieldHasChangedArgName = 'myFieldHasChanged';

    [PreHandlerFor(tableStr(MyTable), tableMethodStr(MyTable, update))]
    public static void MyTable_Pre_update(XppPrePostArgs _args)
    {
        MyTable myTable = _args.getThis() as MyTable;

        boolean myFieldHasChanged = myTable.MyField != myTable.orig().MyField;

        <strong>_args.addArg(MyTableEventHandler_XppPrePostArgs::myFieldHasChangedArgName, myFieldHasChanged);</strong>
    }

    [PostHandlerFor(tableStr(MyTable), tableMethodStr(MyTable, update))]
    public static void MyTable_Post_update(XppPrePostArgs _args)
    {
        MyTable myTable = _args.getThis() as MyTable;

        <strong>boolean myFieldHasChanged = _args.getArg(MyTableEventHandler_XppPrePostArgs::myFieldHasChangedArgName);
</strong>
        if (myFieldHasChanged)
        {
            myTable.doStuff();
        }
    }

Actual Post : https://community.dynamics.com/365/financeandoperations/b/ievgensaxblog/archive/2017/07/01/d365o-trick-to-pass-a-value-between-pre-and-post-event-handler-using-xppprepostargs

Friday 4 January 2019

File contains duplicate rows, cannot insert data into staging due to unique key violation error while importing sales orders in D365 F&O / AX 7.0

Hi All,

I was getting the below error while importing the sales orders into the Ax system.

File contains duplicate rows, cannot insert data into staging due to unique key violation

Reason:

We upgraded D365 from 7.0 to 8.0 version and Microsoft added InventoryLotId field in RowIdx index and made it as an unique key in SalesOrderLineV2Staging table.

So, due to that I was not able to import any sales orders with multiple lines.But, I was able to import with a single line.


Solution:

Added "INVENTORYLOTID" field in the XML template as shown below and updated the data mapping in the sales order data entity with INVENTLOTID and changed to "Auto generated"





Afterwards, I was successfully imported the orders without any issues.

@Rahul


Adding a newline into a string in C# and X++

Below is the sample code we can use for  adding a newline after every occurrence of "@" symbol in the string in C#   using System...