Yep, we also have sometimes a Customization in a lower company where we would like to Run a BAQ and Grab Data from the Master Company without having to Pass Data Down… like PartRev is not Multi-Company Friendly which makes sense, but we wanted to avoid some Service Connect stuff as we want to replace it with APIs…
There are such cases too where you have Master Data and you don’t want to give Employees Access to Upper Companies…
In that case I had to instantiate a New Session as the SysAgent and Execute the BAQ as a Impersonated System Agent who has access to all Companies… Works Great by the way!
Save this Snippet! Took Days to get right! Runs and honors Session Licensing timeouts etc… Also instead of managing another Service Account, I used the “Agent User” a method discovered in the MRP Engine. Works like a charm!
// Session Impersonation Vars
Ice.Core.Session newSession;
// InitCustomCode
this.newSession = this.GetNewSessionAsSysAgent();
// DestroyCustomCode
// Begin Custom Code Disposal
Ice.Proxy.Lib.SessionModImpl sMod = GetInstanceField(typeof(Ice.Core.Session), newSession, "sessionMod") as Ice.Proxy.Lib.SessionModImpl;
sMod.Logout();
this.newSession = null; // Do NOT Dispose it, it will kill Epicor
// We need a Session Link to 003 which Local Users
// may not have access to - lets Auth as Agent
// could be refactored a bit
public Ice.Core.Session GetNewSessionAsSysAgent()
{
string username = string.Empty;
string password = string.Empty;
object searchReslts = ProcessCaller.PerformSearch(oTrans.EpiBaseForm, "SysAgentAdapter", "Rows", string.Empty);
if (searchReslts is DataSet) {
DataSet searchDS = (DataSet) searchReslts;
if (searchDS.Tables[0].Rows.Count > 0) {
username = searchDS.Tables["SysAgent"].Rows[0]["SysUserID"].ToString();
password = searchDS.Tables["SysAgent"].Rows[0]["SysPassWord"].ToString();
}
}
if (username != string.Empty && password != string.Empty)
{
try {
return new Ice.Core.Session(username, Epicor.Security.Cryptography.Encryptor.DecryptToString(password));
}
catch (Exception ex)
{
EpiMessageBox.Show("Unable to Authenticate with Company 00300000.\n" + ex.Message, "SMI Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return null;
}
internal static object GetInstanceField(Type type, object instance, string fieldName)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Static;
FieldInfo field = type.GetField(fieldName, bindFlags);
return field.GetValue(instance);
}
public System.Data.DataSet GetBAQDataSetDataTagFromMainCompany(string partNum, string partRev)
{
if (newSession == null)
{
MessageBox.Show("Unable to Authenticate with Company 003, Please See System Administrator");
return null;
}
using (this.oTrans.PushDisposableStatusText("Initializing Global Query...", true))
{
ILauncher iLnch = new ILauncher( newSession );
//removeEventhandlers(newSession); // Done Globally
using (var newTransaction = new EpiTransaction(iLnch))
using (var adapterDynamicQuery = new DynamicQueryAdapter(newTransaction))
{
adapterDynamicQuery.BOConnect();
// Declare and Initialize Variables
string BAQName = "SMI-zGetDataTagByPartRev";
Ice.BO.QueryExecutionDataSet ds = new Ice.BO.QueryExecutionDataSet();
// Add Parameter Rows
ds.ExecutionParameter.AddExecutionParameterRow("PartNum", partNum, "nvarchar", false, Guid.Empty, "A");
ds.ExecutionParameter.AddExecutionParameterRow("RevisionNum", partRev, "nvarchar", false, Guid.Empty, "A");
// Call Adapter method
adapterDynamicQuery.ExecuteByID(BAQName, ds);
System.Data.DataSet results = adapterDynamicQuery.QueryResults;
return results;
}
}
return null;
}
Def would be nice if On-Prem folks could do this with some ease tags @Rich