Thursday, March 23, 2023

Inventory marking & UnMarking in D365FO X++

 //UnMark

InventTransOrigin::deleteMarking(InventTransOrigin::findByInventTransId(<CurPOInventTransId>).RecId,

                        InventTransOrigin::findByInventTransId(<RefSOInventTransId>).RecId,

                       <Qty>);

//Mark

InventTransOrigin::updateMarking(<CurPOInventTransId>, <RefSOInventTransId>, -1* <Qty>);

Tuesday, March 21, 2023

Picking qty for sales order line in D365FO X++

 Class SAN_PickingQtyOrder

{

    public static void DoPickQtyForOrderLine(SalesLine  _SalesLine, Qty  _qtyPicked)

    {

        InventTransWMS_Pick         inventTransWMS_Pick;

        TmpInventTransWMS           tmpInventTransWMS;

        InventDim                   inventDim;

        InventTrans                 inventTrans;

        Query                       query;           

 

        inventTrans = SAN_PickingQtyOrder::locateSalesLineAndInventTrans(_SalesLine.SalesId, _SalesLine.LineNum);       

 

        if(inventTrans)

        {

            query = SAN_PickingQtyOrder::initInventTransQuery(_SalesLine);

            inventTransWMS_Pick = InventTransWMS_Pick::newStandard(tmpInventTransWMS, query

            inventTrans.Qty = 0 - _qtyPicked; // Quantity needs to be negative.

            inventTransWMS_Pick.createFromInventTrans(inventTrans);

            boolean ret = inventTransWMS_Pick.updateInvent();

            if (!ret)

            {

                throw error("An error occurred when marking IC sales order lines as picked");

            }

        }

        else

        {

            throw error("@Retail:InventTransRecordNotFound");

        }

    }

 

    private static InventTrans locateSalesLineAndInventTrans(SalesId salesId, LineNum salesLineNumber)

    {

        InventTransOrigin   inventTransOrigin;

        InventTrans         inventTrans;

        SalesLine           salesLine;

 

        select firstonly inventTrans

            join RecId from inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && InventTrans.StatusIssue == StatusIssue::ReservPhysical

            join salesLine where salesLine.InventTransId == inventTransOrigin.InventTransId && salesLine.SalesId == salesId && salesLine.LineNum == salesLineNumber;

 

        if (!inventTrans)

        {

            select firstonly inventTrans

            join RecId from inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && InventTrans.StatusIssue == StatusIssue::ReservOrdered

            join  salesLine where salesLine.InventTransId == inventTransOrigin.InventTransId && salesLine.SalesId == salesId && salesLine.LineNum == salesLineNumber;

        }        

 

        if (!inventTrans)

        {

            select firstonly inventTrans

            join RecId from inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && InventTrans.StatusIssue == StatusIssue::OnOrder

            join salesLine where salesLine.InventTransId == inventTransOrigin.InventTransId && salesLine.SalesId == salesId && salesLine.LineNum == salesLineNumber;

        }

        return inventTrans;

    }

 

    private static Query initInventTransQuery(SalesLine salesLine)

    {

        Query                   query;

        InventDimParm           inventDimParmActive;

        InventMovement          inventMovement;

        QueryBuildDataSource    qbdsInventTrans;

        InventTransOriginId     inventTransOriginId;

 

 

 

        query = new Query();

        qbdsInventTrans = query.addDataSource(tableNum(InventTrans));

        qbdsInventTrans.clearDynalinks();

        qbdsInventTrans.clearRanges();

        qbdsInventTrans.addRange(fieldNum(InventTrans,StatusReceipt)).value(SysQuery::value(StatusReceipt::None));

        qbdsInventTrans.addRange(fieldNum(InventTrans,StatusIssue)).value(SysQuery::range(StatusIssue::Picked,StatusIssue::OnOrder));

        inventMovement      = InventTransWMS_Pick::inventMovement(salesLine);

        inventTransOriginId = inventMovement.inventTransOriginId();

 

        SAN_PickingQtyOrder::setInventTransOriginQueryRange(qbdsInventTrans, salesLine, inventMovement, inventTransOriginId);

        inventMovement.inventDimGroupSetup().inventDimParmActive(inventDimParmActive);

        return query;

    }

 

    private static void setInventTransOriginQueryRange(

            QueryBuildDataSource _qbdsInventTrans,

            Common               _callerTable,

            InventMovement       _inventMovement,

            InventTransOriginId  _inventTransOriginId = _inventMovement ? _inventMovement.inventTransOriginId() : 0)

    {

        QueryBuildRange         qbRange;

        InventTransChildType    inventTransChildType;

        InventTransChildRefId   inventTransChildRefId;

        str                     rangeStr;

        int                     inventTransChildTypeInt;

 

        if (_qbdsInventTrans)

        {

            if (_inventMovement)

            {

                if (_inventMovement.transChildType())

                {

                    inventTransChildType  = _inventMovement.transChildType();

                    inventTransChildRefId = _inventMovement.transChildRefId();

                }

                else

                {

                    inventTransChildType  = InventTransChildType::None;

                    inventTransChildRefId = '';

                }

            }

            inventTransChildTypeInt = enum2int(inventTransChildType); 

            qbRange = _qbdsInventTrans.addRange(fieldNum(InventTrans,InventTransOrigin));

            rangeStr = strFmt('((%1.%2 == %3) && (%4.%5 == %6)',

                                     _qbdsInventTrans.name(),

                                     fieldStr(InventTrans,InventTransOrigin),

                                     queryValue(_inventTransOriginId),

                                     _qbdsInventTrans.name(),

                                     fieldStr(InventTrans,TransChildType),

                                     inventTransChildTypeInt);

            if (inventTransChildRefId)

            {

                rangeStr = rangeStr + strFmt(' && (%1.%2 == \"%3\"))',

                                     _qbdsInventTrans.name(),

                                     fieldStr(InventTrans,TransChildRefId),

                                     queryValue(inventTransChildRefId));

            }

            else

            {

                rangeStr = rangeStr + strFmt(' && (%1.%2 == \"\"))',

                                     _qbdsInventTrans.name(),

                                     fieldStr(InventTrans,TransChildRefId));

            }

            qbRange.value(rangeStr);

        }

    }

}

 


New Print management related logic in D365FO X++

/// <summary>

/// Event handler class to define customize reprot list based on new print management type

/// </summary>

class SAN_PrintMgmtDocTypeCustAccStatementEventHandlers

{

    [SubscribesTo(classStr(PrintMgmtDocType), delegateStr(PrintMgmtDocType, getDefaultReportFormatDelegate))]

    public static void getDefaultReportFormatDelegate(PrintMgmtDocumentType _docType, EventHandlerResult _result)

    {

        switch(_docType)

        {

            case PrintMgmtDocumentType::SAN_CustAccountStatement:

                _result.result(ssrsReportStr(SAN_CustAccountStatementsExt, Report));

                break;

        }

    }


    /// <summary>

    /// Delegate handler for the getQueryRangeFieldsDelegate method of the <c>PrintMgmtDocType</c> class.

    /// </summary>

    /// <param name = "_docType"><c>PrintMgmtDocumentType</c> enumeration value.</param>

    /// <param name = "_result">The <c>EventHandlerResult</c> object.</param>

    [SubscribesTo(classstr(PrintMgmtDocType), delegatestr(PrintMgmtDocType, getQueryRangeFieldsDelegate))]

    public static void getQueryRangeFieldsDelegateHandler(PrintMgmtDocumentType _docType, EventHandlerResult _result)

    {

        List fields = new List(Types::Integer);

        if(_docType == PrintMgmtDocumentType::SAN_CustAccountStatement)

        {

            fields.addEnd(fieldNum(CustTable, AccountNum));

            fields.addEnd(fieldNum(CustTable, CustGroup));

            fields.addEnd(fieldNum(CustTable, AccountStatement));

            _result.result(fields);

        }

    }


    /// <summary>

    /// Delegate handler for the getPartyTypeDelegate method of the <c>PrintMgmtDocType</c> class.

    /// </summary>

    /// <param name = "_docType"><c>PrintMgmtDocumentType</c> enumeration value.</param>

    /// <param name = "_jour"><c>Common</c> object containing journal record.</param>

    /// <param name = "_result">The <c>EventHandlerResult</c> object.</param>

    [SubscribesTo(classstr(PrintMgmtDocType), delegatestr(PrintMgmtDocType, getPartyTypeDelegate))]

    public static void getPartyTypeDelegateHandler(PrintMgmtDocumentType _docType, Common _jour, EventHandlerResult _result)

    {

        if (_docType == PrintMgmtDocumentType::SAN_CustAccountStatement)

        {

            _result.result(PrintMgmtPrintDestinationPartyType::Customer);

        }

    }


    /// <summary>

    /// Delegate handler for the getQueryTableIdDelegate method of the <c>PrintMgmtDocType</c> class.

    /// </summary>

    /// <param name = "_docType"><c>PrintMgmtDocumentType</c> enumeration value.</param>

    /// <param name = "_result">The <c>EventHandlerResult</c> object.</param>

    [SubscribesTo(classstr(PrintMgmtDocType), delegatestr(PrintMgmtDocType, getQueryTableIdDelegate))]

    public static void getQueryTableIdDelegateHandler(PrintMgmtDocumentType _docType, EventHandlerResult _result)

    {

        if (_docType == PrintMgmtDocumentType::SAN_CustAccountStatement)

        {

            _result.result(tableNum(CustTable));

        }

    }


}




/// <summary>

/// The <c>FormLetterReport</c> class is used to retrieve the print management settings for the

/// <c>PrintMgmtDocumentType</c> enumeration value.

/// </summary>

[PrintMgmtDocumentTypeFactoryAttribute(PrintMgmtDocumentType::SAN_CustAccountStatement)]

class SAN_SalesFormLetterReport_CustAccountStatement extends SalesFormLetterReport

{

    /// <summary>

    /// Gets the default printer settings for the specified <c>PrintSetupOriginalCopy</c> enumeration value.

    /// </summary>

    /// <param name="_printCopyOriginal">

    /// The <c>PrintSetupOriginalCopy</c> enumeration value that specifies whether the Original or Copy

    /// destinations should be retrieved.

    /// </param>

    /// <returns>

    /// The default printer settings for the specified <c>PrintSetupOriginalCopy</c> enumeration value.

    /// </returns>

    protected container getDefaultPrintJobSettings(PrintSetupOriginalCopy _printCopyOriginal)

    {

        SRSPrintDestinationSettings printSettings = PrintMgmtSetupSettings::initDestination();


        printSettings.printMediumType(SRSPrintMediumType::Screen);

        return printSettings.pack();

    }


    /// <summary>

    /// Gets the <c>PrintMgmtDocumentType</c> enumeration value that specifies the document that this

    /// <c>FormLetterReport</c> class controls.

    /// </summary>

    /// <returns>

    /// The <c>PrintMgmtDocumentType</c> enumeration value that specifies the document that this

    /// <c>FormLetterReport</c> class controls.

    /// </returns>

    /// <remarks>

    /// This value is used to retrieve the appropriate Print Management settings for the report.

    /// </remarks>

    public PrintMgmtDocumentType getPrintMgmtDocumentType()

    {

        return PrintMgmtDocumentType::SAN_CustAccountStatement;

    }


    /// <summary>

    /// Gets the <c>PrintMgmtHierarchyType</c> enumeration value that specifies the hierarchy that this

    /// <c>FormLetterReport</c> class uses.

    /// </summary>

    /// <returns>

    /// The <c>PrintMgmtHierarchyType</c> enumeration value that specifies the hierarchy that this

    /// <c>FormLetterReport</c> class uses.

    /// </returns>

    /// <remarks>

    /// This value is used to retrieve the appropriate Print Management settings for the report.

    /// </remarks>

    protected PrintMgmtHierarchyType getPrintMgmtHierarchyType()

    {

        return PrintMgmtHierarchyType::Sales;

    }


    /// <summary>

    /// Gets the <c>PrintMgmtNodeType</c> enumeration value that specifies the node that this

    /// <c>FormLetterReport</c> class uses.

    /// </summary>

    /// <returns>

    /// The <c>PrintMgmtNodeType</c> enumeration value that specifies the node that this

    /// <c>FormLetterReport</c> class uses.

    /// </returns>

    /// <remarks>

    /// This value is used to retrieve the appropriate Print Management settings for the report.

    /// </remarks>

    protected PrintMgmtNodeType getPrintMgmtNodeType()

    {

        return PrintMgmtNodeType::CustTable;

    }


}




/// <summary>

/// Extension class for PrintMgmtDelegatesHandler to handle custom print management type

/// </summary>

[ExtensionOf(classStr(PrintMgmtDelegatesHandler))]

final class PrintMgmtDelegatesHandlerCls_SAN_Extension

{

    /// <summary>

    /// Determines the party type for a journal records and the current document type.

    /// </summary>

    /// <param name="_jour">

    /// A journal record.

    /// </param>

    /// <returns>

    /// A member of <c>PrintMgmtPrintDestinationPartyType</c>.

    /// </returns>

    /// <exception cref="Exception::Error">

    /// An invalid combination of journal record and document type was found.

    /// </exception>

    protected static PrintMgmtPrintDestinationPartyType getPartyType(PrintMgmtDocumentType _docType, Common _jour)

    {

        PrintMgmtPrintDestinationPartyType polPartyType;


        polPartyType = next getPartyType(_docType, _jour);


        switch (_docType)

        {

            case PrintMgmtDocumentType::SAN_CustAccountStatement:

                return PrintMgmtPrintDestinationPartyType::Customer;

        }


        return polPartyType;

    }


}


/// <summary>

/// Extension class for PrintMgmtNode_CustTable to incoporate new print management node as Polaris customer account statement

/// </summary>

[ExtensionOf(classStr(PrintMgmtNode_CustTable))]

final class PrintMgmtNode_CustTableCls_SAN_Extension

{

    public List getDocumentTypes()

    {

        List ret;

        ret = new List(Types::Enum);

        ret = next getDocumentTypes();

        ret.addEnd(PrintMgmtDocumentType::SAN_CustAccountStatement);


        return ret;

    }


}



/// <summary>

/// This class is used to extend the print management

/// </summary>

[ExtensionOf(classStr(PrintMgmtNode_Sales))]

final class PrintMgmtNode_SalesCls_SAN_Extension

{

    /// <summary>

    /// This class is used to extend the print management

    /// </summary>

    /// <returns>docTypes</returns>

    public List getDocumentTypes()

    {

        List docTypes; 

        docTypes = new List(Types::Enum); 

        docTypes = next getDocumentTypes();

        docTypes.addEnd(PrintMgmtDocumentType::SAN_CustAccountStatement);

        return docTypes;

    }


}



/// <summary>

/// New class to populate the data in PrintMgmtReportFormat table

/// </summary>

[ExtensionOf(classStr(PrintMgmtReportFormatPopulator))]

final class PrintMgmtReportFormatPopulatorCls_SAN_Extension

{

    #PrintMgmtSetup


    /// <summary>

    /// extension of method to populate the data in PrintMgmtReportFormat table

    /// </summary>

    protected void addDocuments()

    {

        next addDocuments();

        this.addOther(PrintMgmtDocumentType::SAN_CustAccountStatement, ssrsReportStr(SAN_CustAccountStatementsExt, Report), ssrsReportStr(SAN_CustAccountStatementsExt, Report), #NoCountryRegionId);

    }


}

Post sales packing slip in D365FO X++

     protected void executePostingDataPerOrder(str   _salesId)

    {

        SalesFormLetter_PackingSlip         salesFormLetter_PackingSlip;

        salesFormletterParmData             salesFormLetterParmData;

        SalesParmTable                      salesParmTable;

        salesParmUpdate                     salesParmUpdate;

        SalesTable                          salestable = SalesTable::find(_salesId, true);

        SalesLine                           salesLine;

        TransDate                           PackingSlipDate;

        

        PackingSlipDate = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());

        if (salestable && salestable.SalesStatus == SalesStatus::Backorder)

        {

            salesFormLetterParmData = salesFormletterParmData::newData(DocumentStatus::PackingSlip, VersioningUpdateType::Initial);


            salesFormLetterParmData.parmOnlyCreateParmUpdate(true);

            salesFormLetterParmData.createData(false);

            salesParmUpdate = salesFormLetterParmData.parmParmUpdate();


            salesParmTable.clear();

            salesParmTable.TransDate                = PackingSlipDate;

            salesParmTable.Ordering                 = DocumentStatus::PackingSlip;

            salesParmTable.ParmJobStatus            = ParmJobStatus::Waiting;

            salesParmTable.salesId                  = salesTable.salesId;

            salesParmTable.salesName                = salesTable.salesName;

            salesParmTable.DeliveryName             = salesTable.DeliveryName;

            salesParmTable.DeliveryPostalAddress    = salesTable.DeliveryPostalAddress;

            salesParmTable.CustAccount              = salesTable.CustAccount;

            salesParmTable.CurrencyCode             = salesTable.CurrencyCode;

            salesParmTable.InvoiceAccount           = salesTable.InvoiceAccount;

            salesParmTable.ParmId                   = salesParmUpdate.ParmId;

            salesParmTable.insert();


            while select salesLine

                        where salesLine.SalesId == _salesId

                            && salesLine.InventTransId

            {

                salesParmLine.Clear();

        salesParmLine.InitFromsalesLine(salesline);

        salesParmLine.DeliverNow    = salesline.SalesQty;

        salesParmLine.ParmId        = salesParmTable.ParmId;

        salesParmLine.TableRefId    = salesParmTable.TableRefId;

        salesParmLine.setQty(DocumentStatus::PackingSlip, false, true);

        salesParmLine.setLineAmount(salesline);

        salesParmLine.closed        = NoYes::No; //Set to Yes, if want to short close order line

        salesParmLine.insert();


        salesParmSubLine.clear();

        salesParmSubLine.initValue();

        salesParmSubLine.initFromSalesParmLine(salesParmLine);

        salesParmSubLine.InventNow              = salesLine.SalesQty;

        salesParmSubLine.DeliverNow             = salesLine.SalesQty;

        salesParmSubLine.insert();

            }



            salesFormLetter_PackingSlip = SalesFormLetter::construct(DocumentStatus::PackingSlip);

            salesFormLetter_PackingSlip.transDate(PackingSlipDate);

            salesFormLetter_PackingSlip.proforma(NoYes::No);

            salesFormLetter_PackingSlip.specQty(salesUpdate::PackingSlip);

            salesFormLetter_PackingSlip.salesTable(salesTable);

            salesFormLetter_PackingSlip.parmId(salesParmTable.ParmId);

            salesFormLetter_PackingSlip.salesParmUpdate(salesFormLetterParmData.parmParmUpdate());

            salesFormLetter_PackingSlip.runOperation();

        }

    }

Wednesday, March 15, 2023

To select the nth row in a SQL database table?

Query:


SELECT * FROM

    (

        SELECT ROW_NUMBER () OVER (ORDER BY RecId) AS RowNum, *   FROM SALESTABLE

    ) sub

WHERE RowNum = 9

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...