I’ve created an Epicor function that references callContextClient.CurrentPlant. The function works correctly if I run it from a BPM or invoke it via Postman. However, if I run it from a scheduled function, it seems to be using the current plant associated with the task agent, not the Cur-Plant that was set in the SysAgentTaskParam dataset. Has anyone run into this before and any advice on simplest way to set the site on the function? I was hoping to use Epicor functionality but maybe it’s simpler to use a powershell script via Windows scheduler
Pass the plant as a parameter to the function then use the temporary session constructor to switch to that plant
CallContextClient (as the name implies) is tied to the client running the code in this case the task agent
Thanks!
Another question about this topic. I have a function library that calls nested functions and it seems callContextClient.CurrentPlant in the sub functions does not know the plant changed and defaults back to the plant from the original client. Anyone have advice on getting the CurrentPlant value / context reset in subfunction?
CALLER FUNCTION “SchedService” loops through dataset and passes site name in as parameter
var mySites = (myDs.Tables[0].AsEnumerable()).Select(r=>r.Field<string>("Plant")).Distinct().ToList();
foreach(var sendSite in mySites){
//copy filtered datatable
var innerds = myDs.Tables[0].AsEnumerable().Where(r=>r.Field<string>("Plant")==sendSite).CopyToDataTable();
var sendDS = JsonConvert.SerializeObject(innerds); //for input parameter
var subf = ThisLib.SchedForSite(sendSite,sendDS);
}
CALLED FUNCTION “SchedServiceForSite” input strings (sendSite (string), sendDS (string))
using(CallContext.Current.TemporarySessionCreator.SetCompanyID("MEI").SetPlantID(sendSite).Create())
{
var dt = JsonConvert.DeserializeObject<DataTable>(sendDS);
if(sendSite!=callContextClient.CurrentPlant) {
throw new Exception($"You are in site {callContextClient.CurrentPlant}. You should be in {sendSite}"); //throws error, site doesn't match yet :(
}
foreach(DataRow dr in dt.Rows) {
var mkjob = ThisLib.ChangeJob((string)dr["PartNum"]); //really where site context matters
}
}
``
Pass in the plant as a parameter and use temporary session creator there too.
I’ve found Session.PlantID to be reliable.
Thank you but for some reason it is not working the way I think it should, or more likely I’m just confused Setting the plant id in the temp session context does not appear to reset the callContextClient.CurrentPlant property. Because it is not getting reset, existing error checking I have throws an error prior to processing. I could remove error checking in the functions but I am concerned running without that check could lead to further downstream issues with BO / BPM calls?
It won’t, just pass the plant along to the next function and do so again
Thanks! I tried setting that in the function editor and receive “Property or indexer ‘ISession.PlantID’ cannot be assigned to – it is read only”. Do I need to use reflection to get this to work or is there a trick to find the correct Session object in functions?
Ok I’ll try that, thanks for the advice, I really appreciate it! Do you know if there is noticeable overhead with using the TemporarySessionCreator?
I guess I don’t understand. When I schedule a function, I do it from the plant that it needs to run in. If I do multiple companies/plants, then I do the temporary company/plant method that @josecgomez suggested.
When I do just a single plant, then the Session.PlantID gives you the plant it was run from in the task agent. Maybe callContextClient.CurrentPlant gives you the same thing. I dunno.
This doesn’t survive the scheduled is created (every time the function runs) Session might be ok.