Blog

Name is Anant Dubey and the intent to create this blog is to discuss the problems and issues that developer face in the dynamics AX development and to share the new things that come up with the new version of AX.

Tuesday, October 12, 2021

Enable delete button on Purchase order or change Purchase order status or delete purchase order versions in d365


To change that status to draft write following code where we will change its status to draft and further code to is to remove version of purchase order which necessary to make delete button enabled on purchase order form


code:-


/// <summary>
/// extension of class: ReqTransPoMarkFirm
/// </summary>
[ExtensionOf(classStr(ReqTransPoMarkFirm))]
final class ReqTransPoMarkFirmCFSClass_Extension
{
    public container conPurchOrders;

    /// <summary>
    /// updatePurchTable
    /// </summary>
    /// <param name = “_purchTable”>_purchTable</param>
    protected void updatePurchTable(PurchTable _purchTable)
    {
        conPurchOrders += _purchTable.PurchId;

        next updatePurchTable(_purchTable);
    }

    /// <summary>
    /// purchTablePostProcessing
    /// </summary>
    protected void purchTablePostProcessing()
    {
        next purchTablePostProcessing();

        for (int i = 1; i <= conLen(conPurchOrders); i++)
        {
            PurchTable purchTable = PurchTable::find(conPeek(conPurchOrders, i), true);

            if(purchTable.RecId)
            {
                ttsbegin;
                //delete the version created for po
                PurchTableVersion purchTableVersion = PurchTableVersion::findLatest(purchTable.PurchId, purchTable.DataAreaId, true);

                if(purchTableVersion.RecId)
                {
                    purchTableVersion.delete();
                }

                purchTable.ChangeRequestRequired = NoYes::No;
                purchTable.DocumentState         = VersioningDocumentState::Draft;
                purchTable.update();

                ttscommit;
            }
        }

    }


Ref: - https://www.cloudfronts.com/change-planned-purchase-order-status-as-draft-insted-of-default-approved/ 

Add link on infolog message in D365 fo

 class CFSMessageAPI

{
    public static void main(Args _args)
    {
        SalesTable            salesTable = SalesTable::find('SH-000121');
        MenuItemMessageAction actionData = new MenuItemMessageAction();

        actionData.MenuItemName(menuItemDisplayStr(SalesTable));
        actionData.TableName(tableStr(SalesTable));
        actionData.RecId(salesTable.RecId);
        str jsonData = FormJsonSerializer::serializeClass(actionData);

        int64 messageId = Message::AddAction(MessageSeverity::Informational, "Sales order details", salesTable.customerName(), MessageActionType::DisplayMenuItem, jsonData);
    }

}
Ref: - https://www.cloudfronts.com/message-api-messageaddaction-in-d365fo-version-10-0-10-pu34-new-feature/

Add FactBox in D365 fo

Ref: - https://www.cloudfronts.com/factbox-of-workflow-history-on-purchase-order-in-d365fo/ 

Details: 

Well, Factbox is a very pretty cool feature available from the earlier version AX 2012. It is very easy to achieve in Dynamics 365 as well. 

Here we will see how easy it is and steps for that. 







 

















As shown in the above image, we will be going to create factbox for the “Tracking details list”

Steps: 

Create the solution in Visual Studio and project for that. We’ll be required four objects mainly that is one display MenuItem, Table, Form (on which to display factbox), another Form (factbox). Reference attached below:

1. Table

For displaying workflow history, we need to create the extension of table WorkflowTrackingStatusTable and create the normal relation and its relevant properties as

2. Factbox

Now we are required to create the factbox of workflow history. For that we will use the effortless technique, where we will duplicate the standard form “WorkflowStatus” and will name as CFSPurchTableWorkflowHistoryFactBox (give name as per your naming convention standards)

After duplicating and renaming the form, we need to change the pattern as “custom”



After applying the custom pattern, delete the NavigationList which is not required in factbox, and do visible false ActionPane and PanelTab

After that create the new Grid and assign the data source to it in the property and put all the required fields to show in factbox

3. Display MenuItem

We will attach the created factbox form to the display menu item and relevant label “Workflow history”

4. Base form

Base form we call it as where we will attach the factbox. Here it is purchase form. Go to Parm section and create a new part and give it a relevant name and its properties

Properties: 

Data source: Attached data source with which workflow history is connected
Data Source Relation: WorkflowTable.RelationName
Name: Part name

That’s it. Build the project and go the frontend and check the output how it looks like.

Conclusion:

It results as (we can scroll left and right to see all the tracking details list)

Hurray, How pretty it looks like!

Synchronize DB using power shell in d365 fo

 

K:\AOSService\webroot\bin\Microsoft.Dynamics.AX.Deployment.Setup.exe 
-bindir "K:\AosService\PackagesLocalDirectory" 
metadatadir "K:\AosService\PackagesLocalDirectory" 
-sqluser "axdbadmin" -sqlserver "." -sqldatabase "AxDB" 
-setupmode "sync" -syncmode "fullall" 
-isazuresql "false" -sqlpwd "AOSWebSite@123" 
-logfilename "H:\MSSQL_LOGS\AxDB_log.log"
Ref: - https://www.cloudfronts.com/d365-finance-and-operations-database-synchronization-using-powershell/

Monday, October 11, 2021

Hide Dialog field from data contract in d365

 


[DataMemberAttribute,SysOperationControlVisibilityAttribute(false)]
public ItemId parmItemId(ItemId _itemId = itemId)
{
    ;

    itemId = _itemId;
    return itemId;
}
Ref:- https://www.miklix.com/dynamics-ax/hide-sysoperation-data-contract-dialog-field-in-dynamics-ax-2012/


Sunday, October 10, 2021

Data contract Class parmQuery method in d365 fo

