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.

Please make sure to like 👍, comment 💬, and share ↪ it with our D365 Community. A single share can save multiple hours of someone’s life.

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.

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

Note : (Read comments at the top for better understanding of the code, and feel free to reach out if you need my help with anything)

 //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 exist
         changecompany(_contract.parmDataAreaId())
         {

             ttsBegin;

             // Replace with your desired Production Order ID
             str prodId = _contract.parmProductionOrderNumber(); // Replace with the actual Production Order ID

             // Fetch the production order
             select forUpdate prodTable
         where prodTable.ProdId == prodId;

             if (prodTable.RecId != 0 && prodTable.ProdStatus == ProdStatus::Scheduled)
             {
                 try
                 {
                     // Initialize ProdParmStartUp parameters
                     prodParmStartUp.ProdId = prodTable.ProdId;
                     prodParmStartUp.initValue(); // Initialize default values

                     // Fetch the InventDimId from ProdTable
                     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;
                     }

                     // Validate journal names that these journal exist
                     if (!prodParmStartUp.RouteJournalNameId || !prodParmStartUp.bomJournalNameId)
                     {
                         throw error("Journal names are missing and could not be set. Please configure them in ProdParametersDim.");
                         return false;
                     }

                     // Set additional fields
                     prodParmStartUp.EndPicklist         = NoYes::No;
                     prodParmStartUp.EndRouteCard        = NoYes::No;
                     prodParmStartUp.PostNowBOM          = NoYes::No; // Updated as requested
                     prodParmStartUp.PostNowRoute        = NoYes::No; // Updated as requested
                     prodParmStartUp.References          = NoYes::No;
                     prodParmStartUp.StartUpProduction   = NoYes::Yes;
                     prodParmStartUp.AutoUpdate          = NoYes::Yes;
                     prodParmStartUp.bomAutoConsump      = BOMAutoConsump::FlushingPrincip;
                     prodParmStartUp.RouteAutoConsump    = RouteAutoConsump::RouteDependent;

                     // Use conditional logic for postDate we are getting it from the request
                     prodParmStartUp.PostDate            = _contract.parmDate();
                     if(prodtable.QtySched < _contract.parmGoodQuantity())
                     {
                         throw error("Good quantity can not be greater than startUp quantity.");
                         return false;
                     }

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

                     // Insert ProdParmStartUp record
                     prodParmStartUp.insert();

                     // Start the production order
                     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. Process completed without errors.", _contract.parmProductionOrderNumber()));

         }
     }
     catch (Exception::CLRError)
     {
         System.Exception interopException = CLRInterop::getLastException();
         returnMessage = interopException.ToString();
        return false;
     }

     return true;
 }

Leave a Reply

Your email address will not be published. Required fields are marked *