How to launch a form to use a site other than the current site

I am working on a screen customization that will launch the JobEntry form from itself in a different site (user is in FIELD1 and job is located in MFG) using the code below.

var session = (Ice.Core.Session)oTrans.Session;
var oldplant = session.PlantID; //plantid="FIELD1"
session.PlantID = "MFG"; //plant I want to open the form in
LaunchFormOptions launchObject = new LaunchFormOptions(); 
launchObject.IsModal = false; 
launchObject.SuppressFormSearch = true;
launchObject.ValueIn = newJobNum;
ProcessCaller.LaunchForm(oTrans, "PJGO1010", launchObject);
session.PlantID = oldplant; //reset session back to original

I’m encountering two issues:

  1. A warning message "Attempting to launch Erp.UI.JobEntry from itself is not logical. Do you want to launch a new instance?

  2. More importantly, after answering Yes, the form opens and the status bar shows me it’s been opened in the MFG site but the job is not there. When searching for jobs from the secondary form, it appears it is still in the FIELD1 site.

The reason we want to do this is that we repair elevators through our field office (FIELD1) and frequently need materials manufactured from our manufacturing facility (MFG). The person entering the job information is creating the main field job and I am automating the generation of the manufactured job in the other site. It would be great if I can also pop up the form of the manufactured job for them to allow them to enter the materials on the other screen.

I have read in other posts against tampering with the session object but it will really make our data entry person’s lives much easier. Site security is not an issue in this instance because all of our users have access to the MFG site. Any help would be greatly appreciated!

Thanks,
Tanner

1 Like

Since 10.2 upgrade, we can have our tiles setup per plant. No need to change plants. So JobEntryplantA for tile 1 and JobEntryPlantB for tile2.

Would it be possible to call a tile as we can call menus? Or maybe your form call options may have a an option to pass a plant as a parameter?

I wander…?

@Hogardy Thanks for the input. We do that with tiles on Active Homepage as well so it seems possible to do this. Is there a way to decompile the main menu interface to investigate what it is doing?

I see if I open the second form as modal it appears to work as it should. I assume this is because it stops processing commands in the original form. However, it would be much better for the users if these forms could be maintained simultaneously.

If you remove the final part of your code that sets the Plant back, does it work?

If so, perhaps there are two options:

  1. I wonder if you couldnt just make a copy of the oTrans for the purpose of passing the value. This means you could change and leave the plant value. Along with the benefits of this method, you could spoof the name of the calling form possible and avoid the “DuplicateLaunch” error you are getting.

  2. Another possibility would be to add a callback from form you open. This way you could wait until the form spins up and is configured before continuing execution on the calling form (to set the plant back)

Thanks for the response @Chris_Conn

It appears that if I don’t set the plant back, it does work on the form that is launched. Knowing that, I took your advise and

  1. I tried to duplicate the oTrans but can’t quite figure out the syntax . Do you have any pointers on how to duplicate the object?

  2. I also tried to launch a callback form (using ProcessCaller.LaunchCallbackForm instead of ProcessCaller.LaunchForm) but that didn’t do anything differently (unless I am misunderstanding)

You can use MemberwiseClone…except for Epicor protected it. So we use a page from @josecgomez 's playbook and use reflection

	MethodInfo dynMethod = oTrans.GetType().GetMethod("MemberwiseClone", 
    	BindingFlags.NonPublic | BindingFlags.Instance);
	

     var mytrans = (EpiTransaction)dynMethod.Invoke(oTrans,  null ); //oTrans.MemberwiseClone();
    MessageBox.Show(mytrans.Name);

@Chris_Conn Thanks for the code example! I used this code example to make a clone and passed the clone into the launched form. Unfortunately, the behavior is the same. Could it be the clone references the same CoreSession object which contains the site that is being changed?

My thought was you’d change your plant in the cloned session and pass it.

I remember doing something similar and I used a clone instead and I wonder instead of using SetUser if you can use SetPlant or SetPlantID.

Son of a… So there is a Clone() metthod on Session object…

1 Like

Thank you both for the suggestions. I am think I tried to clone the session and that did not work. However I will try it when I get back to work on the 12th and let you know if it works!

Thanks

Tanner

Thanks

Tanner Post

I attempted to clone the session but now I am uncertain how to pass the cloned session into the ProcessCaller.LaunchForm or if I need to use a different technique to launch the form in the other session.

var newsession = ((Ice.Core.Session)oTrans.Session).Clone(session.License,null,null);
newsession.PlantID = "MFG";
newsession.OnSessionChanged(Ice.Core.Session.SessionChangedItem.Plant);
LaunchFormOptions launchObject = new LaunchFormOptions()
{
  IsModal = false,
  SuppressFormSearch = true,
  ValueIn = newJobNum
};
//it requires sender which would normally be an EpiTransaction but I'm trying to pass just a session...
ProcessCaller.LaunchForm(newsession, "PJGO1010", launchObject);

I cannot pass just the session into the form and receive an error message stating: “Menu ID PJGO1010 is not valid for the current user”. I think I may be missing something fairly simple. Any other ideas @hkeric.wci / @Chris_Conn?

Do you get the same error when passing oTrans for that menu?

Also, did you try my reflection method? I only ask because it should deep copy, ensuring you get the same exact object (and you change only plant)

1 Like

@chris_conn I do not get the same error message when using your method, but unfortunately the result appears to be the same as modifying the session on the original oTrans. As soon as the plant on oTrans session is changed, the clone’s plant changes as well…

MethodInfo dynMethod = oTrans.GetType().GetMethod("MemberwiseClone",BindingFlags.NonPublic | BindingFlags.Instance);
var mytrans = (EpiTransaction)dynMethod.Invoke(oTrans, null);
var newsession = (Ice.Core.Session)mytrans.Session;
newsession.PlantID = "MFG";
newsession.OnSessionChanged(Ice.Core.Session.SessionChangedItem.Plant);

LaunchFormOptions launchObject = new LaunchFormOptions()
{
	IsModal = false,
	SuppressFormSearch = true,
	ValueIn = newJobNum
};

ProcessCaller.LaunchForm(mytrans, "PJGO1010", launchObject);
//this appears to also modify the plant ID on mytrans but should only by for oTrans...
session.PlantID = oldplant;
session.OnSessionChanged(Ice.Core.Session.SessionChangedItem.Plant);

Well it was worth a try. I suspect, session object is still just a pointer back to an actual session, thus despite a new object it is still acting on the same session. This means we’d need to create a new session to do this (and ultimately consume a license)

:frowning: Shoot! Is there a way to see what’s happening when clicking a menu item from the main menu which can load plant context in? That technique appears to be able to switch plants without consuming another session / license

Full server trace might expose some details.I’d look at the decomp, but you have to go mighty deep to find stuff like that.

Hmm, stumbled across this…

@Chris_Conn That is interesting, I will look into this method a bit more to see if it can be applied client side. Thanks for the info!