Tuesday, December 27, 2016

Error in getting sid AX2012

Hi Guys,

I had recently setup a new environment and it was working fine. Then suddenly one of our team members reported that he is not able to post Purchase Packing Slip. The Packing Slip screen comes and when you press OK it just goes off and does nothing. He also got an error "Failed to create a session" but just once.

I was trying to set default company and I got "Error in getting SID" error. So after doing some hit and trial I reached a really silly solution. Whichever user is facing this issue just disable the UserId from SystemAdministrator->Common->Users->Users. Select the user, click "Edit", then uncheck the "Enabled" checkbox and save the record. and enable it. Now do the reverse and check the "Enabled" checkbox and save the record. Then ask him to re-login and check. And it works now. :)

Monday, December 19, 2016

Update SQLDictionary

When you have a TransactionDB from one environment and ModelDB from another, you will face DBSync issues. This is a very common problem where SQLDictionary in TransDB refers to the objects from older ModelDB hence it throws the error with TableId/FieldId mismatch or Typecasting issue.
The below job is used to update the SQLDictionary in some case when you have issues in DBSync:

static void fixTableAndFieldIds(Args _args)
{
    Dictionary dictionary = new Dictionary();
    SysDictTable dictTable;
    DictField dictField;
    TableId tableId;
    FieldId fieldId;
    SqlDictionary sqlDictionaryTable;
    SqlDictionary sqlDictionaryField;

    setPrefix("Update of data dictionary IDs");
    tableId = dictionary.tableNext(0);
    ttsbegin;

    while (tableId)
    {
        dictTable = new SysDictTable(tableId);

        setPrefix(dictTable.name());

        if (!dictTable.isSystemTable() && !dictTable.isView())
        {
            //Finds table in SqlDictionary by name in AOT, if ID was changed.
            //Empty field ID represents a table.
            select sqlDictionaryTable
                where sqlDictionaryTable.name == dictTable.name()
                && sqlDictionaryTable.fieldId == 0
                && sqlDictionaryTable.tabId != dictTable.id();

            if (sqlDictionaryTable)
            {
                info(dictTable.name());
                //Updates table ID in SqlDictionary
                if (ReleaseUpdateDB::changeTableId(
                    sqlDictionaryTable.tabId,
                    dictTable.id(),
                    dictTable.name()))
                {
                    info(strFmt("Table ID changed (%1 -> %2)", sqlDictionaryTable.tabId, dictTable.id()));
                }
            }

            fieldId = dictTable.fieldNext(0);

            //For all fields in table
            while (fieldId)
            {
                dictField = dictTable.fieldObject(fieldId);

                if (!dictField.isSystem())
                {
                    //Finds fields in SqlDictionary by name and compares IDs
                    select sqlDictionaryField
                        where sqlDictionaryField.tabId == dictTable.id()
                        && sqlDictionaryField.name == dictField.name()
                        && sqlDictionaryField.fieldId != 0
                        && sqlDictionaryField.fieldId != dictField.id();

                    if (sqlDictionaryField)
                    {
                        //Updates field ID in SqlDictionary
                        if (ReleaseUpdateDB::changeFieldId(
                            dictTable.id(),
                            sqlDictionaryField.fieldId,
                            -dictField.id(),
                            dictTable.name(),
                            dictField.name()))
                        {
                            info(strFmt("Pre-update: Field %1 - ID changed (%2 -> %3)",
                                dictField.name(),
                                sqlDictionaryField.fieldId,
                                -dictField.id()));
                        }
                    }
                }
                fieldId = dictTable.fieldNext(fieldId);
            }

            fieldId = dictTable.fieldNext(0);

            //For all fields in table
            while (fieldId)
            {
                dictField = dictTable.fieldObject(fieldId);

                if (!dictField.isSystem())
                {
                    select sqlDictionaryField
                        where sqlDictionaryField.tabId == dictTable.id()
                        && sqlDictionaryField.name == dictField.name()
                        && sqlDictionaryField.fieldId < 0;

                    if (sqlDictionaryField)
                    {
                        //Updates field ID in SqlDictionary
                        if (ReleaseUpdateDB::changeFieldId(
                            dictTable.id(),
                            sqlDictionaryField.fieldId,
                            -sqlDictionaryField.fieldId,
                            dictTable.name(),
                            dictField.name()))
                        {
                            info(strFmt("Final update: Field %1 - ID changed (%2 -> %3)",
                                dictField.name(),
                                sqlDictionaryField.fieldId,
                                -sqlDictionaryField.fieldId));
                        }
                    }
                }
                fieldId = dictTable.fieldNext(fieldId);
            }
        }
        tableId = dictionary.tableNext(tableId);
    }
    ttscommit;
}

Reference: http://sashanazarov.blogspot.in/2012/09/id-change-in-dynamics-ax-data-dictionary.html

Wednesday, December 14, 2016

Display method on InventOnHandItem form

Hi guys,

Today I faced a very typical issue while adding a new display field in InvnetOnHandItem. I had to show the sum of a quantity from a customized table based on ItemId and Warehouse. Now the problem here was the grouping between InventSum and InventDim due to which I was not getting the value of InventDimId in InventSum.

So after a lot of failed techniques, I found a solution to use the InventDim values and the code is below:

display public InventQtyReservOrdered ale_PendingVerificationQty(InventSum _inventSum)
{
    InboundWebOrderLine     inboundWebOrderLine;
    InventDim               joinDim, dimValues;
    InventDimParm           dimParm;

    dimValues.data(_inventSum.joinChild());
    dimParm.initFromInventDim(dimValues);

    select sum(QtyOrdered) from inboundWebOrderLine
        where inboundWebOrderLine.ItemId == _inventSum.ItemId
        && (inboundWebOrderLine.EcomMerchantLocation == dimValues.InventLocationId
        || inboundWebOrderLine.EcomMerchantLocation != '')
        && inboundWebOrderLine.EcomBridgeOrderItemStatus == EcomBridgeOrderItemStatus::Ordered;

    return inboundWebOrderLine.QtyOrdered;
}

This method worked like a charm and a had sigh of relief. :)