callContextClient.CurrentPlant in Scheduled Function

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

3 Likes

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 :grimacing: 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.

1 Like

This doesn’t survive the scheduled is created (every time the function runs) Session might be ok.

1 Like

thanks for this post. I had this exact problem that I had a BAQ that used the BAQ.CurrentPlant that worked but when the function ran the callContext.CurrentPlant was the value of my user profile for the last time I changed plants. In restrospect, I think making the plant a parameter is a better method but I was able to use Session.PlantID in my function to get the same value as BAQ.CurrentPlant. This was the value of the plant when I submitted the job.