Case Entry - New Case menu

Hi, working with 10.1.400.25 and trying to play in customization C# code of the Case Entry screen.

1-Im trying to find what code/function is called when user click “New Case” menu. Asking since I would like to mimic the click with code (at form launch) and would like to re-use code already in place instead of doing it myself from scratch. Does anyone know?

2-Ive tried to add my code in the AfterToolClick() method (case “EpiAddNewnewCase”) but seems there is no event fired when we click the menu (as opposed to Save/Refresh/Clear buttons). Any idea why?

thanks in advance,

Martin

oTrans.GetNewHDCase();

Hello Martin,

Have you run a Trace? That will tell you what is going on. Find it under Settings | Tracing Options…

[cid:image002.jpg@01D2A2F6.32D35190]

Mark W.

1 Like

Thanks Jose,

oTrans.GetNewHDCase(); seems to be what I was looking for!

Now hitting a second challenge after doing oTrans.GetNewHDCase():

after setting the TerritoryID, CustNum and ShipToCustNum, the dropdown (for Territory) and the two texboxes (for CustID at SoldTo and ShipTo) wont refresh to display the value. The textboxes only refresh and display the CustID after Save. The Territory dropdown displays “None Selected” until we save, close the screen and re-open it (or if we pick a ShipToNum, it will refresh it). I tried to force the values in those controls without any luck. Any idea?

thanks,

Martin,
You need to run a trace and invoke all the methods that Epicor invokes while this is happening

Thanks Jose,

I checked the trace but I dont think it helps. The reason is im trying to refresh the displaying before saving anything (my case is still not created in DB but all data is pre-filled for the user in the form). All the data retrieving that the trace shows me seem to assume that the data is already in the DB. Looks like I would need a client-side type of screen refresh. Not sure if that exist.

thanks,

How are you assigning the values to the fields?
Epicor does a lot of business object calls that populate Names, and Descriptions etc… a lot of the dataset calls don’t need the data to be on the databse.

thanks again for the quick response:

like this, in the Form_Load():

HDCase_DataView[0][“CustNum”] = Convert.ToInt32(strCustNum);
HDCase_DataView[0][“ShipToCustNum”] = Convert.ToInt32(strCustNum);
HDCase_DataView[0][“CustomerName”] = strName;
HDCase_DataView[0][“TerritoryID”] = strTerritoryID;

In Form load you can’t populate values in the DataView since the dataView doesn’t yet exist.
You should not be doing any data manipulation in the Form_Load since Epicor loads a lot of their dataset after the fact.
What is the end goal you are trying to accomplish?

Im trying to create a “Create Case” shortcut from Customer Tracker that calls the Case Entry screen and pre-fill the most fields as possible (defaults) for the user. Im not opening any existing case.

Everything seems to be working perfectly so far except that field refreshing which may confuse the end users, especially the Territory display.

Can you post all the code you are running on Form_Load?

private void HelpDeskForm_Load(object sender, EventArgs args)
{
LoadCustomer();
}

private void LoadCustomer()
	{
		string strToParse = "";
		string strCustNum = "";
		string strShipToNum = "";

		if (HelpDeskForm.LaunchFormOptions != null) 
		{ 
			EpiDataView edv = (EpiDataView)oTrans.EpiDataViews["ReportParam"]; 
			
			strToParse = HelpDeskForm.LaunchFormOptions.ContextValue.ToString();

			if (strToParse.IndexOf('|') > -1)
			{
				 strCustNum = strToParse.Substring(0, strToParse.IndexOf('|'));
				 strShipToNum = strToParse.Substring(strToParse.IndexOf('|')+1, strToParse.Length-(strToParse.IndexOf('|')+1));
			}

			if (HDCase_DataView != null)
			{
				if (strCustNum != "")
				{

					oTrans.GetNewHDCase();

					System.Threading.Thread.Sleep(1);//leave time to BPM to run (set defaults)

					if (HDCase_DataView.Count > 0)
					{

						HDCase_DataView[0]["CustNum"] = Convert.ToInt32(strCustNum);
						HDCase_DataView[0]["ShipToCustNum"] = Convert.ToInt32(strCustNum);
						

						//Get customer info
						 Erp.Proxy.BO.CustomerImpl c = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.CustomerImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Erp.Contracts.CustomerSvcContract>.UriPath);
        				 Erp.BO.CustomerDataSet ds = new Erp.BO.CustomerDataSet();

        				 ds = c.GetByID(Convert.ToInt32(strCustNum));
						
						if (ds.Tables["Customer"].Rows.Count > 0)
						{
							HDCase_DataView[0]["CustomerName"] = ds.Tables["Customer"].Rows[0].Table.Rows[0]["Name"].ToString();
							HDCase_DataView[0]["TerritoryID"] = ds.Tables["Customer"].Rows[0].Table.Rows[0]["TerritoryID"].ToString();
							
							
							if (strShipToNum == "")
							{
								HDCase_DataView[0]["ShipToNum"] = ds.Tables["Customer"].Rows[0].Table.Rows[0]["ShipToNum"].ToString();
							}
							else
							{
								
								HDCase_DataView[0]["ShipToNum"] = strShipToNum;
								
							}
						}

					}
				}	
			}
		}
	}

