web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

D365FO X++ Register Purchase Order Line "Inventory dimension Batch number must be specified. "

(0) ShareShare
ReportReport
Posted on by 1,214

I'm trying to perform PO line registration and referring to these links:

https://domhk.blogspot.com/2013/01/ax2012-update-invent-registration-from.html

https://sangeethwiki.blogspot.com/2020/11/po-registration-x-d365fo.html

Here's my button event handler codes:

    [FormControlEventHandler(formControlStr(PurchTable, BtnTestRegister), FormControlEventType::Clicked)]
    public static void BtnTestRegister_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        FormRun formRun = sender.formRun();
        FormDataSource PurchTable_ds = formRun.dataSource("PurchTable");
        PurchTable purchTable = PurchTable_ds.cursor();
        PurchLine purchLine;
        InventTrans inventTrans;
        InventTransOrigin inventTransOrigin;
        InventDim inventDim;
        InventTransWMS_Register inventTransWMS_register;
        TmpInventTransWMS tmpInventTransWMS;


        ////USMF Sample PO = '00000600' ItemId = 'M9010batch'
        InventSiteId          _inventSiteId = '1';
        InventLocationId      _inventLocationId = '11';
        WMSLocationId         _wmsLocationId = "11";
        InventBatchSerialId   _batchNo = "GH34567";
        InventBatchSerialId   _serialNo = "";

        InventSite      inventSite;             //Site
        InventLocation  inventLocation;         //Warehouse
        WMSLocation     wmsLocation;            //Location
        InventBatch     inventBatch;            //Batch number
        InventSerial    inventSerial;           //Serial number      
        ;

        ttsbegin;
        while select RecId, InventTransId, ItemId, PurchId from purchLine
        where purchLine.PurchId == purchTable.PurchId
        && purchLine.IsDeleted == NoYes::No
        && purchLine.PurchQty > 0
        {
            inventTrans = InventTrans::findTransId(purchLine.InventTransId);
            if(inventTrans && inventTrans.StatusReceipt != StatusReceipt::Registered)
            {
                inventDim = inventTrans.inventDim();
                tmpInventTransWMS.clear();
                tmpInventTransWMS.initFromInventTrans(inventTrans);
                tmpInventTransWMS.InventQty = inventTrans.Qty;

                if(_wmsLocationId)
                {
                    wmsLocation = WMSLocation::find(_wmsLocationId, _inventLocationId);
                    if(wmsLocation)
                        inventDim.wMSLocationId = wmsLocation.wMSLocationId;
                    else
                        error(strFmt('Location %1 not exist in warehouse %1.', _wmsLocationId, _inventLocationId));
                }

                if(_batchNo)
                {
                    inventBatch = InventBatch::findOrCreate(_batchNo, inventTrans.ItemId);
                    inventDim.inventBatchId = inventBatch.inventBatchId;
                }

                if(_serialNo)
                {
                    inventSerial = InventSerial::findOrCreate(_serialNo, inventTrans.ItemId);
                    inventDim.inventSerialId = inventSerial.InventSerialId;
                }

                tmpInventTransWMS.InventDimId = inventDim::findOrCreate(inventDim).inventDimId;

                tmpInventTransWMS.insert();

                inventTransWMS_register = inventTransWMS_register::newStandard(tmpInventTransWMS);
                inventTransWMS_Register.createFromInventTrans(inventTrans, inventDim);
                inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS, inventTrans, inventTrans.inventDim());
                inventTransWMS_register.updateInvent(purchLine);

                Info(strFmt('%1 of item %2 in PurchId %3 registered with Batch: %4 Location: %5', 
                    tmpInventTransWMS.InventQty,
                    purchLine.ItemId,
                    purchLine.PurchId, _batchNo, _wmsLocationId));
            }
        }
        ttscommit;
    }

The item tracking dimension for Item "M9010batch" is until batch number.

In the code, we select PO line, update InventDimId with batch number and insert tmpInventTransWMS with updated InvendDimId, then call inventTransWMS_register.updateInvent.

Running this code, I get error message "Inventory dimension Batch number must be specified. "

Debugging the code, even though we pass tmpInventTransWMS with the updated InventDimId, inside method InventTransWMS_Register::updateInventFromMovementServer, the tmpInventTransWMS.InventDimId is somehow being reset.

Naturally, this is not the case when we perform the action manually via InventTransRegister form.

I'm still trying to compare debugging results between our code and standard form calling, but if anyone can point out what I passed wrongly, are highly appreciated.

Thank you.

I have the same question (0)
  • Suggested answer
    WillWU Profile Picture
    22,363 on at

    Hi HAIRUL HAZRI,

    The method InventTransWMS_Register.updateInventFromMovementServer has been refactored to support extensibility.

    Did you try to extend it?

  • Verified answer
    HAIRUL HAZRI Profile Picture
    1,214 on at

    Cross referencing the method brings me to EGAISWaybillRegister_RU.createNewRegistration() method where it shows how its done. Here is the method:

        private void createNewRegistration()
        {
            InventTransWMS_Register     inventTransWMS_Register;
            tmpInventTransWMS           tmpInventTransWMS;
            PurchLine                   purchLine;
            EGAISWaybillSettlement_RU   settlement;
            EGAISWaybillLine_RU         waybillLine;
            InventTransOrigin           inventTransOrigin;
            InventTrans                 inventTrans;
    
            while select settlement
                exists join waybillLine
                    where waybillLine.RecId == settlement.WaybillLine &&
                          waybillLine.waybillJour == waybillJour.RecId
            {
                purchLine = purchLine::findInventTransId(settlement.InventTransId);
    
                delete_from tmpInventTransWMS;
                inventTransWMS_Register = InventTransWMS_Register::newStandard(tmpInventTransWMS);
    
                select firstOnly RecId from inventTransOrigin
                    where inventTransOrigin.InventTransId == settlement.InventTransId
                join inventTrans
                    where inventTrans.InventTransOrigin == inventTransOrigin.RecId
                        && inventTrans.StatusReceipt == StatusReceipt::Ordered
                        && inventTrans.Qty >= settlement.Qty;
    
                if (!inventTransOrigin)
                {
                    throw error("@EGAIS:NothingToRegister");
                }
    
                inventTrans.Qty = settlement.Qty;                       //NOTE THIS
                inventTrans.inventDimId = settlement.InventDimId;       //NOTE THIS
                inventTransWMS_Register.createFromInventTrans(inventTrans, inventTrans.inventDim());
                inventTransWMS_Register.updateInvent(purchLine);
            }
        }

    inventTrans.Qty and inventTrans.inventDimId fields are assigned the intended value.

    Following event handler works for me:

        [FormControlEventHandler(formControlStr(PurchTable, BtnTestRegister), FormControlEventType::Clicked)]
        public static void BtnTestRegister_OnClicked(FormControl sender, FormControlEventArgs e)
        {
            FormRun formRun = sender.formRun();
            FormDataSource PurchTable_ds = formRun.dataSource("PurchTable");
            PurchTable purchTable = PurchTable_ds.cursor();
            PurchLine purchLine;
            InventTrans inventTrans;
            InventTransOrigin inventTransOrigin;
            InventDim inventDim;
            InventTransWMS_Register inventTransWMS_register;
            TmpInventTransWMS tmpInventTransWMS;
    
    
            ////USMF Sample PO = '00000600' ItemId = 'M9010batch'
            InventSiteId          _inventSiteId = '1';
            InventLocationId      _inventLocationId = '11';
            WMSLocationId         _wmsLocationId = "11";
            InventBatchSerialId   _batchNo = "GH34567";
            InventBatchSerialId   _serialNo = "";
    
            InventSite      inventSite;             //Site
            InventLocation  inventLocation;         //Warehouse
            WMSLocation     wmsLocation;            //Location
            InventBatch     inventBatch;            //Batch number
            InventSerial    inventSerial;           //Serial number      
            ;
    
            ttsbegin;
            while select RecId, InventTransId, ItemId, PurchId from purchLine
            where purchLine.PurchId == purchTable.PurchId
            && purchLine.IsDeleted == NoYes::No
            && purchLine.PurchQty > 0
            {
                inventTrans = InventTrans::findTransId(purchLine.InventTransId);
                if(inventTrans && inventTrans.StatusReceipt != StatusReceipt::Registered)
                {
                    inventDim = inventTrans.inventDim();
                    tmpInventTransWMS.clear();
                    tmpInventTransWMS.initFromInventTrans(inventTrans);
                    tmpInventTransWMS.InventQty = inventTrans.Qty;
    
                    if(_wmsLocationId)
                    {
                        wmsLocation = WMSLocation::find(_wmsLocationId, _inventLocationId);
                        if(wmsLocation)
                            inventDim.wMSLocationId = wmsLocation.wMSLocationId;
                        else
                            error(strFmt('Location %1 not exist in warehouse %1.', _wmsLocationId, _inventLocationId));
                    }
    
                    if(_batchNo)
                    {
                        inventBatch = InventBatch::findOrCreate(_batchNo, inventTrans.ItemId);
                        inventDim.inventBatchId = inventBatch.inventBatchId;
                    }
    
                    if(_serialNo)
                    {
                        inventSerial = InventSerial::findOrCreate(_serialNo, inventTrans.ItemId);
                        inventDim.inventSerialId = inventSerial.InventSerialId;
                    }
    
                    tmpInventTransWMS.InventDimId = inventDim::findOrCreate(inventDim).inventDimId;
    
                    tmpInventTransWMS.insert();
                    
                    inventTrans.Qty = 0; /**register quantity*//    //NEW LINE;
                    inventTrans.inventDimId = inventDim::findOrCreate(inventDim).inventDimId; //NEW LINE
                    inventTransWMS_register = inventTransWMS_register::newStandard(tmpInventTransWMS);
                    inventTransWMS_Register.createFromInventTrans(inventTrans, inventDim);
                    inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS, inventTrans, inventTrans.inventDim());
                    inventTransWMS_register.updateInvent(purchLine);
    
                    Info(strFmt('%1 of item %2 in PurchId %3 registered with Batch: %4 Location: %5', 
                        tmpInventTransWMS.InventQty,
                        purchLine.ItemId,
                        purchLine.PurchId, _batchNo, _wmsLocationId));
                }
            }
            ttscommit;
        }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 490 Super User 2025 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 429 Most Valuable Professional

#3
BillurSamdancioglu Profile Picture

BillurSamdancioglu 241 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans