Thanks for the reply Jose.
I’m just running a test app at the moment, trying to get this all working so ignore the limited scope just yet.
In summary, I’m creating an order and line, adding my dummy configured part and trying to run the configurator. I’m not getting very far with the configurator.
Let me know if I’ve left out any required details and I’ll fill the gaps
// set up EpicorRest in previous routine
EpicorRest.AppPoolHost = sAppPoolHost;
EpicorRest.AppPoolInstance = sInstance;
EpicorRest.UserName = "username";
EpicorRest.Password = "password";
EpicorRest.Company = "company";
EpicorRest.APIKey = sAPIKey;
EpicorRest.APIVersion = EpicorRestVersion.V2;
private static string CreateOrderHed()
{
string sReturn = "ERROR";
// create a new order with an empty ds
dynamic dNewOrd = EpicorRest.BoPost("Erp.BO.SalesOrderSvc", "GetNewOrderHed", new { ds = new { } });
// isolate OrderHed and remove from ds
dynamic dOH = dNewOrd.ResponseData.parameters.ds;
// update required values in OrderHed
dOH["OrderHed"][0].Company = "CEB";
dOH["OrderHed"][0].CustNum = 180;
dOH["OrderHed"][0].BTCustNum = 180;
dOH["OrderHed"][0].ShipToCustNum = 180;
dOH["OrderHed"][0].PONum = "RJM" + DateTime.Today.ToString("MMdd");
dOH["OrderHed"][0].NeedByDate = DateTime.Today.AddDays(20).ToString("yyyy-MM-dd");
dOH["OrderHed"][0].TermsCode = "30";
// put values back in ds
dOH = new { ds = dOH };
// update the order
dynamic dUpdateOrder = EpicorRest.BoPost("Erp.BO.SalesOrderSvc", "Update", dOH);
string sNewON;
string sNewLN;
if (dUpdateOrder.Response.StatusCode == System.Net.HttpStatusCode.OK)
{
// get order number of new order from OrderHed
sNewON = dUpdateOrder.ResponseData.parameters.ds["OrderHed"][0].OrderNum;
}
else
{
return "ERROR at Order";
}
// _________________________________________________________________________________________________
// create a new line
dynamic dNewLine = EpicorRest.BoPost("Erp.BO.SalesOrderSvc", "GetNewOrderDtl", new { ds = dUpdateOrder, orderNum = sNewON });
// isolate OrderDtl and remove from ds
dynamic dOD = dNewLine.ResponseData.parameters.ds;
// update required values in OrderDtl
dOD["OrderDtl"][0].PartNum = "123456";
dOD["OrderDtl"][0].RevisionNum = "01";
dOD["OrderDtl"][0].LineDesc = "This is an automated description";
dOD["OrderDtl"][0].ProdCode = 5370;
// put values back in the ds
dOD = new { ds = dOD };
// update the order
dynamic dUpdateLine = EpicorRest.BoPost("Erp.BO.SalesOrderSvc", "Update", dOD);
if (dUpdateLine.Response.StatusCode == System.Net.HttpStatusCode.OK)
{
//get order line of the new line from OrderDtl
sNewLN = dUpdateLine.ResponseData.parameters.ds["OrderDtl"][0].OrderLine;
}
else
{
return "ERROR at Line";
}
// set SysRowID of the OrderLine record
string sODSysRowID = dUpdateLine.ResponseData.parameters.ds["OrderDtl"][0].SysRowID;
string sODPart = dUpdateLine.ResponseData.parameters.ds["OrderDtl"][0].PartNum;
string sODConfigRev = dUpdateLine.ResponseData.parameters.ds["OrderDtl"][0].RevisionNum;
dynamic dBaseConfig = EpicorRest.BoPost("Erp.BO.SalesOrderSvc", "GetBasePartAndConfigType",
new { sourceSysRowID = sODSysRowID });
// _________________________________________________________________________________________________
// configurator
// isolate config associated with ordered part
dynamic dBaseConfigParams = dBaseConfig.ResponseData.parameters;
string sConfigID = dBaseConfigParams["configID"];
// get context header from last call
dynamic dContext = ((IEnumerable<dynamic>)dBaseConfig.Response.Headers).Where(header => header.Name == "ContextHeader").FirstOrDefault();
// create ConfigParams ds
dynamic dConfigParams = new { RuntimeDS = new { }, configID = sConfigID, uniqueID = "0/0", dContext };
// get RuntimeDS from GetNewPcConfigParams
dynamic dBlankConfig = EpicorRest.BoPost("Erp.BO.ConfigurationRuntimeSvc", "GetNewPcConfigParams",dConfigParams);
// get context header from last call
dContext = ((IEnumerable<dynamic>)dBlankConfig.Response.Headers).Where(header => header.Name == "ContextHeader").FirstOrDefault();
// isolate PcConfigurationParams from the RunTime ds
dynamic dRTParams = dBlankConfig.ResponseData.parameters.RuntimeDS.PcConfigurationParams[0];
// update values in RunTimeDS
dRTParams["RelatedToTable"] = "OrderDtl";
dRTParams["RelatedToSysRowID"] = sODSysRowID;
dRTParams["SourceTable"] = "PartRev";
dRTParams["TestMode"] = "PRODUCTION";
dRTParams["ConfigID"] = sConfigID;
dRTParams["UniqueID"] = "0/0";
dRTParams["PartNum"] = sODPart;
dRTParams["RevisionNum"] = sODConfigRev;
// put values back in ds
dBlankConfig.ResponseData.parameters.RuntimeDS.PcConfigurationParams = dRTParams;
dynamic dCRTDS = new { PcValueGrp = new { }, PcValueHead = new { }, PcConfigurationParams = dRTParams, PcConfiguredDrawings = new { },
PcContextProperties = new { }, PcInputsLayerDetail = new { }, PcInputsLayerHeader = new { }, PcInputsPublishToDocParams = new { },
PcInputVar = new { }, PcValueInputLayerDetail = new { }, PcValueInputLayerHeader = new { }, QBuildMapping = new { },
ExtensionTables = new { }
};
dynamic dConfigSummary = new { ConfigurationSummary = new {}, PcInputValue = new {}, ExtensionTables = new {} };
// tried with and without context, same result
dynamic dTest = new { configurationRuntimeDS = dCRTDS, configurationSummaryTS = dConfigSummary }; //, CallContext = dContext };
// fails at this point with HttpStatus 400 and the error message “No ttPcConfigurationParams record was found, at least one ttPcConfigurationParams record is needed.”
dynamic dPreConfig = EpicorRest.BoPost("Erp.BO.ConfigurationRuntimeSvc", "PreStartConfiguration", dTest);
return sReturn;
}
Trace log attached. This starts after the Order and Line have been created and the “Configure…” button is clicked.
Happy to also export the configurator and attach if that would be useful but it’s just a small dummy config with a handful of controls while I test this process.
By all means “correct” my code too - I’m always happy to learn better ways to do things.
Thanks again for looking into this with me, much appreciated.
PreConfigShared.xml (142.5 KB)