Ok I see the problem, you need to invoke the appropriate BO’s that Epicor invokes when any of this data changes in the case.
For example When you Click New Case
And you Select a Person / Contact

Then Epicor executes the business object

 <businessObject>Erp.Proxy.BO.HelpDeskImpl</businessObject>
  <methodName>OnChangeReqPerConID</methodName>
  <returnType>System.Void</returnType>
  <localTime>3/22/2017 15:43:39:2152663 PM</localTime>
  <executionTime>13</executionTime>

Which returns back the Name, Link and Context ETC… the same thing happens with MOST fields. In your code you are settings CustNum but you need to mimick what the UI does, when you select a Customer it calls some method GETCUSTOMERINFO() which “refreshes” like you say and populated the right fields in the dataset.

You need to do a trace as you make the changes and mimick EVERY (almost every) business logic call that Epicor makes.

Just to share something that someone shared with me that can reduce a bit of the complexity of parsing the LaunchFormOptions:

#From:

           strToParse = HelpDeskForm.LaunchFormOptions.ContextValue.ToString();



           if (strToParse.IndexOf('|') > -1)

           {

                    strCustNum = strToParse.Substring(0, strToParse.IndexOf('|'));

                    strShipToNum = strToParse.Substring(strToParse.IndexOf('|')+1, strToParse.Length-(strToParse.IndexOf('|')+1));

           }

#To:
char[] separatingChars = { “|” };

strToParse = HelpDeskForm.LaunchFormOptions.ContextValue.ToString();
string[] parms = strToParse.Split(separatingChars);
if (parms.Length >= 2)
{
strCustNum = parms[0];
strShipToNum = parms[1];
}

1 Like

Jose,

can you please clarify how to call the method? I tried this but getting error at bottom. oTrans.OnChangeCustID doesnt seem to be valid.

Erp.Proxy.BO.HelpDeskImpl h = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.HelpDeskImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Erp.Contracts.HelpDeskSvcContract>.UriPath);

Erp.BO.HelpDeskDataSet ds2 = new Erp.BO.HelpDeskDataSet();

						h.OnChangeCustID(ds2,ds.Tables["Customer"].Rows[0].Table.Rows[0]["CustID"].ToString(),true);

Application Error

Exception caught in: mscorlib

Error Detail

Message: Exception has been thrown by the target of an invocation.
Inner Exception Message: No modified record found.
Program: CommonLanguageRuntimeLibrary
Method: InvokeMethod

Client Stack Trace

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeScriptMethod(MethodInfo scriptMethod, Object[] parameters)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeCustomFormLoadIfExists(String methodName, Object sender, EventArgs e)
at Ice.Lib.Customization.CustomScriptManager.<>c__DisplayClassa.b__8()
at Ice.Lib.Customization.CustomScriptManager.TryActionShowExceptionBoxOrLogVerificationErrorIfException(Action action, String exceptionBoxTitle)

Inner Exception

No modified record found.

Inner Stack Trace

at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
at Erp.Proxy.BO.HelpDeskImpl.OnChangeCustID(HelpDeskDataSet ds, String proposedCustID, Boolean getDefaults)
at Script.LoadCustomer()
at Script.HelpDeskForm_Load(Object sender, EventArgs args)

Use the adapters, not the WCF Services it will make your life much easier. Also since you are updating the current screen you want to call the current Adapter.
So you are assigning the custom which it probably doesn’t normally pick up natively, rather when you pick a customer the CustID gets assigned and then a Method gets called which brings the correct CustNum / etc into the form.

You want to set the custid
There are triggers in the dataset which will fire if you set the right fields. For example setting the field ShipToCustNumCustID will trigger it to look up the customer / ship to information and populate it.

Setting the CustNumCustID field will do the samefor customer it will invoke the adapter.OnChangeCustID

There are plenty of examples in the forum of how to use the adapters which you’ll have to use to trigger the events in the current form.

In E9 we use BPMs to load the defaults, in particular the workflow based on the logged in user, which ties back to the CaseOwner…which is really the Workforce, which really ties back to the salesRep Table.

The other thing that we found, once again in E9. That the OnChangeReqPerConID method will bring back not only active contacts but inactive ones as well,not to mention all contexts(eg. Customer,Employee and workforce). A good example if a contact has moved from one customer to another.

Took a quite a while to cases working the way we wanted, a few years down the track now and there are a few things if I had understood properly I would do differently now.

Not sure if it helps any, but thought it was worth mentioning

thanks everyone.

Seems like all I had to do was to set CustNumCustID and not bother with all others. This one will set the rest.

thanks,

1 Like