 First, in the data contract class, the query will be stored packed in a string. Its parm method must be decorated with the AifQueryTypeAttribute attribute, like so (in this example I’ve used the SalesUpdate query, but you can replace this with any AOT query):

[   
    DataMemberAttribute,
    AifQueryTypeAttribute('_packedQuery', queryStr(SalesUpdate))
]
public str parmPackedQuery(str _packedQuery = packedQuery)
{
    ;

    packedQuery = _packedQuery;
    return packedQuery;
}

If you want the query to be decided by the controller class instead, you can also use an empty string. In that case, you also need to implement a couple of helper methods (which you probably should implement anyway for your own convenience when you need to access the query):

public Query getQuery()
{
    ;

    return new Query(SysOperationHelper::base64Decode(packedQuery)); 
}
public void setQuery(Query _query)
{
    ;

    packedQuery = SysOperationHelper::base64Encode(_query.pack());
}

If you need to initialize the query (for example, add ranges), you should implement an initQuery method

public void initQuery()
{
    Query queryLocal = this.getQuery();
    ;

    // add ranges, etc...

    this.setQuery(queryLocal);
}

You need to make sure to call this method from the controller class.


Ref: - https://www.miklix.com/dynamics-ax/using-a-query-in-a-sysoperation-data-contract-class-in-dynamics-ax-2012/

Thanks Mikkel

Convert Real to string in d365 fo

 strFmt() is enough, but that function always rounds off to two decimals, which is not always what I want.

Then there’s the num2str() function, which does work well, but requires you know ahead of time how many decimals and characters you want.

What if you just want the number converted to a string, with all digits and decimals? For some reason, this is something that always has me Googling because it is surprisingly obscure to do and I do it so rarely that I usually can’t remember exactly how – in most languages, I would expect that you could just concatenate the real to an empty string, but X++ doesn’t support that.

Anyway, the by far easiest way I have found to do this is by using a .NET call. There are multiple options here as well, with and without options for advanced formatting, but if you just want the really simple conversion of a real to a string, this will suffice:

stringValue = System.Convert::ToString(realValue);

If this code is to be run on the AOS (for example in a batch job), remember to assert the necessary code access permission first. In this case you’ll need an InteropPermission of type ClrInterop to call .NET code, so the full code example would look something like this:

new InteropPermission(InteropKind::ClrInterop).assert();
stringValue = System.Convert::ToString(realValue);
CodeAccessPermission::revertAssert();

Be aware that this simple System::Convert function uses the system’s current locale with respect to decimal point character. This may not be an issue for you, but for me who lives in an area where comma is used rather than period as decimal separator, it may require further processing if the string for example needs to be used in a file that must be readable by other systems.


Ref: - https://www.miklix.com/dynamics-ax/convert-a-real-to-string-with-all-decimals-in-dynamics-ax-2012/

Thanks Mikkel

Get All Enum Values in d365

 DictEnum dictEnum = new DictEnum(enumNum(SalesStatus));

Counter  c;
;

for (c = 0; c < dictEnum.values(); c++)
{
    info(strFmt('%1: %2', dictEnum.index2Symbol(c),
                          dictEnum.index2Label(c)));
}

This will output the symbol and label of each element in the enum to the infolog.


Ref: - https://www.miklix.com/dynamics-ax/how-to-iterate-over-the-elements-of-an-enum-from-x-code-in-dynamics-ax-2012/