Back to InsightsD365 F&O

Start Production Order & Create Picking List and Route Card Journal Using X++ (Part 2)

May 18, 2025 8 min read D365 F&O

In the previous article, we learned how to firm a planned production order using X++ (Part 1). When we firm a planned production order, it automatically creates a production order.

In this blog post, we will learn how to start the created production order and how to create its Picking list and Route card journal.

**Note:** Read comments in the code for better understanding, and feel free to reach out if you need help with anything.

The code for starting the production order and creating the Picking List and Route Card journal is defined below:

xpp
// This method is used to change the status of the production order from Scheduled to Started
private boolean updateStatusToStarted(ProdOrderStatusToStartedRequestContract _contract)
{
    List JournalIdList = new List(Types::Class);
    ProdTable prodTable;
    ProdParmStartUp prodParmStartUp;
    ProdParametersDim prodParametersDim;
    str inventDimId;
    ProdJournalTable prodJournalTable;

    try
    {
        // Change the company to legal entity in which the production order exists
        changecompany(_contract.parmDataAreaId())
        {
            ttsBegin;
            str prodId = _contract.parmProductionOrderNumber();

            select forUpdate prodTable where prodTable.ProdId == prodId;

            if (prodTable.RecId != 0 && prodTable.ProdStatus == ProdStatus::Scheduled)
            {
                try
                {
                    prodParmStartUp.ProdId = prodTable.ProdId;
                    prodParmStartUp.initValue();

                    inventDimId = prodTable.InventDimId;
                    if (!inventDimId)
                    {
                        throw error("InventDimId not found for the production order.");
                        return false;
                    }

                    prodParametersDim = ProdParametersDim::find(inventDimId);
                    if (prodParametersDim)
                    {
                        if (!prodParmStartUp.RouteJournalNameId)
                            prodParmStartUp.RouteJournalNameId = prodParametersDim.RouteJournalNameId;
                        if (!prodParmStartUp.bomJournalNameId)
                            prodParmStartUp.bomJournalNameId = prodParametersDim.BOMJournalNameId;
                    }
                    else
                    {
                        throw error("ProdParametersDim not found for the given InventDimId.");
                        return false;
                    }

                    if (!prodParmStartUp.RouteJournalNameId || !prodParmStartUp.bomJournalNameId)
                    {
                        throw error("Journal names are missing. Please configure them in ProdParametersDim.");
                        return false;
                    }

                    prodParmStartUp.EndPicklist         = NoYes::No;
                    prodParmStartUp.EndRouteCard        = NoYes::No;
                    prodParmStartUp.PostNowBOM          = NoYes::No;
                    prodParmStartUp.PostNowRoute        = NoYes::No;
                    prodParmStartUp.References          = NoYes::No;
                    prodParmStartUp.StartUpProduction   = NoYes::Yes;
                    prodParmStartUp.AutoUpdate          = NoYes::Yes;
                    prodParmStartUp.bomAutoConsump      = BOMAutoConsump::FlushingPrincip;
                    prodParmStartUp.RouteAutoConsump    = RouteAutoConsump::RouteDependent;
                    prodParmStartUp.PostDate            = _contract.parmDate();

                    if (prodtable.QtySched < _contract.parmGoodQuantity())
                    {
                        throw error("Good quantity cannot be greater than startup quantity.");
                        return false;
                    }

                    prodParmStartUp.StartUpQty = _contract.parmGoodQuantity();
                    prodParmStartUp.LineNum = ProdParmStartUp::lastLineNum(prodParmStartUp.ParmId) + 1;
                    prodParmStartUp.insert();

                    if (!prodTable.status().runStartUp(prodParmStartUp, false, null, null, false))
                    {
                        throw error("Failed to start the production order using runStartUp.");
                        return false;
                    }
                }
                catch (Exception::CLRError)
                {
                    System.Exception interopException = CLRInterop::getLastException();
                    returnMessage = interopException.ToString();
                    return false;
                }
            }
            else
            {
                throw error("Production order not found or is not in the Schedule status.");
                return false;
            }
            ttsCommit;
            info(strFmt("Production order %1 has been successfully started.", _contract.parmProductionOrderNumber()));
        }
    }
    catch (Exception::CLRError)
    {
        System.Exception interopException = CLRInterop::getLastException();
        returnMessage = interopException.ToString();
        return false;
    }
    return true;
}

Have a Dynamics 365 Challenge?

Our experts are ready to help. Book a free consultation today.

Talk to an Expert