Thursday 16 December 2021

Getting error while doing Database Sync

Getting error while performing DB sync and Dynamics 365 Unified Operations: Batch management services not getting started


Hi,

Getting the below error while doing full DB Sync and Batch services also not getting started. Have done a full build with reference package and it has passed without an error. Its D365 Finance & Ops PU45 environment:

DB Sync error:

at Microsoft.Dynamics.Ax.MSIL.Interop.createSession(String userId, String company, String language, String partitionKey, Int32 workLoadType)
at Microsoft.Dynamics.AX.Framework.Database.Tools.SyncEngine.Run(String metadataDirectory, String sqlConnectionString, SyncOptions options)
at Microsoft.Dynamics.Ax.MSIL.Interop.throwException(Int32 ExceptionValue, interpret* ip)
at Microsoft.Dynamics.Ax.MSIL.Interop.createRunAsSession(String userId, String company, String language, String partitionKey, WorkLoadTypeEnum workLoadType)
at Microsoft.Dynamics.AX.Framework.Database.Tools.SyncEngine.FullTableViewSync()
at Microsoft.Dynamics.AX.Framework.Database.Tools.SyncEngine.RunSync()
Microsoft.Dynamics.Ax.Xpp.ErrorException: Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics 365 for Finance and Operations.
at Microsoft.Dynamics.AX.Framework.Database.Tools.SyncEngine.FullSync()
at Microsoft.Dynamics.Ax.MSIL.XppSession.Start(String userId, String company, String language, String partitionKey, Int32 workLoadType)
More Information: Invalid partitionKey parameter arguments passed to the method globalUserGuidCache::getUserGuid
at Microsoft.Dynamics.Ax.MSIL.XppSession.Start()
at Microsoft.Dynamics.AX.Framework.Database.Tools.LegacyCodepath.RunFullTableSync(SyncOptions syncOptions, String sqlConnectionString, IMetadataProvider metadataProvider)
Unhandled exception
at Microsoft.Dynamics.AX.Framework.Database.Tools.LegacyCodepath.ExecuteWithinAOS(SyncOptions syncOptions, String sqlConnectionString, IMetadataProvider metadataProvider, Func`1 func, Action`1 errorHandler)
syncengine.exe exited with code -1.

Resolution:

After some checks on the DB, I found out that the sysglobalconfiguration was set to azuresql even though I was working with a local sql server. Reason behind, DB backup has been taken from Tier-2 environment and restored into Dev box which is Tier-1 environment so after changing the configuration the DB Sync was succeeded and Batch management service gets started.

Before:











After (fix through sql query):

update sysglobalconfiguration set  value = 'SQLSERVER' where RecId = 5637144576

 

Happy Daxing...

Friday 26 November 2021

To post Packing slip through X++ in D365 F&O

Post Packing slip in D365 F&O

Today, I am going to share with you about how to post Packing slip for entire sales order or a particular sales order line. 

Here we go for entire Sales order:-

Post Packing slip for a sales order

To post Packing slip for an entire sales order, we need to pass SalesId to initialize data into Sales Parm tables.

/// <summary>
    /// to post Packing slip for an item requirement.
    /// </summary>
    /// <param name = "_salesId"> SalesId is passed as parameter. </param>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    public void postPackingSlip(SalesId _salesId, InventTransId _inventTransId)
    {
        SalesTable      salesTable = salesTable::find(_salesId);
        SalesFormLetter salesFormLetter;
        SalesParmLine   salesParmLine;
    
        // below line is to post Packing slip for a sales order
        salesFormLetter = SalesFormLetter::construct(DocumentStatus::PackingSlip);

        // If you want to post Packing slip for a project sales order, comment above line and uncomment below line
        //salesFormLetter = SalesFormLetter::construct(DocumentStatus::ProjectPackingSlip);

        // Do the steps manually, which normally are done in method
        salesFormLetter.salesTable(salesTable);
        salesFormLetter.initParmSalesTable(salesFormLetter.salesTable());
              salesFormLetter.transDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
        salesFormLetter.specQty(SalesUpdate::All);
        salesFormLetter.proforma(NoYes::No);        //salesFormLetter.salesParmUpdate().Proforma);
        salesFormLetter.printFormLetter(NoYes::No); //salesFormLetter.printFormLetter());
        salesFormLetter.printCODLabel(NoYes::No);
        salesFormLetter.printShippingLabel(NoYes::No);
        salesFormLetter.usePrintManagement(false);
        salesFormLetter.creditRemaining(salesFormLetter.creditRemaining());
        salesFormLetter.createParmUpdateFromParmUpdateRecord(SalesFormletterParmData::initSalesParmUpdateFormletter(salesFormLetter.documentStatus(),
                                                                                                                    salesFormLetter.pack(),
                                                                                                                    true,
                                                                                                                    false,
                                                                                                                    false));
        salesFormLetter.initParameters(salesFormLetter.salesParmUpdate(), Printout::Current);
        salesFormLetter.initLinesQuery();        
        salesFormLetter.run();     
    }

