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

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Supply chain | Supply Chain Management, Commerce
Suggested Answer

Can we create Planned Order using Engine Planning Optimization by code x++ ?

(2) ShareShare
ReportReport
Posted on by 8
 
I want to create a planned order based on predefined data. Previously, I used legacy code and explicitly defined which item the planned order would be created for. However, when I run it now, I get the following error:
 
 
 
“Deprecated master planning is not available in this environment. Please use Planning Optimization. You can find more information here: https://go.microsoft.com/fwlink/?linkid=2275925”
 
 
 
Is there any solution that allows me to create a planned order based on predefined data using code?
 

 

 
Thanks in advance.

 
01. PO packing ja...
Screenshot 2026-0...

Your file is currently under scan for potential threats. Please wait while we review it for any viruses or malicious content.

I have the same question (0)
  • André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    Hi umbrellatcorp,
     
    Can you clarify what exactly you mean by "predefined data using code"? What data do you have available? What coding did you use?
    What is the exact process you want to fulfil with this customization?

    Note that at this moment, I'm not yet able to see your added screenshots as they are being scanned for potential threats. In case these screenshots do provide relevant information, it will need to review your question later again.
  • André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    PS. I moved your question to the Dynamics 365 Supply Chain Management forum.
  • umbrellatcorp Profile Picture
    8 on at
    Thank you for your response.
     
    What I mean is that I have a custom solution to import a list of items for which planned orders need to be created. The list contains the item numbers and quantities for the planned orders.
    My code loops through the data imported from Excel and creates planned orders based on the list provided in the Excel file. This code was working previously; however, it is now throwing the error “Deprecated Master Planning is not available”.
    i run this custom on Tier 2 / UAT.
     
    So this issue appear when I try to create Planned Order through coding x++.
     
     
  • André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    Hi umbrellatcorp,

    Thanks for the clarification. This is helpful in understanding the requirement. Can you share the code you used at this moment? Did you interact with the ReqPO table directly or what other class did you call?
  • umbrellatcorp Profile Picture
    8 on at
    Hi @André Arnaud de Calavon,
    This is my code.
     
    [Form]
    public class CEB_PlannedOrderImport extends FormRun
    {
        FormStringControl       fileNameControl, fileOpenControl;
        InventLocationId        fromInventLocationId;
        InventLocationId        toInventLocationId;
        ReqPO                   newReqPo;
        ReqPO                   mReqPo;
        ReqPOType               mReqPOType;
        ReqPlanData             mReqPlanData;
        InventDim               inventDim;
        Map                     mapReqPoUpdated;
        int                     countApprove;
        int                     countDireived;
        ReqTrans            reqTransPO;
        ReqTransPOCreate    reqTransPOCreate;
        ReqCalcExplode      reqCalcExplode;
        public void close()
        {
            CEB_PlannedOrderTmp plannedOrderTmp;
            super();
            ttsBegin;
            delete_from plannedOrderTmp;
            ttsCommit;
        }
        public boolean createReqPO()
        {
            ReqPO   saveReqPO;
            boolean createFailed;
            XDSServices xdsServices = new XDSServices();
            #DirParty
            if (!mReqPo.RecId)
            {
                saveReqPO.data(mReqPo);
                try
                {
                    xdsServices.setXDSContext(0, #SystemUser);
                    this.insertFromForm(mReqPo,inventDim,fromInventLocationId,toInventLocationId,true);
                    xdsServices.setXDSContext(0, '');
                }
                catch
                {
                    createFailed = true;
                }
                if (!createFailed)
                {
                    newReqPo.data(mReqPo);
                }
                else
                {
                    mReqPo.data(saveReqPO);
                }
            }
            return !createFailed;
        }
        public void deletePlannedOrderTmpTable(ItemId pItemNumber, ReqQty pQty, ReqDateDlv pDateDlv, RouteId pRouteId)
        {
            CEB_PlannedOrderTmp plannedOrderTmp;
            delete_from plannedOrderTmp
            where plannedOrderTmp.CEB_ItemNumber == pItemNumber
               && plannedOrderTmp.CEB_ReqQty == pQty
               && plannedOrderTmp.CEB_RequirementDate == pDateDlv
               && plannedOrderTmp.CEB_RouteNumber == pRouteId;
        }
        str fileNameLookupFilename()
        {
            Filename filepath;
            Filename fileName;
            Filename fileType;
            [filepath, fileName, fileType] = fileNameSplit(fileNameControl.text());
            return fileName + fileType;
        }
        container fileNameLookupFilter()
        {
            #file
            return [
                WinApi::fileType('.dat'),
                WinApi::fileType('.xlsx'),
                WinApi::fileType('.xls')
            ];
        }
        str fileNameLookupInitialPath()
        {
            #WinAPI
            Filename filepath;
            Filename fileName;
            Filename fileType;
            [filepath, fileName, fileType] = Global::FileNameSplit(fileNameControl.text());
            return filepath;
        }
        str fileNameLookupTitle()
        {
            return fileNameControl.label();
        }
        public void getInventDim()
        {
            element.updateInventLocationFields();
        }
        private ReqCalcExplode getReqCalcExplode(ReqTrans _reqTrans)
        {
            if (reqCalcExplode)
            {
                return reqCalcExplode;
            }
            return ReqCalcExplode::newReqTrans(_reqTrans, null);
        }
        public void init()
        {
            super();
            ButtonUploadData.enabled(True);
            ButtonPostJournal.enabled(True);
            FileOpen.enabled(true);
        }
        public void insertFromForm(
            ReqPO _reqPO,
            InventDim _inventDim,
            InventLocationId _fromInventLocationId = '',
            InventLocationId _toInventLocationId = '',
            boolean _runExplosion = true,
            boolean _recalculateBomLevels = false)
        {
            ReqCalcExplodePo reqCalcExplodePo;
            ReqTrans transferDemand;
            InventDim inventDimDemand;
            ReqPlanData reqPlanData;
            reqTransPO.clear();
            if (_toInventLocationId)
            {
                _inventDim.InventLocationId = _toInventLocationId;
                _inventDim.initFromInventLocation(_inventDim.inventLocation());
            }
            _inventDim.clearNotCovPrDim(InventDimGroupSetup::newItemId(_reqPO.ItemId));
            if (! _reqPO.validateWrite() || ! _inventDim.checkDimFieldsValid(_reqPO.ItemId,_inventDim.RecId ? _inventDim.orig() : null))
            {
                throw Exception::Error;
            }
            ttsbegin;
            _reqPO.initPurchQty();
            reqPlanData = ReqPlanData::newReqPlanVersion(_reqPO.PlanVersion);
            _reqPO.RefId  = NumberSeq::newGetNumFromId(reqPlanData.sequencePlannedOrder()).num();
            _reqPO.setBOMCreated(_reqPO.ItemBomId ? true : false);
            _reqPO.setRouteCreated(_reqPO.ItemRouteId ? true : false);
            _reqPO.initYield();
            _reqPO.CovInventDimId = InventDim::findOrCreate(_inventDim).InventDimId;
            _reqPO.setIsDerivedDirectly(ReqSetupDim::newCovInventDimId(ReqSetup::newItemId(_reqPO.ItemId), _reqPO.CovInventDimId));
            _reqPO.insert();
            reqTransPo.ReqDateDlvOrig = _reqPO.ReqDateDlv;
            reqTransPOCreate::construct().parmAlwaysCreateBOM(_reqPO.isBOMCreated());
            reqTransPOCreate::construct().parmAlwaysCreateRoute(_reqPO.isRouteCreated());
            reqTransPOCreate::construct().insertFromReqPo(reqTransPo, _reqPO, false, reqPlanData);
            if (_fromInventLocationId && reqTransPo.RefType == ReqRefType::TransferPlannedOrder)
            {
                transferDemand = reqTransPo.selectDerived(true);
                while (transferDemand.RecId)
                {
                    inventDimDemand = transferDemand.inventDim();
                    inventDimDemand.InventLocationId = _fromInventLocationId;
                    inventDimDemand.initFromInventLocation(inventDimDemand.inventLocation());
                    transferDemand.CovInventDimId = InventDim::findOrCreate(inventDimDemand).InventDimId;
                    transferDemand.update();
                    next transferDemand;
                }
            }
            if (_runExplosion)
            {
                reqCalcExplodePo = this.getReqCalcExplode(reqTransPo);
                reqCalcExplodePo.parmRecalculateBomLevels(_recalculateBomLevels);
                reqCalcExplodePo.run();
                reqCalcExplodePo.refreshUpdatedReqPo(_reqPO);
            }
            ttscommit;
            ttsbegin;
            element.updateStatus(_reqPO.IsDerivedDirectly, _reqPO.RefId);
            ttscommit;
        }
        void updateInventLocationFields()
        {
            InventTable inventTable;
            InventDimGroupFieldSetup inventDimGroupFieldSetup;
            inventDim.data(InventDim::find(mReqPo.CovInventDimId));
            if (mReqPo.supplyPrinciple(mReqPlanData) == ReqSupplyPrinciple::Transfer)
            {
                inventTable = InventTable::find(mReqPo.ItemId);
                inventDimGroupFieldSetup = EcoResDimensionGroupSetup::getFieldSetupForItem(mReqPo.ItemId, fieldNum(InventDim, InventLocationId));
                if (!inventDimGroupFieldSetup.isCoveragePlanByDimensionEnabled())
                {
                    error(strFmt("@SYS106618", mReqPo.ItemId, EcoResStorageDimensionGroup::find(inventTable.storageDimensionGroup()).Name));
                    mReqPo.ItemId = '';
                }
                else
                {
                    toInventLocationId = inventDim.InventLocationId;
                    fromInventLocationId = mReqPo.reqSetupDim().mainInventLocationId(mReqPo.RefType,mReqPo.reqDateTime());
                }
            }
        }
        public void updateStatus(ReqIsDerivedDirectly isDerivedDirectly, InventTransRefId refId)
        {
            if (isDerivedDirectly == NoYes::No)
            {
                setPrefix(#prefixField(mReqPo,refId));
                select forUpdate mReqPo where mReqPo.RefId == refId;
                mReqPo.ReqPOStatus = ReqPOStatus::Approved;
                mReqPo.update();
                mapReqPoUpdated = new Map(typeName2Type(extendedTypeStr(recId)), Types::Record);
                mapReqPoUpdated.insert(mReqPo.RecId,mReqPo);
                countApprove++;
            }
            else
            {
                countDireived++;
            }
        }
        public int validate()
        {
            Query query;
            QueryRun queryRun;
            CEB_PlannedOrderTmp plandOrderTmpTable;
            ErrorMsg errerMsg = "";
            int countPass = 0;
            int countFail = 0;
            int countLine = 0;
            ReqPlanId _reqPlanId = "STD";
            query = CEB_PlannedOrderTmp_ds.query();
            queryRun = new QueryRun(query);
            while (queryRun.next())
            {
                countLine++;
                plandOrderTmpTable = queryRun.get(tablenum(CEB_PlannedOrderTmp));
                if ((select * from InventTable where InventTable.ItemId == plandOrderTmpTable.CEB_ItemNumber).RecId == 0)
                {
                    errerMsg = "@CEB221";
                }
                if (plandOrderTmpTable.CEB_RequirementDate < DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()))
                {
                    errerMsg = "@CEB222";
                }
                if ((select * from RouteTable where RouteTable.RouteId == plandOrderTmpTable.CEB_RouteNumber).RecId == 0)
                {
                    errerMsg = "@CEB224";
                }
                if(errerMsg != "")
                {
                    Error(strfmt("@CEB225", plandOrderTmpTable.CEB_ItemNumber, errerMsg));
                    countFail ++;
                    errerMsg = "";
                    continue;
                }
                try
                {
                    mReqPlanData = ReqPlanData::newReqPlanId(_reqPlanId);
                    mReqPo.PlanVersion = mReqPlanData.parmReqPlanVersionRefRecId();
                    mReqPo.RefType = ReqPO::reqPoType2ReqRefType(reqPoType::Production);
                    mReqPo.ItemId = plandOrderTmpTable.CEB_ItemNumber;
                    if(!mReqPo.validateFieldValue("ItemId"))
                    {
                        info(strFmt("Line error is %1", countLine));
                        countFail++;
                        continue;
                    }
                    mReqPo.modifiedFieldValue("ItemId");
                    mReqPo.Qty = plandOrderTmpTable.CEB_ReqQty;
                    mReqPo.modifiedFieldValue("Qty");
                    mReqPo.ReqDateDlv = plandOrderTmpTable.CEB_RequirementDate;
                    mReqPo.modifiedFieldValue("ReqDateDlv");
                    element.getInventDim();
                    if (mReqPo.validateFieldValue(fieldStr(ReqPO, ItemId)) && mReqPo.validateWrite())
                    {
                        mReqPo.ItemRouteId = plandOrderTmpTable.CEB_RouteNumber;
                        if(!ProdTable::validateRouteId(mReqPo.ItemRouteId,mReqPo.ItemId,inventDim))
                        {
                            info(strFmt("Line error is %1", countLine));
                            countFail++;
                            continue;
                        }
                        mReqPo.ItemBomId = plandOrderTmpTable.CEB_ItemBomId;
                        if(!ProdTable::validateBOMId(mReqPo.ItemBomId, mReqPo.ItemId, inventDim))
                        {
                            info(strFmt("Line error is %1", countLine));
                            countFail++;
                            continue;
                        }
                    }
                }
                catch(Exception::Error)
                {
                    info(strFmt("Line error is %1", countLine));
                    countFail++;
                    continue;
                }
                countPass++;
            }
            if(countPass != 0 || countFail != 0)
            {
                info(strfmt("@CEB244", countPass, countFail));
                CEB_PlannedOrderTmp_ds.executeQuery();
                if(countFail != 0)
                {
                    return 1;
                }
                return 0;
            }
            else
            {
                return 2;
            }
        }
        [Control("Button")]
        class ButtonValidation
        {
            void clicked()
            {
                int chkimport;
                chkimport = element.validate();
                if(chkimport == 2)
                {
                    Error("@CEB228");
                }
            }
        }
        [Control("Button")]
        class ButtonPostJournal
        {
            void clicked()
            {
                int chkimport;
                int countLine = 0;
                Query query;
                QueryRun queryRun;
                CEB_PlannedOrderTmp mCEB_PlannedOrderTmp;
                ReqPlanId _reqPlanId = "STD";
                countDireived = 0;
                countApprove = 0;
                chkimport = element.validate();
                if(chkimport == 0)
                {
                    query = CEB_PlannedOrderTmp_ds.query();
                    queryRun = new QueryRun(query);
                    ttsBegin;
                    while (queryRun.next())
                    {
                        countLine++;
                        mReqPo.clear();
                        inventDim.clear();
                        mCEB_PlannedOrderTmp = queryRun.get(tableNum(CEB_PlannedOrderTmp));
                        mReqPlanData = ReqPlanData::newReqPlanId(_reqPlanId);
                        mReqPo.PlanVersion = mReqPlanData.parmReqPlanVersionRefRecId();
                        mReqPo.RefType = ReqPO::reqPoType2ReqRefType(reqPoType::Production);
                        mReqPo.ItemId = mCEB_PlannedOrderTmp.CEB_ItemNumber;
                        mReqPo.modifiedFieldValue("ItemId");
                        mReqPo.Qty = mCEB_PlannedOrderTmp.CEB_ReqQty;
                        mReqPo.modifiedFieldValue("Qty");
                        mReqPo.ReqDateDlv = mCEB_PlannedOrderTmp.CEB_RequirementDate;
                        mReqPo.modifiedFieldValue("ReqDateDlv");
                        element.getInventDim();
                        mReqPo.ItemRouteId = mCEB_PlannedOrderTmp.CEB_RouteNumber;
                        mReqPo.ItemBomId = mCEB_PlannedOrderTmp.CEB_ItemBomId;
                        if (element.createReqPO())
                        {
                            super();
                        }
                    }
                    ttsCommit;
                    if(countDireived > 0)
                    {
                        info(strFmt("@SYS345114",countDireived));
                    }
                    if(countApprove > 0)
                    {
                        info(strFmt("@SYS119143",countApprove));
                    }
                    element.closeOk();
                }
                else
                {
                    Error("@CEB228");
                }
            }
        }
        [Control("String")]
        class FileOpen
        {
            public void gotFocus()
            {
                fileNameControl = this;
                super();
            }
        }
        [Control("Button")]
        class ButtonUploadData
        {
            void clicked()
            {
                str fileFullPath;
                FileUploadTemporaryStorageResult fileUpload;
                TOC_CEBPlannedOrderImport import = new TOC_CEBPlannedOrderImport();
                if (!TOC_FileUpload.getFileUploadResult())
                {
                    warning("Please select a file to import.");
                    return;
                }
                if (Box::yesNo("Do you want to import this file?", DialogButton::No, "Import Confirmation") != DialogButton::Yes)
                {
                    return;
                }
                this.enabled(false);
                FileOpen.enabled(false);
                try
                {
                    fileUpload = TOC_FileUpload.getFileUploadResult();
                    import.parmFileOpen(fileUpload);
                    import.run();
                    info("File imported successfully.");
                }
                catch
                {
                    error("An unexpected error occurred during the import process.");
                }
                finally
                {
                    FileOpen.enabled(true);
                    this.enabled(true);
                }
                CEB_PlannedOrderTmp_ds.executeQuery();
            }
        }
    }
     

    My create planned order function start from here 
     
    Control("Button")]
        class ButtonPostJournal
        {
            void clicked()
            {
                int chkimport;
                int countLine = 0;
                Query query;
                QueryRun queryRun;
                CEB_PlannedOrderTmp mCEB_PlannedOrderTmp;
                ReqPlanId _reqPlanId = "STD";
                countDireived = 0;
                countApprove = 0;
                chkimport = element.validate();
                if(chkimport == 0)
                {
                    query = CEB_PlannedOrderTmp_ds.query();
                    queryRun = new QueryRun(query);
                    ttsBegin;
                    while (queryRun.next())
                    {
                        countLine++;
                        mReqPo.clear();
                        inventDim.clear();
                        mCEB_PlannedOrderTmp = queryRun.get(tableNum(CEB_PlannedOrderTmp));
                        mReqPlanData = ReqPlanData::newReqPlanId(_reqPlanId);
                        mReqPo.PlanVersion = mReqPlanData.parmReqPlanVersionRefRecId();
                        mReqPo.RefType = ReqPO::reqPoType2ReqRefType(reqPoType::Production);
                        mReqPo.ItemId = mCEB_PlannedOrderTmp.CEB_ItemNumber;
                        mReqPo.modifiedFieldValue("ItemId");
                        mReqPo.Qty = mCEB_PlannedOrderTmp.CEB_ReqQty;
                        mReqPo.modifiedFieldValue("Qty");
                        mReqPo.ReqDateDlv = mCEB_PlannedOrderTmp.CEB_RequirementDate;
                        mReqPo.modifiedFieldValue("ReqDateDlv");
                        element.getInventDim();
                        mReqPo.ItemRouteId = mCEB_PlannedOrderTmp.CEB_RouteNumber;
                        mReqPo.ItemBomId = mCEB_PlannedOrderTmp.CEB_ItemBomId;
                        if (element.createReqPO())
                        {
                            super();
                        }
                    }
                    ttsCommit;
                    if(countDireived > 0)
                    {
                        info(strFmt("@SYS345114",countDireived));
                    }
                    if(countApprove > 0)
                    {
                        info(strFmt("@SYS119143",countApprove));
                    }
                    element.closeOk();
                }
                else
                {
                    Error("@CEB228");
                }
            }
        }

    CEB_PlannedOrderTmp is my table to store data from imported excel.

    Thanks in advance @André Arnaud de Calavon
  • Suggested answer
    André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    Hi umbrellatcorp,
     
     
    The error comes from using the classes ReqCalcExplode and ReqCalcExplodePo. Both extends the ReqCalc class which is replaced by Planning Optimization. You can check if you can create your import into the ReqPO table without calling methods from these classes. 
  • umbrellatcorp Profile Picture
    8 on at
     
    Could you please provide any official documentation or sample code that I can refer to for this type of customization?

    This would be very helpful for adjusting my existing solution to align with the current planning framework.

    Thank you.
  • André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    Hi umbrellatcorp,

    I'm not able to provide sample code as I don't know the exact requirement why you called these methods and what they should do in your customization. Besides, I did you read your coding. I only scanned your code for the classes and methods impacted by the decision from Microsoft to move from the legacy master planning calculation in X++ to the Planning Optimization service.
  • umbrellatcorp Profile Picture
    8 on at
    Hi @André Arnaud de Calavon,

    I just want to create planned order using code x++.
     

    Do you have any official documentation or example code that you can share or that you have encountered for this use case?


    Thank you.
  • André Arnaud de Calavon Profile Picture
    303,269 Super User 2026 Season 1 on at
    Hi,

    Unfortunately, I don't have code examples for you. The last time I was involved in a customization where an external tool created planned orders was with an AX2012 environment about 11 years ago. Aren't you able to just set field values in the ReqPO table and then insert the record?

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

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Congratulations to our 2025 Community Spotlights

Thanks to all of our 2025 Community Spotlight stars!

Leaderboard > Supply chain | Supply Chain Management, Commerce

#1
Mallesh Deshapaga Profile Picture

Mallesh Deshapaga 1,072

#2
Laurens vd Tang Profile Picture

Laurens vd Tang 227 Super User 2026 Season 1

#3
SoumitraforD365 Profile Picture

SoumitraforD365 130

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans