Add item to handheld menu in E10.2.200.1

After some reflection (pun intended) I’ve sort of figured out that as of 10.2.200.1 you have to add items to the handheld menu by adding rows to the table that holds the entries. I haven’t been able to make that happen yet.

Here’s what I have so far:
MESMenuAdapter mesMenuAdapter = new MESMenuAdapter(HHMenuForm);
mesMenuAdapter.BOConnect();
Guid guid = new Guid(“9a8a3fad-ef1d-40c4-87a8-3599fbdee0ad”);
Erp.BO.MESMenuDataSet.MESMenuRow newrow =
mesMenuAdapter.MESMenuData.MESMenu.NewMESMenuRow();
newrow.ParentMESMenuID = 1;
newrow.Seq = 7;
newrow.MenuID = “HHMENUID”;
newrow.MenuDesc = “7 - Menu Title”;
newrow.Company = “XXXXX”;
newrow.MESMenuID = 700;
newrow.Hidden = false;
newrow.SystemFlag = false;
newrow.MenuType = “H”;
newrow.SysRowID = guid;
mesMenuAdapter.MESMenuData.MESMenu.AddMESMenuRow(newrow);
Boolean updateok = mesMenuAdapter.UpdateMenuData();

Nothing other than the standard initial menu entries were showing up. When I added the UpdateMenuData call I get a runtime error:
MESMenu data has not yet been initialized for company “companynumber”.

This code is in HHMenuForm_Load. Obviously that’s too early. When should this be called?

3 Likes

Hey Michael,

We actually ran into some similar issues figuring this one out for ourselves, so hopefully I can shed some light on a few things.

First, as far as I can tell there is no way in current core Epicor to add new menus to the database tables. The GetNew and Update methods aren’t implemented, and the UpdateMenuData method looks like it is designed to handle the security data for the MES Menus (stored in the MESMenuSecurity table) rather than updating the MESMenu table. The error message you’re seeing is actually tied to the “System Setup > Security Maintenance > Handheld / MES Menu Security Maintenance” program which was added in 10.2 to manage the menu options based on employee security.

To add the menu items, I added them to the MESMenu EpiDataView in the transaction. This also involved filling in the security settings for the program, and specifying whether or not the current employee had access to the menu. Here’s a snip:

		edvMenu = (EpiDataView)oTrans.EpiDataViews["MESMenu"];
		DataRow row;
		
		if (edvMenu.dataView.Table.Select("MESMenuID = 700").Length <= 0)
		{
			row = edvMenu.dataView.Table.NewRow();
			
			// Menu Setup
			row["Company"] = ((Session)oTrans.Session).CompanyID;
			row["MESMenuID"] = 700;
			row["ParentMESMenuID"] = 1;
			row["MenuType"] = "H";
			row["Seq"] = 7;
			row["MenuID"] = "HHMENUID";
			row["MenuDesc"] = "Menu Title"; // Seq property is appended to start of menu title by default now.
			row["Hidden"] = false;
			row["SystemFlag"] = false;

			// Employee Security
			row["MESMaterialHandler"] = true;
			row["MESSupervisor"] = true;
			row["MESShipping"] = true;
			row["MESProduction"] = true;
			row["MESService"] = true;
			row["PCIDInbound"] = false;
			row["PCIDOutbound"] = false;
			row["PCIDInventory"] = false;
			row["PCIDManufacturing"] = false;
			row["PCIDQuality"] = false;
			row["CurrentEmpAllowed"] = ValidateEmpPermissions(dsEmpBasic.EmpBasic.Rows[0], row);
			row["TranslateMenuDesc"] = "Menu Title";
			row["BitFlag"] = 0;
			row["RowMod"] = "";
			
			edvMenu.dataView.Table.Rows.Add(row);
		}

ValidateEmpPermissions just compares the current employee’s settings against the menu’s security options, and returns true if the employee should be allowed to access the menu. I can send you code for this as well if you’d like.

As for timing, we call this both at the end of the InitializeCustomCode method and in an AfterAdapterMethod event handler, for the GetMenuData method. We also only load the custom menus if there is an employee ID specified (since in Epicor 10.2, the menus aren’t shown unless an employee is entered).