Post Packing slip for a sales order line (for a particular lot)

To post Packing slip for a particular lot (sales order line), we need to pass SalesId to initialize data into Sales Parm tables and then clear unwanted parm lines.

/// <summary>
    /// to post Packing slip for an item requirement.
    /// </summary>
    /// <param name = "_salesId"> SalesId is passed as parameter. </param>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    public void postPackingSlip(SalesId _salesId, InventTransId _inventTransId)
    {
        SalesTable      salesTable = salesTable::find(_salesId);
        SalesFormLetter salesFormLetter;
        SalesParmLine   salesParmLine;
    
        // below line is to post Packing slip for a sales order
        salesFormLetter = SalesFormLetter::construct(DocumentStatus::PackingSlip);

        // If you want to post Packing slip for a project sales order, comment above line and uncomment below line
        //salesFormLetter = SalesFormLetter::construct(DocumentStatus::ProjectPackingSlip);

        // Do the steps manually, which normally are done in method
        salesFormLetter.salesTable(salesTable);
        salesFormLetter.initParmSalesTable(salesFormLetter.salesTable());
        salesFormLetter.transDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
        salesFormLetter.specQty(SalesUpdate::All);
        salesFormLetter.proforma(NoYes::No);        //salesFormLetter.salesParmUpdate().Proforma);
        salesFormLetter.printFormLetter(NoYes::No); //salesFormLetter.printFormLetter());
        salesFormLetter.printCODLabel(NoYes::No);
        salesFormLetter.printShippingLabel(NoYes::No);
        salesFormLetter.usePrintManagement(false);
        salesFormLetter.creditRemaining(salesFormLetter.creditRemaining());
        salesFormLetter.createParmUpdateFromParmUpdateRecord(SalesFormletterParmData::initSalesParmUpdateFormletter(salesFormLetter.documentStatus(),
                                                                                                                    salesFormLetter.pack(),
                                                                                                                    true,
                                                                                                                    false,
                                                                                                                    false));
        salesFormLetter.initParameters(salesFormLetter.salesParmUpdate(), Printout::Current);
        salesFormLetter.initLinesQuery();

        // Delete unwanted records from SalesParmLine
        while select forupdate salesParmLine
                where salesParmLine.ParmId == salesFormLetter.parmId()
        {
            if (salesParmLine.InventTransId != _inventTransId)
            {
                salesParmLine.delete();
            }
        }
        salesFormLetter.run();     
    }



Happy Daxing...

To Register pick list through X++ in D365 F&O

Register Pick list in D365 F&O

Today, I am going to share with you about how to register pick list for entire sales order or a particular sales order line. 

Here we go for entire Sales order:-

Register pick list for a sales order

To register pick list for an entire sales order, we need to pass SalesId to initialize data into Sales Parm tables. Here, we are passing InventDimId from InventTrans table (you can pick InventDimId from your expected source as well).

    /// <summary>
    /// to register pick list for an item requirement.
    /// </summary>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    /// <param name = "_inventDimId"> InventDimId is passed as parameter. </param>
    public void registerPickingList(SalesId _salesId, InventTransId _inventTransId, InventDimId _inventDimId)
    {
        SalesParmLine       salesParmLine;
        WMSPickingRoute     wmsPickingRoute;
        WMSOrderTrans       wmsOrderTrans;

        Map                 wmsOrderTransMap    = new Map(Types::Int64, Types::Enum);
        List                pickingRouteList    = new List(Types::String);

        select firstonly ParmId,PickingRouteID,transRefId,RecId from wmsPickingRoute
        join OrigSalesId,ParmId,InventTransId,RecId from salesParmLine
            where wmsPickingRoute.ParmId        == salesParmLine.ParmId
            &&    wmsPickingRoute.transRefId    == salesParmLine.OrigSalesId
            &&    salesParmLine.OrigSalesId     == _salesId
            &&    salesParmLine.InventTransId   == _inventTransId;
            
        ttsbegin;
        while select forupdate wmsOrderTrans
                where wmsOrderTrans.routeId == wmsPickingRoute.PickingRouteID
                &&    wmsOrderTrans.inventTransRefId == _salesId
                &&    wmsOrderTrans.inventTransType == inventTransType::Sales
                &&    wmsOrderTrans.fullPallet == 0
        {
            if (wmsOrderTrans.InventTransId == _inventTransId && _inventDimId != strMin())
            {
                wmsOrderTrans.inventDimId = _inventDimId;
                wmsOrderTrans.update();
            }
        }
        ttscommit;

        pickingRouteList.addEnd(wmsPickingRoute.PickingRouteID);

        WMSPickingRoute::finishMulti(pickingRouteList.pack());
    }

