<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>DaxOnline</title>
	<link>http://daxonline.org/</link>
	<language>en</language>
	<description></description>
	<!--image>
		<url>{RssLogo}</url>
		<title></title>
		<link>http://daxonline.org/</link>
	</image-->
	
	<item>
		<title><![CDATA[Create profit/loss inventory journal from X++]]></title>
		<guid isPermaLink="false">2028</guid>
		<link>http://daxonline.org/2028-create-profit-loss-inventory-journal-from-x.html</link>
		<description><![CDATA[<p>Here is an example of X++ code to create a profit/loss inventory journal connected to a sales order delivery note.</p><p></p><pre><code>    CustPackingSlipJour custPackingSlipJour; 
    InventJournalTable inventJournalTable;
    InventJournalTrans inventJournalTrans;
    InventJournalTableData journalTableData;
    InventJournalTransData journalTransData;

    /// &lt;summary&gt;
    /// Create Inventory journal header record
    /// &lt;/summary&gt;
    /// &lt;param name = &quot;_throwOnError&quot;&gt;throw on error (Y/N)?&lt;/param&gt;
    /// &lt;returns&gt;true is record has been created, false if it already exists&lt;/returns&gt;
    protected boolean createInventJournalTable(boolean _throwOnError = true)
    {
        boolean ret = true;

        if (inventJournalTable.RecId != 0)
        {
            return ret;
        }

        journalTableData = JournalTableData::newTable(inventJournalTable);

        // Init JournalTable
        inventJournalTable.clear();

        inventJournalTable.JournalId = journalTableData.nextJournalId();
        inventJournalTable.JournalType = InventJournalType::LossProfit;
        inventJournalTable.JournalNameId = InventParameters::find().VKJournalNameId;
        inventJournalTable.VKRefDeliveryNote = custPackingSlipJour.InternalPackingSlipId;
        inventJournalTable.VKRefSourceDocumentHeader = custPackingSlipJour.SourceDocumentHeader;  // unique ref

        journalTableData.initFromJournalName(journalTableData.journalStatic().findJournalName(inventJournalTable.JournalNameId));

        inventJournalTable.DeletePostedLines = NoYes::No;

        if (inventJournalTable.validateWrite())
        {
            inventJournalTable.insert();
        }
        else
        {
            ret = false;
            if (_throwOnError)
            {
                throw Error(&quot;@SYS93289&quot;);
            } 
        }
        return ret;
    }

    /// &lt;summary&gt;
    /// Create Inventory journal line records
    /// &lt;/summary&gt;
    /// &lt;returns&gt;true if records have been created, exception is thrown otherwise&lt;/returns&gt;
    protected boolean createInventJournalTrans()
    {
        boolean ret = true;

        if (!inventJournalTable)
        {
            this.createInventJournalTable();
        }

        CustPackingSlipTrans custPackingSlipTrans;

        while select custPackingSlipTrans
            where custPackingSlipTrans.SalesId == custPackingSlipJour.SalesId
            &amp;&amp; custPackingSlipTrans.PackingSlipId == custPackingSlipJour.PackingSlipId
            &amp;&amp; custPackingSlipTrans.DeliveryDate  == custPackingSlipJour.DeliveryDate
        {
            
            inventJournalTrans.clear();
            
            journalTransData = journalTableData.journalStatic().newJournalTransData(inventJournalTrans, journalTableData);

            if (inventJournalTable.NumOfLines)
            {
                journalTransData.parmLastLineNum(inventJournalTable.NumOfLines);
            }
            journalTransData.initFromJournalTable();

            inventJournalTrans.TransDate    = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());
            inventJournalTrans.ItemId       = custPackingSlipTrans.ItemId;

            inventJournalTrans.VKOrigRefRecId  = custPackingSlipTrans.RecId;

            inventJournalTrans.Qty                          = 0;
            if (PdsGlobal::pdsIsCWItem(inventJournalTrans.ItemId)
			{
				inventJournalTrans.pdsCWQty                 = 0;
			}

            // standard unit qty
            inventJournalTrans.UnitQty  = 0; // synced by default with 0 Qty
            inventJournalTrans.Unit     = custPackingSlipTrans.SalesUnit;

            InventTransOrigin   inventTransOrigin;
            InventTrans inventTrans;
            select firstonly RecId from inventTransOrigin
                where inventTransOrigin.InventTransId == custPackingSlipTrans.InventTransId
                join InventDimId from inventTrans
                where inventTrans.inventTransOrigin == inventTransOrigin.RecId
                &amp;&amp; inventTrans.PackingSlipId == custPackingSlipJour.PackingSlipId;

            inventJournalTrans.InventDimId = inventTrans.InventDimId;
            inventJournalTrans.setCostPrice(inventJournalTrans.InventDimId);            
            inventJournalTrans.DefaultDimension = custPackingSlipTrans.DefaultDimension;

            journalTransData.create();
        }

        return ret;
    }</code></pre><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[journals]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Tue, 05 May 2026 07:28:18 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Ship transfer order from code]]></title>
		<guid isPermaLink="false">2027</guid>
		<link>http://daxonline.org/2027-ship-transfer-order-from-code.html</link>
		<description><![CDATA[<p>Here is an example of X++ code to post the transfer order shipment with autoreceive and check that it was successful:</p><pre><code>        InventTransferVoucherId voucherId = &#039;&#039;;
        if (inventTransferTable)
        {
            InventTransferUpdShip   shipUpdate;
            InventTransferParmTable inventTransferParmTable;

            InventTransferTable.selectForUpdate(true);
            InventTransferTable.ReceiveDate         = intTransferReceiptStaging.ReceiveDate;
            InventTransferTable.update();

            inventTransferParmTable.initParmDefault();
        
            inventTransferParmTable.TransferId      = inventTransferTable.TransferId;
            inventTransferParmTable.ShipUpdateQty   = InventTransferShipUpdateQty::PickedQty;
            inventTransferParmTable.EditLines       = NoYes::Yes;
            inventTransferParmTable.TransDate       = intTransferReceiptStaging.ReceiveDate;
            inventTransferParmTable.AutoReceiveQty  = NoYes::Yes;
        
            shipUpdate = InventTransferUpdShip::newParmBuffer(inventTransferParmTable);
            shipUpdate.run();

            if (shipUpdate.parmIsSomeThingPosted())
            {
                InventTransferJour  inventTransferJour = shipUpdate.parmInventTransferJour();
                voucherId = inventTransferJour.VoucherId;
            }</code></pre><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Wed, 29 Apr 2026 10:39:20 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Cancel transfer/sales order picks]]></title>
		<guid isPermaLink="false">2025</guid>
		<link>http://daxonline.org/2025-cancel-transfer-sales-order-picks.html</link>
		<description><![CDATA[<p>Here is an example of X++ code, which can be used to cancel existing transfer/sales order picks:</p><pre><code>    void cancelPreviousPicks(SalesId _salesId)
    {
        SalesLine           salesLine;
        wmsOrderTrans       wmsOrderTrans,
                            wmsOrderTransNew;
        InventTrans         inventTransCancel;
        InventTransOrigin   inventTransOriginCancel;

        // select forupdate is required by standard unpick logic
        while select forupdate wmsOrderTrans
            //join inventTransferLine
            //    where inventTransferLine.TransferId == _transferId
            join salesLine
                where salesLine.SalesId             == _salesId
                    &amp;&amp;wmsOrderTrans.inventTransId   == salesLine.InventTransId
                    &amp;&amp;wmsOrderTrans.expeditionStatus== WMSExpeditionStatus::Complete
        {

            select sum(qty), sum(PdsCWQty)
                from inventTransCancel
                join inventTransOriginCancel
                    where  inventTransOriginCancel.InventTransId    == wmsOrderTrans.inventTransId
                        &amp;&amp; inventTransOriginCancel.RecId            == inventTransCancel.inventTransOrigin
                        &amp;&amp; InventTransCancel.StatusIssue            == statusIssue::Picked
                        &amp;&amp; InventTransCancel.PickingRouteID         == wmsOrderTrans.RouteId;

            // Unpick previous picks if not delivered
            if (abs(InventTransCancel.qty) &gt;= wmsOrderTrans.qty)
            {
                wmsOrderTrans.wmsOrderTransType().unPick(
                    wmsOrderTrans.qty,
                    wmsOrderTrans.inventDim(),
                    NoYes::Yes,
                    wmsOrderTrans.PdsCWQty
                );
            }
            // If there is delivered quantity then unpick as much as possible that has not been delivered
            else if (InventTransCancel.qty &lt; 0  &amp;&amp; abs(InventTransCancel.qty) &lt; wmsOrderTrans.qty)
            {
                wmsOrderTransNew = wmsOrderTrans.split(abs(InventTransCancel.qty), abs(InventTransCancel.PdsCWQty));
                wmsOrderTransNew.wmsOrderTransType().unPick(
                    abs(InventTransCancel.qty),
                    wmsOrderTrans.inventDim(),
                    NoYes::Yes,
                    wmsOrderTrans.PdsCWQty
                );
            }
        }
    }</code></pre><p></p><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[journals]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Thu, 23 Apr 2026 10:13:26 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Post transfer order picking list from code]]></title>
		<guid isPermaLink="false">2024</guid>
		<link>http://daxonline.org/2024-post-transfer-order-picking-list-from-code.html</link>
		<description><![CDATA[<p>Here is an example of X++ code to post the transfer order picking list with a check that it was successful:</p><pre><code>        InventTransferParmTable inventTransferParmTable;
        InventTransferUpdPick   inventTransferUpdPick;
        ParmId                  parmId = RunBaseMultiParm::getSysParmId();
    
        inventTransferParmTable.clear();
        inventTransferParmTable.initParmDefault();
    
        inventTransferParmTable.ParmId                      = parmId;
        inventTransferParmTable.TransferId                  = _transferId;
        inventTransferParmTable.UpdateType                  = InventTransferUpdateType::PickingList;
        inventTransferParmTable.PickUpdateQty               = InventTransferPickUpdateQty::All;
        inventTransferParmTable.EditLines                   = NoYes::Yes;
        inventTransferParmTable.PrintTransferPickingList    = NoYes::No;
    
        inventTransferUpdPick = InventTransferUpdPick::newParmBuffer(inventTransferParmTable);
        inventTransferUpdPick.run();

        WMSPickingRoute wmsPickingRoute;

        if (inventTransferUpdPick.parmIsSomeThingPosted())
        {
            select firstonly RecId from wmsPickingRoute
                where   wmsPickingRoute.ParmId      == parmId
                    &amp;&amp;  wmsPickingRoute.transRefId  == _transferId
                    &amp;&amp;  wmsPickingRoute.transType   == InventTransType::TransferOrderShip;
        }</code></pre><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[journals]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Thu, 23 Apr 2026 10:02:11 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Cross company indexes]]></title>
		<guid isPermaLink="false">2019</guid>
		<link>http://daxonline.org/2019-cross-company-indexes.html</link>
		<description><![CDATA[<p>Cross-company indexes might be required to optimize cross-company oData queries. Or other cross-company X++ queries.</p><p>By default, for company-specific tables (SaveDataPerCompany=Yes), DataAreaId is always included in the index at the beginning. Like, for example, PurchTable PurchIdx index structure from MS SQL Server Management Studio:</p><img src="/cnt/202601/h3fb8r9duf.png"><p>Such indexes will NOT work for cross-company queries.</p><p><br>Sometimes it is required to optimize the performance of cross-company queries to company-specific tables. For example, to optimize cross-company oData queries.</p><p>To accomplish this, you need to add the DataAreaId field explicitly to your index at the end and set the property Included Column to Yes.</p><img src="/cnt/202601/3wjt52xkgh.png"><p><br>From MS SQL Server Management Studio:</p><img src="/cnt/202601/pjuo4m14ba.png"><p>DataAreaId field appears in the Included columns, and this index will be used by SQL Server for cross-company queries:</p><img src="/cnt/202601/himkd8ed1h.png"><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sql]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Wed, 14 Jan 2026 08:30:18 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Exchange rate operations]]></title>
		<guid isPermaLink="false">2018</guid>
		<link>http://daxonline.org/2018-exchange-rate-operations.html</link>
		<description><![CDATA[<p>Exchange rate operations:</p><p>Convert to accounting currency:</p><pre><code>CurrencyExchangeHelper::amountCur2MST(amount, currencyCodeFrom[, fixedExchRate]);</code></pre><p>Convert to a different currency:</p><pre><code>CurrencyExchangeHelper::curAmount2CurAmount(amount, currencyCodeFrom, CurrencyCodeTo);</code></pre><p>Get accounting currency:</p><pre><code>CurrencyCode    accountingCurrency = Ledger::accountingCurrency();
CurrencyCode    accountingCurrency = Ledger::accountingCurrencyByLedger(_ledgerRecId);</code></pre><p>Get reporting currency:</p><pre><code>CurrencyCode    accountingCurrency = Ledger::reportingCurrency();
CurrencyCode    accountingCurrency = Ledger::reportingCurrencyByLedger(_ledgerRecId);</code></pre><p>Convert currency with a class instance:</p><pre><code>CurrencyExchangeHelper currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(
    Ledger::current(),
    DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())
);
currencyExchangeHelper.calculateTransactionToAccounting(currencyCodeFrom, amountCur, true);
// currencyExchangeHelper.calculateCurrencyToCurrency()
currencyExchangeHelper.parmExchangeRate1();</code></pre><p>Get the exchange rate:</p><pre><code>//accounting currency
ExchangeRateCalculation exchangeRateCalculation = ExchangeRateCalculation::newExchangeDate(Ledger::defaultExchangeRateType(),
    purchTable.CurrencyCode,
    Ledger::accountingCurrency(),
    DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));

purchTable.FixedExchRate = exchangeRateCalculation.getExchangeRate1();

// reporting currency
ExchangeRateCalculation exchangeRateCalculation = ExchangeRateCalculation::newExchangeDate(Ledger::reportingCurrencyExchangeRateType(),
    currencyCodeFrom,
    currencyCodeTo,
    DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
exchangeRateCalculation.getExchangeRate1();</code></pre><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Mon, 24 Nov 2025 11:45:31 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[SysTableBrowser extension to control visible fields and pre-applied ranges]]></title>
		<guid isPermaLink="false">2015</guid>
		<link>http://daxonline.org/2015-systablebrowser-extension-to-control-visible-fields-and-pre-applied-ranges.html</link>
		<description><![CDATA[<p>Often, due to a large number of fields in the table or an enormous amount of records, the standard SysTableBrowser is heavily lagging, especially on the DEV boxes.</p><p>Also, when you are interested in only several field contents, it is not convenient to scroll back and forth to investigate particular field values.</p><p>Here is the SysTableBrowser extension, which you can use together with the <a target="_blank" rel="noopener noreferrer nofollow" href="/d365/table-browser.html">Table Browser tool</a>.</p><p>It allows you to:</p><p>- indicate fields which you want to see.</p><p>- predefine field ranges to see only specific records</p><p></p><p><strong>Last updated: April 29, 2026</strong><br></p><img src="/cnt/202509/ld057kava0.png"><p><br></p><img src="/cnt/202509/oadgdlmq4x.png"><p><br>How to install?</p><p>- create a class with the name DXTSysTableBrowserFrm_Extension</p><p>- copy/paste the following content</p><p>- compile</p><p><br></p><pre><code>/// &lt;summary&gt;
/// CoC extension of SysTableBrowser form
/// &lt;/summary&gt;
[ExtensionOf(formStr(SysTableBrowser))]
final class DXTSysTableBrowserFrm_Extension
{
    private Map                 visibleFieldList;
    private Map                 rangeFieldList;
    private TableId             tableId;
    private FormGridControl     formGridControlAllFields;
    private FormGroupControl    customGroup;
    private str                 parmFieldList;
    private str                 parmRangeList;
    private FormStringControl   visibleFieldListControl;
    private FormStringControl   rangeFieldListControl;
 
    /// &lt;summary&gt;
    /// CoC for init method
    /// &lt;/summary&gt;
    public void init()
    {
        next init();
 
        parmFieldList               = strLRTrim(getClientURLQueryValue(&#039;FieldList&#039;));
        parmRangeList               = strLRTrim(getClientURLQueryValue(&#039;RangeList&#039;));
        formGridControlAllFields    = this.design(0).controlName(formControlStr(SysTableBrowser, AllFieldsGrid));
        tableId                     = formGridControlAllFields.formRun().dataSource().cursor().TableId;
 
        this.dxtParseFieldListParam();
        this.dxtApplyRanges();
        this.dxtShowHideFields(true);
        this.dxtAddControls();
    }

    /// &lt;summary&gt;
    /// Applies datasource ranges.
    /// &lt;/summary&gt;
    public void dxtApplyRanges()
    {
        FormDataSource          fds = this.dataSource(1);
        Query                   q;
        QueryBuildDataSource    qbds;

        rangeFieldList = new Map(Types::Integer, Types::Integer);
 
        container   ranges = str2con(parmRangeList, &#039;,&#039;);
        str         rangeValue;
        FieldName   fieldName;
        FieldId     fieldId;
        int         i;
        
        if (fds)
        {
            q       = fds.query();
            qbds    = q.dataSourceNo(1);
            qbds.clearRanges();
 
            if (parmRangeList &amp;&amp; conLen(ranges))
            {
                for (i = 1; i &lt;= conLen(ranges); i++)
                {
                    str         pairStr = strLTrim(conPeek(ranges, i));
                    container   pairCnt = str2con(pairStr, &#039;=&#039;);
                    fieldName   = conPeek(pairCnt, 1);
                    rangeValue  = conPeek(pairCnt, 2);
                    fieldId     = fieldName2Id(tableId, fieldName);
                    if (fieldId &amp;&amp; rangeValue)
                    {
                        QueryBuildRange qbr = qbds.addRange(fieldId);
                        qbr.value(rangeValue);
                        if (!rangeFieldList.exists(fieldId))
                        {
                            rangeFieldList.add(fieldId, 1);
                        }
                    }
                }
            }
        }
    }

    /// &lt;summary&gt;
    /// Add additional controls on the SySTableBrowser form.
    /// &lt;/summary&gt;
    public void dxtAddControls()
    {
        FormGroupControl   filterGroup = this.design().controlName(formControlStr(SysTableBrowser, CustomFilter));
        FormGroupControl   parentGroup;
 
        if (filterGroup)
        {
            parentGroup = filterGroup.parentControl();
 
            customGroup = this.design().addControl(FormControlType::Group, &#039;DXTCustomGroup&#039;, filterGroup);
            customGroup.caption(&#039;Extended functionality&#039;);
            customGroup.columns(2);
 
            visibleFieldListControl = customGroup.addControl(FormControlType::String, &#039;DXTVisibleFields&#039;);
            visibleFieldListControl.multiLine(true);
            visibleFieldListControl.width(400, -1);
            visibleFieldListControl.displayHeight(2, AutoMode::Fixed);
            visibleFieldListControl.text(parmFieldList);
            visibleFieldListControl.label(&#039;Visible fields&#039;);
            visibleFieldListControl.helpText(&#039;Comma-separated list of visible field names (AOT).&#039;);
            visibleFieldListControl.labelPosition(LabelPosition::Left);
 
            visibleFieldListControl.registerOverrideMethod(
                methodStr(FormStringControl, modified),
                methodStr(DXTSysTableBrowserFrm_Extension, dxtVisibleFieldListControlModified),
                this);
 
            rangeFieldListControl = customGroup.addControl(FormControlType::String, &#039;DXTRangeFields&#039;);
            rangeFieldListControl.multiLine(true);
            rangeFieldListControl.width(400, -1);
            rangeFieldListControl.displayHeight(2, AutoMode::Fixed);
            rangeFieldListControl.text(parmRangeList);
            rangeFieldListControl.label(&#039;Ranges&#039;);
            rangeFieldListControl.helpText(&#039;Comma-separated list of field ranges in the format FieldName=RangeValue.&#039;);
            rangeFieldListControl.labelPosition(LabelPosition::Left);
 
            rangeFieldListControl.registerOverrideMethod(
                methodStr(FormStringControl, modified),
                methodStr(DXTSysTableBrowserFrm_Extension, dxtRangeFieldListControlModified),
                this);
        }
    }

    /// &lt;summary&gt;
    /// DXTVisibleFields modified method. To update visible fields, when field list is changed.
    /// &lt;/summary&gt;
    /// &lt;param name = &quot;_formControl&quot;&gt;FormStringControl&lt;/param&gt;
    /// &lt;returns&gt;boolean&lt;/returns&gt;
    public boolean dxtVisibleFieldListControlModified(FormStringControl _formControl)
    {
        var locFieldList = strLRTrim(visibleFieldListControl.valueStr());
        if (locFieldList != parmFieldList)
        {
            parmFieldList = locFieldList;
            this.dxtParseFieldListParam();
            this.dxtShowHideFields();
        }
 
        return _formControl.modified();
    }

    /// &lt;summary&gt;
    /// DXTRangeFields modified method. To update ranges, when ranges are changed.
    /// &lt;/summary&gt;
    /// &lt;param name = &quot;_formControl&quot;&gt;FormStringControl&lt;/param&gt;
    /// &lt;returns&gt;boolean&lt;/returns&gt;
    public boolean dxtRangeFieldListControlModified(FormStringControl _formControl)
    {
        var locFieldList = strLRTrim(rangeFieldListControl.valueStr());
        if (locFieldList != parmRangeList)
        {
            parmRangeList = locFieldList;
            this.dxtApplyRanges();
            FormDataSource fds = this.dataSource(1);
            fds.executeQuery();
        }
 
        return _formControl.modified();
    }

    /// &lt;summary&gt;
    /// Parse visible field list string.
    /// &lt;/summary&gt;
    public void dxtParseFieldListParam()
    {
        visibleFieldList    = new Map(Types::Integer, Types::Integer);
 
        if (parmFieldList)
        {
            container   fieldNames = str2con(parmFieldList, &#039;,&#039;);
            FieldName   fieldName;
            FieldId     fieldId;
            int         i;
 
            for (i = 1; i &lt;= conLen(fieldNames); i++)
            {
                fieldName   = strLRTrim(conPeek(fieldNames, i));
                fieldId     = fieldName2Id(tableId, fieldName);
                if (fieldId)
                {
                    if (!visibleFieldList.exists(fieldId))
                    {
                        visibleFieldList.insert(fieldId, 1);
                    }
                }
            }
        }
    }

    /// &lt;summary&gt;
    /// Show/Hide field based on the user preference.
    /// &lt;/summary&gt;
    /// &lt;param name = &quot;_initRun&quot;&gt;boolean&lt;/param&gt;
    public void dxtShowHideFields(boolean _initRun = false)
    {
        int             fieldCount      = formGridControlAllFields.controlCount(),
                        visFldCount     = visibleFieldList.elements(),
                        i;
 
        if (_initRun &amp;&amp; !visFldCount)
        {
            return;
        }

        for (i = 1; i &lt;= fieldCount; i++)
        {
            FormControl     formControl     = formGridControlAllFields.controlNum(i);
            FieldBinding    fieldBinding    = formControl.fieldBinding();
            FieldId         fieldId         = fieldBinding.fieldId();

            if (!visFldCount || (fieldId &amp;&amp; (visibleFieldList.exists(fieldId) || rangeFieldList.exists(fieldId))))
            {
                formControl.visible(true);
            }
            else
            {
                formControl.visible(false);
            }
        }
    }

}</code></pre><p></p>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[tools]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Tue, 23 Sep 2025 10:49:56 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Add/overwrite SSRS print management design]]></title>
		<guid isPermaLink="false">2012</guid>
		<link>http://daxonline.org/2012-add-overwrite-ssrs-print-management-design.html</link>
		<description><![CDATA[
<div>Add/overwrite SSRS print management design</div>
<div><br>
</div>
<div>
<pre>/// &lt;summary&gt;
/// An extension class of the &lt;c&gt;PrintMgmtReportFormatPopulator&lt;/c&gt; class.
/// &lt;/summary&gt;
[ExtensionOf(classStr(PrintMgmtReportFormatPopulator))]
public final class VKPrintMgmtReportFormatPopulatorCls_Extension
{
&nbsp; &nbsp; #PrintMgmtSetup

&nbsp; &nbsp; /// &lt;summary&gt;
&nbsp; &nbsp; /// Add custom reports to the print management.
&nbsp; &nbsp; /// &lt;/summary&gt;
&nbsp; &nbsp; protected void addDocuments()
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; this.addOther(PrintMgmtDocumentType::SalesOrderConfirmation, ssrsReportStr(VKSalesConfirm, Report), ssrsReportStr(VKSalesConfirm, Report), #NoCountryRegionId);
&nbsp; &nbsp; &nbsp; &nbsp; this.addOther(PrintMgmtDocumentType::SalesOrderInvoice, ssrsReportStr(VKSalesInvoice, Report), ssrsReportStr(VKSalesInvoice, Report), #NoCountryRegionId);

&nbsp; &nbsp; &nbsp; &nbsp; next addDocuments();
&nbsp; &nbsp; }

}</pre>
</div>
<div>addOther vs addStandard.</div>
<div>addOther - if populate (PrintMgmtReportFormat::populate()) is executed with standard code, it add a record to the PrintMgmtReportFormat table where System = Yes. Then, if populate is executed with extended code, a new record is added, and it will get System = Yes.</div>
<div>If the population with extended code is executed in the company without prior execution with standard code, only one record is added to&nbsp;the PrintMgmtReportFormat table and it will NOT be System. The report will fail when executed as "Original preview" with error:</div>
<ul>
<li><b>Report name in report contract cannot be null or empty.</b></li>
<li><b>Customer CustNum, Invoice InvoiceNum was not delivered because of a print management setup issue. Verify that print management is set up correctly and the destination is valid.</b></li></ul>
<div><br>
</div>
<div>
<pre>/// &lt;summary&gt;
/// event handler class to print new purchase order report
/// &lt;/summary&gt;
internal final class VKPrintMgmtDocTypeCls_EventHandler
{
&nbsp; &nbsp; /// &lt;summary&gt;
&nbsp; &nbsp; /// Get new custom default report for purchase order
&nbsp; &nbsp; /// &lt;/summary&gt;
&nbsp; &nbsp; /// &lt;param name = "_docType"&gt;Print mgmt document type&lt;/param&gt;
&nbsp; &nbsp; /// &lt;param name = "_result"&gt;delegate for default report&lt;/param&gt;
&nbsp; &nbsp; [SubscribesTo(classstr(PrintMgmtDocType), delegatestr(PrintMgmtDocType, getDefaultReportFormatDelegate))]
&nbsp; &nbsp; public static void getDefaultReportFormatDelegate(PrintMgmtDocumentType _docType, EventHandlerResult _result)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; switch (_docType)
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case PrintMgmtDocumentType::PurchaseOrderRequisition:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _result.result(ssrsReportStr(VKPurchPurchaseOrder, Report));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case PrintMgmtDocumentType::SalesOrderConfirmation:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _result.result(ssrsReportStr(VKSalesConfirm, Report));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case PrintMgmtDocumentType::SalesOrderInvoice:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _result.result(ssrsReportStr(VKSalesInvoice, Report));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

}</pre>
</div>
<div>New print management node</div>
<div>
<pre>/// &lt;summary&gt;
/// Extension of PrintMgmtNode_Sales class
/// &lt;/summary&gt;
[ExtensionOf(classStr(PrintMgmtNode_Sales))]
final class VKPrintMgmtNode_Sales_Extension
{
&nbsp; &nbsp; &nbsp;/// &lt;summary&gt;
&nbsp; &nbsp; /// Adds additional document types for Sales module
&nbsp; &nbsp; /// &lt;/summary&gt;
&nbsp; &nbsp; /// &lt;returns&gt;Document types list&lt;/returns&gt;
&nbsp; &nbsp; public List getDocumentTypes()
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; List docTypes;
&nbsp; &nbsp; &nbsp; &nbsp; docTypes = new List(Types::Enum);
&nbsp; &nbsp; &nbsp; &nbsp; docTypes = next getDocumentTypes();
&nbsp; &nbsp; &nbsp; &nbsp; docTypes.addEnd(PrintMgmtDocumentType::VKCustomerReturnReceived);
&nbsp; &nbsp; &nbsp; &nbsp; return docTypes;
&nbsp; &nbsp; }

}</pre>
</div>
<div><br>
</div>
<div><br>
</div>]]></description>
		
		<category><![CDATA[SSRS]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Thu, 12 Jun 2025 12:31:47 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[SalesUpdateRemain updateDeliverRemainder catch weight quantity errors]]></title>
		<guid isPermaLink="false">2011</guid>
		<link>http://daxonline.org/2011-salesupdateremain-updatedeliverremainder-catch-weight-quantity-errors.html</link>
		<description><![CDATA[
<div>Errors:&nbsp;</div>
<div>
<ul>
<li><b>Illegal splitting.&nbsp;Update has been cancelled.</b></li>
<li><b>Full catch weight quantity requested was not processed.</b><br>
To resolve this issue, go to the order lines -&gt; Stock -&gt; Pick to pick sufficient amount to issue.<br>
<b>Insufficient stock transactions with status Picked.</b></li></ul></div>
<div><br>
</div>
<div>Occurs when trying to update the deliver remainder on the sales order line:</div>
<div>
<pre>SalesUpdateRemain::construct().updateDeliverRemainder(salesLine, salesQty, inventQty, cwQty);</pre>
</div>
<div>Even though we pass the catch weight quantity to the updateDeliverRemainder() method, it does not set it on the sales line buffer inside. It updates only RemainSalesPhysical and RemainInventPhysical:</div>
<div><br>
</div>
<div>
<pre>&nbsp; &nbsp; &nbsp; &nbsp; InventQty&nbsp; &nbsp; &nbsp; diffRemainSalesPhysical&nbsp; &nbsp; &nbsp; &nbsp;= _salesLine.RemainSalesPhysical&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- _remainSalesPhysical;
&nbsp; &nbsp; &nbsp; &nbsp; InventQty&nbsp; &nbsp; &nbsp; diffRemainInventPhysical&nbsp; &nbsp; &nbsp; = _salesLine.RemainInventPhysical&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - _remainInventPhysical;
&nbsp; &nbsp; &nbsp; &nbsp; PdsCWInventQty diffPdsCWRemainInventPhysical = _salesLine.orig().PdsCWRemainInventPhysical&nbsp; - _cWRemainInventPhysical;

&nbsp; &nbsp; &nbsp; &nbsp; _salesLine.RemainSalesPhysical&nbsp; = _remainSalesPhysical;
&nbsp; &nbsp; &nbsp; &nbsp; _salesLine.RemainInventPhysical = _remainInventPhysical;

&nbsp; &nbsp; &nbsp; &nbsp; if (_salesLine.RemainInventPhysical)
&nbsp; &nbsp; &nbsp; &nbsp; {</pre>
</div>
<div>The fix is to update PdsCWRemainInventPhysical on sales line buffer before calling&nbsp;updateDeliverRemainder() method.</div>
<div>
<pre>if (PdsGlobal::pdsIsCWItem(salesLine.ItemId))
{
&nbsp; &nbsp; salesLine.PdsCWRemainInventPhysical = cwQty;
}
SalesUpdateRemain::construct().updateDeliverRemainder(salesLine, salesQty, inventQty, cwQty);</pre>
</div>
<div>Or a fix for the whole environment, create CoC and update it before calling the next:</div>
<div>
<pre>/// &lt;summary&gt;
/// An extension class of the &lt;c&gt;SalesUpdateRemain&lt;/c&gt; class.
/// &lt;/summary&gt;
[ExtensionOf(classStr(SalesUpdateRemain))]
public final class NXRSalesUpdateRemainCls_Extension
{
&nbsp; &nbsp; /// &lt;summary&gt;
&nbsp; &nbsp; /// CoC for updateDeliverRemainder() method
&nbsp; &nbsp; /// &lt;/summary&gt;
&nbsp; &nbsp; /// &lt;param name="_salesLine"&gt;
&nbsp; &nbsp; /// The instance of &lt;c&gt;SalesLine&lt;/c&gt; for which delivery remainder is set.
&nbsp; &nbsp; /// &lt;/param&gt;
&nbsp; &nbsp; /// &lt;param name="_remainSalesPhysical"&gt;
&nbsp; &nbsp; /// New value for remaining physical sales quantity.
&nbsp; &nbsp; /// &lt;/param&gt;
&nbsp; &nbsp; /// &lt;param name="_remainInventPhysical"&gt;
&nbsp; &nbsp; /// New value for remaining physical inventory quantity.
&nbsp; &nbsp; /// &lt;/param&gt;
&nbsp; &nbsp; /// &lt;param name="_cWRemainInventPhysical"&gt;
&nbsp; &nbsp; /// New value for remaining physical inventory CW quantity.
&nbsp; &nbsp; /// &lt;/param&gt;
&nbsp; &nbsp; /// &lt;returns&gt;
&nbsp; &nbsp; /// true if the line's delivery remainder was successfully updated; otherwise, false.
&nbsp; &nbsp; /// &lt;/returns&gt;
&nbsp; &nbsp; public boolean updateDeliverRemainder(
&nbsp; &nbsp; &nbsp; &nbsp; SalesLine&nbsp; &nbsp; &nbsp; _salesLine,
&nbsp; &nbsp; &nbsp; &nbsp; InventQty&nbsp; &nbsp; &nbsp; _remainSalesPhysical,
&nbsp; &nbsp; &nbsp; &nbsp; InventQty&nbsp; &nbsp; &nbsp; _remainInventPhysical,
&nbsp; &nbsp; &nbsp; &nbsp; PdsCWInventQty _cWRemainInventPhysical)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; if (PdsGlobal::pdsIsCWItem(_salesLine.ItemId))
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // even though we pass _cWRemainInventPhysical to updateDeliverRemainder() - it does not set it on the SalesLine buffer and therefore fails
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // setting PdsCWRemainInventPhysical before updateDeliverRemainder() to work in same way as when updating deliver remainder from UI
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _salesLine.PdsCWRemainInventPhysical = _cWRemainInventPhysical;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; return next updateDeliverRemainder(_salesLine, _remainSalesPhysical, _remainInventPhysical, _cWRemainInventPhysical);
&nbsp; &nbsp; }

}</pre>
</div>
<div><br>
</div>]]></description>
		
		<category><![CDATA[D365F&SCM]]></category>
		<category><![CDATA[error]]></category>
		<dc:creator>Vasyl Kovalenko</dc:creator>
		<pubDate>Wed, 04 Jun 2025 04:47:20 GMT</pubDate>
	</item>
	<item>
		<title><![CDATA[Export related work items from pull request to Excel or CSV]]></title>
		<guid isPermaLink="false">2004</guid>
		<link>http://daxonline.org/2004-export-related-work-items-from-pull-request-to-excel-or-csv.html</link>
		<description><![CDATA[Create a draft Pull request with linked work items from one branch to another.<br>
Open a new window and update next URL with your information:<br>
<a href="https://dev.azure.com/%7Borganization%7D/%7Bproject%7D/_apis/git/repositories/%7Brepository%7D/pullRequests/%7BpullRequestId%7D/workitems?api-version=6.1-preview.1">
<pre>https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repository}/pullRequests/{pullRequestId}/workitems?api-version=6.1-preview.1</pre>
</a>
<div>Copy and paste the JSON result to any service for converting "JSON to CSV" or Excel (e.g. https://www.convertcsv.com/json-to-csv.htm)</div>
<div>That's it!</div><br>
]]></description>
		
		<category><![CDATA[devops]]></category>
		<dc:creator>Dmytro Obrusnik</dc:creator>
		<pubDate>Wed, 19 Mar 2025 09:31:15 GMT</pubDate>
	</item>
</channel>
</rss>