The only thing with this is that I haven’t figured out yet how to get a custom menu to show in the initial menu when the program first loads. If you open any of the other menus and then return to the main menu, your custom menu will show up at that point.

For what it’s worth, we also opened a case with Epicor Support regarding this, and they have confirmed that there’s no way in Core Epicor to add new records to the Erp.MESMenu table. We’re in the process of submitting an enhancement request for this.

private void HHMenuForm_Load(object sender, EventArgs args)
{
oTrans.GetType().GetMethod(“addMenuItem”, BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] {typeof(int), typeof(int), typeof(string), typeof(string)}, null).Invoke(oTrans, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { 8, 5, “CS Putaway”, “HHCSPUT” }, null);
}

This is the code that I use in E10.1.600.14, but alas it doesn’t work in E10.2. Thanks for the heads up, I’ll watch this post for any updates regards doing the same in 10.2

Jason, my apologies for the delay in getting back to you. Thank you for the example. I’d like to see the ValidateEmpPermissions code if you don’t mind. it would be helpful.

I also got a reply from Chris Conn that does deal with having the added items appear when the programs first loads.

this is it:

    private void HHMenuForm_Load(object sender, EventArgs args)
    {
           // Add Event Handler Code
           var view = oTrans.Factory("MESMenu");
           var menuItem = view.dataView.AddNew();
           menuItem.BeginEdit();
           menuItem["MESMenuID"] = 177;
           //menuItem["IsMenu"] = true ;
           menuItem["Hidden"] = false;
           menuItem["CurrentEmpAllowed"] = true;
           menuItem["MenuType"] = "H";
           menuItem["ParentMESMenuID"] = 1;
           menuItem["TranslateMenuDesc"] = "Chris";
           menuItem["Company"] = ((Ice.Core.Session)oTrans.Session).CompanyID;
           menuItem.EndEdit();

           var menuItem2 = view.dataView.AddNew();
           menuItem2.BeginEdit();
           menuItem2["MESMenuID"] = 178;
           //menuItem["IsMenu"] = true ;
           menuItem2["Hidden"] = false;
           menuItem2["CurrentEmpAllowed"] = true;
           menuItem2["MenuType"] = "H";
           menuItem2["ParentMESMenuID"] = 177;
           menuItem2["MenuID"] ="HHMN1001";
           menuItem2["TranslateMenuDesc"] = "ChrisSub";
           menuItem2["Company"] = ((Ice.Core.Session)oTrans.Session).CompanyID;
           menuItem2.EndEdit();

           var menuCall = HHMenuForm.GetType().GetMethod("showMenu",  BindingFlags.Instance | BindingFlags.NonPublic,null,CallingConventions.Any,  new Type[]{typeof(int)}, null);
           menuCall.Invoke(HHMenuForm,new object[]{1});
    }

I hope he doesn’t mind me sharing it, but he was very generous in sending it to me so I believe it should be ok.

1 Like

No problem, enjoy :smiley:

Thanks Michael. As requested, here’s the code snip for ValidateEmpPremissions:

private bool ValidateEmpPermissions(DataRow employee, DataRow menuOption)
{
	if (Convert.ToBoolean(employee["MaterialHandler"].ToString()) && Convert.ToBoolean(menuOption["MESMaterialHandler"].ToString()))
	{
		return true;
	}
	
	if (Convert.ToBoolean(employee["ShopSupervisor"].ToString()) && Convert.ToBoolean(menuOption["MESSupervisor"].ToString()))
	{
		return true;
	}
	
	if (Convert.ToBoolean(employee["ShipRecv"].ToString()) && Convert.ToBoolean(menuOption["MESShipping"].ToString()))
	{
		return true;
	}
	
	if (Convert.ToBoolean(employee["ProductionWorker"].ToString()) && Convert.ToBoolean(menuOption["MESProduction"].ToString()))
	{
		return true;
	}
	
	if (Convert.ToBoolean(employee["ServTech"].ToString()) && Convert.ToBoolean(menuOption["MESService"].ToString()))
	{
		return true;
	}
	
	return false;
}

We only look at these five properties ourselves since it’s how we choose to manage our employee’s security, but you could also include the PkgControl properties from the EmpBasic table in the validation if desired.