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...