Register pick list for a sales order line (for a particular lot)

To register pick list for a particular lot (sales order line), we need to pass SalesId to initialize data into Sales Parm tables and then clear unwanted parm lines. Here, we are passing InventDimId from InventTrans table (you can pick InventDimId from your expected source as well).

    /// <summary>
    /// to register pick list for an item requirement.
    /// </summary>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    /// <param name = "_inventDimId"> InventDimId is passed as parameter. </param>
    public void registerPickingList(SalesId _salesId, InventTransId _inventTransId, InventDimId _inventDimId)
    {
        SalesParmLine       salesParmLine;
        WMSPickingRoute     wmsPickingRoute;
        WMSOrderTrans       wmsOrderTrans;

        Map                 wmsOrderTransMap    = new Map(Types::Int64, Types::Enum);
        List                pickingRouteList    = new List(Types::String);

        select firstonly ParmId,PickingRouteID,transRefId,RecId from wmsPickingRoute
        join OrigSalesId,ParmId,InventTransId,RecId from salesParmLine
            where wmsPickingRoute.ParmId        == salesParmLine.ParmId
            &&    wmsPickingRoute.transRefId    == salesParmLine.OrigSalesId
            &&    salesParmLine.OrigSalesId     == _salesId
            &&    salesParmLine.InventTransId   == _inventTransId;
            
        ttsbegin;
        while select forupdate wmsOrderTrans
                where wmsOrderTrans.routeId == wmsPickingRoute.PickingRouteID
                &&    wmsOrderTrans.inventTransRefId == _salesId
                &&    wmsOrderTrans.inventTransType == inventTransType::Sales
                &&    wmsOrderTrans.fullPallet == 0
        {
            if (wmsOrderTrans.InventTransId == _inventTransId && _inventDimId != strMin())
            {
                wmsOrderTrans.inventDimId = _inventDimId;
                wmsOrderTrans.update();
            }
            else if (wmsOrderTrans.expeditionStatus == WMSExpeditionStatus::Activated ||
                        wmsOrderTrans.expeditionStatus == WMSExpeditionStatus::None)
            {
                wmsOrderTransMap.insert(wmsOrderTrans.RecId, wmsOrderTrans.expeditionStatus);

                wmsOrderTrans.cancel();
            }
        }
        ttscommit;

        pickingRouteList.addEnd(wmsPickingRoute.PickingRouteID);

        WMSPickingRoute::finishMulti(pickingRouteList.pack());

        MapEnumerator   wmsMapEnumerator = wmsOrderTransMap.getEnumerator();

        while (wmsMapEnumerator.moveNext())
        {
            wmsOrderTrans = null;
            ttsbegin;
            update_recordset wmsOrderTrans
                    setting expeditionStatus = wmsMapEnumerator.currentValue()
                    where wmsOrderTrans.RecId == wmsMapEnumerator.currentKey()
                    &&    wmsOrderTrans.routeId == wmsPickingRoute.PickingRouteID;
            ttscommit;
        }
    }



Happy Daxing...

To post Picking list through X++ in D365 F&O

Post Picking list in D365 F&O

Today, I am going to share with you about how to post Picking list for entire sales order or a particular sales order line. 

Here we go for entire Sales order:-

Post Picking list for a sales order

To post picking list for an entire sales order, we need to pass SalesId to initialize data into Sales Parm tables.

/// <summary>
    /// to post pick list for an item requirement.
    /// </summary>
    /// <param name = "_salesId"> SalesId is passed as parameter. </param>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    public void postPickingList(SalesId _salesId, InventTransId _inventTransId)
    {
        SalesTable      salesTable = salesTable::find(_salesId);
        SalesFormLetter salesFormLetter;
        SalesParmLine   salesParmLine;
    
        // below line is to post Picking list for a sales order
        salesFormLetter = SalesFormLetter::construct(DocumentStatus::PickingList);

        // If you want to post Picking list for a project sales order, comment above line and uncomment below line
        //salesFormLetter = SalesFormLetter::construct(DocumentStatus::ProjectPickingList);

        // Do the steps manually, which normally are done in method
        salesFormLetter.salesTable(salesTable);
        salesFormLetter.initParmSalesTable(salesFormLetter.salesTable());
              salesFormLetter.transDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
        salesFormLetter.specQty(SalesUpdate::All);
        salesFormLetter.proforma(NoYes::No);        //salesFormLetter.salesParmUpdate().Proforma);
        salesFormLetter.printFormLetter(NoYes::No); //salesFormLetter.printFormLetter());
        salesFormLetter.printCODLabel(NoYes::No);
        salesFormLetter.printShippingLabel(NoYes::No);
        salesFormLetter.usePrintManagement(false);
        salesFormLetter.creditRemaining(salesFormLetter.creditRemaining());
        salesFormLetter.createParmUpdateFromParmUpdateRecord(SalesFormletterParmData::initSalesParmUpdateFormletter(salesFormLetter.documentStatus(),
                                                                                                                    salesFormLetter.pack(),
                                                                                                                    true,
                                                                                                                    false,
                                                                                                                    false));
        salesFormLetter.initParameters(salesFormLetter.salesParmUpdate(), Printout::Current);
        salesFormLetter.initLinesQuery();        
        salesFormLetter.run();     
    }

Post Picking list for a sales order line (for a particular lot)

To post picking list for a particular lot (sales order line), we need to pass SalesId to initialize data into Sales Parm tables and then clear unwanted parm lines.

/// <summary>
    /// to post pick list for an item requirement.
    /// </summary>
    /// <param name = "_salesId"> SalesId is passed as parameter. </param>
    /// <param name = "_inventTransId"> InventTransId is passed as parameter. </param>
    public void postPickingList(SalesId _salesId, InventTransId _inventTransId)
    {
        SalesTable      salesTable = salesTable::find(_salesId);
        SalesFormLetter salesFormLetter;
        SalesParmLine   salesParmLine;
    
        // below line is to post Picking list for a sales order
        salesFormLetter = SalesFormLetter::construct(DocumentStatus::PickingList);

        // If you want to post Picking list for a project sales order, comment above line and uncomment below line
        //salesFormLetter = SalesFormLetter::construct(DocumentStatus::ProjectPickingList);

        // Do the steps manually, which normally are done in method
        salesFormLetter.salesTable(salesTable);
        salesFormLetter.initParmSalesTable(salesFormLetter.salesTable());
        salesFormLetter.transDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
        salesFormLetter.specQty(SalesUpdate::All);
        salesFormLetter.proforma(NoYes::No);        //salesFormLetter.salesParmUpdate().Proforma);
        salesFormLetter.printFormLetter(NoYes::No); //salesFormLetter.printFormLetter());
        salesFormLetter.printCODLabel(NoYes::No);
        salesFormLetter.printShippingLabel(NoYes::No);
        salesFormLetter.usePrintManagement(false);
        salesFormLetter.creditRemaining(salesFormLetter.creditRemaining());
        salesFormLetter.createParmUpdateFromParmUpdateRecord(SalesFormletterParmData::initSalesParmUpdateFormletter(salesFormLetter.documentStatus(),
                                                                                                                    salesFormLetter.pack(),
                                                                                                                    true,
                                                                                                                    false,
                                                                                                                    false));
        salesFormLetter.initParameters(salesFormLetter.salesParmUpdate(), Printout::Current);
        salesFormLetter.initLinesQuery();

        // Delete unwanted records from SalesParmLine
        while select forupdate salesParmLine
                where salesParmLine.ParmId == salesFormLetter.parmId()
        {
            if (salesParmLine.InventTransId != _inventTransId)
            {
                salesParmLine.delete();
            }
        }
        salesFormLetter.run();     
    }


Happy Daxing...

Thursday 11 February 2021

Find and Delete workspace from TFS through Visual studio command prompt

 

How to delete workspace from TFS Visual Studio

In this blog, we will see how we can delete any of the TFS workspace which is assigned to different user


Even if tried to remove/delete the workspace from Visual Studio, We’re unable to map existing workspace to new user.  

In such scenario, It is necessary to delete the workspace explicitly while getting the error as below 

"The working folder 'Workspace_Folder_Local_Path' is already in use by  the workspace : on computer

Solution: 

1. Open Developer Command Prompt for VS2015 from Start menu Or, type the word Command in search box and select "VS2015 x86 x64 Cross Tools Command Prompt".


2. For getting the list of workspaces, run the below command
tf workspaces

3. For deleting a workspace, run the below command

Syntax: 

TF workspace /delete workspacename;owner_id

Real command: 

TF workspace /delete xxx-Dev-4;treddi




Happy DAXing...