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;
}