Data Entry Form in Kinetic

I have a great (classic) custom dashboard using UD09 to store temporary information about parts in stock for open jobs. The form is pretty simple with a handful of textboxes/combo boxes used as inputs, along with a grid view to show the table contents.

The classic form uses some code to help populated the drop-down boxes, as well as to validate the data before submitting it to the database with a BPM inside my BAQ. Here is the customization code:

// **************************************************
// Custom code for MainController Open Job Inventory (Shipping Excel File)
// Created: 1/14/2021 10:45:51 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Ice.BO;
using Ice.UI;
using Ice.Lib;
using Ice.Adapters;
using Ice.Lib.Customization;
using Ice.Lib.ExtendedProps;
using Ice.Lib.Framework;
using Ice.Lib.Searches;
using Ice.UI.FormFunctions;
using System.Reflection;
using Infragistics.Shared;
using Infragistics.Win;
using Infragistics.Win.UltraWinGrid;
using System.Diagnostics;
using Ice.Core;
using Erp.Adapters;

public class Script
{
	// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables' Comments! **
	// Begin Wizard Added Module Level Variables **

	// End Wizard Added Module Level Variables **

	// Add Custom Module Level Variables Here **
	public EpiUltraCombo cmbBins;
	public EpiUltraCombo cmbRevs;
	public EpiUltraCombo cmbJobs;
	public void InitializeCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
		// Begin Wizard Added Variable Initialization

		// End Wizard Added Variable Initialization

		// Begin Wizard Added Custom Method Calls

		this.epiButtonDelRow.Click += new System.EventHandler(this.epiButtonDelRow_Click);
		this.epiButtonAddRow.Click += new System.EventHandler(this.epiButtonAddRow_Click);

		this.MyPartNum.Leave += new System.EventHandler(this.MyPartNum_Leave);
		this.epiRevs.Leave += new System.EventHandler(this.epiRevs_Leave);
		this.baqComboC1.Leave += new System.EventHandler(this.baqComboC1_Leave);
		this.epiButtonC1.Click += new System.EventHandler(this.epiButtonC1_Click);
		this.epiJobs.Leave += new System.EventHandler(this.epiJobs_Leave);
		// End Wizard Added Custom Method Calls
	}

	public void DestroyCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
		// Begin Wizard Added Object Disposal

		this.epiButtonDelRow.Click -= new System.EventHandler(this.epiButtonDelRow_Click);
		this.epiButtonAddRow.Click -= new System.EventHandler(this.epiButtonAddRow_Click);

		this.MyPartNum.Leave -= new System.EventHandler(this.MyPartNum_Leave);
		this.epiRevs.Leave -= new System.EventHandler(this.epiRevs_Leave);
		this.baqComboC1.Leave -= new System.EventHandler(this.baqComboC1_Leave);
		this.epiButtonC1.Click -= new System.EventHandler(this.epiButtonC1_Click);
		this.epiJobs.Leave -= new System.EventHandler(this.epiJobs_Leave);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void BAQRunCustomAction(EpiDataView iEdv, string iActionID)
	{
	    BAQDataView BAQView = (BAQDataView)iEdv;
	    Assembly assembly = Assembly.LoadFrom("Ice.Lib.EpiClientLib.dll");
	    Type t = assembly.GetType("Ice.Lib.Framework.BAQUpdater");
	    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
	    MethodInfo mi = t.GetMethod("BAQRunCustomAction", bf);
	    object[] param = new object[] { BAQView, iActionID};
	    mi.Invoke("Ice.Lib.Framework.BAQUpdater", param);
	}



	private void epiButtonDelRow_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		// Run custom code in BPM
		string message = "These parts must be added to the inventory through Inventory Transfer before deleting them here. Are you sure you want to delete the selected records?";
        string caption = "Are you sure?";
        MessageBoxButtons buttons = MessageBoxButtons.YesNo;
        DialogResult result;

        // Displays the MessageBox.

        result = MessageBox.Show(message, caption, buttons);

        if(result == DialogResult.Yes)
        {
		var edvV = oTrans.Factory("V_UD_OpenJobInventory_1View");
		BAQRunCustomAction(edvV, "DeleteRows");
 	   RefreshPage();
		}
	}
	private void RefreshPage()
	{
		MainController.AppControlPanel.HandleToolClick("RefreshTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["RefreshTool"], null));
		MyPartNum.Text="";
		epiRevs.Value="";
		MyQuantity.Text="";
		epiStatus.Value="";
		epiUltraComboC1.Value="";
		baqComboC1.Value="";
		epiJobs.Value="";
		MyNotes.Text="";
		MyDate.Text="";
	}

	private void MainController_Load(object sender, EventArgs args)
	{
		// Add Event Handler Code
	}





	private void epiButtonAddRow_Click(object sender, System.EventArgs args)
	{
		//Verify text values before adding record
		if (MyPartNum.Text == "")
		{
		MessageBox.Show("Part Number Missing!");
		return;
		}
		if (epiJobs.Value.ToString() == "")
		{
		MessageBox.Show("Job Lot Number Missing!");
		return;
		}
		if (epiRevs.Value.ToString() == "")
		{
		MessageBox.Show("Revision Number Missing!");
		return;
		}
		if (baqComboC1.Value.ToString() == "")
		{
		MessageBox.Show("Warehouse Missing!");
		return;
		}
		if (epiUltraComboC1.Value.ToString() == "")
		{
		MessageBox.Show("Bin Number Missing!");
		return;
		}
		if (epiStatus.Value.ToString() == "")
		{
		MessageBox.Show("Status Missing!");
		return;
		}
//		if (MyNotes.Text == "")
//		{
//		MessageBox.Show("Notes Missing!");
//		return;
//		}
		if (MyQuantity.Text == "")
		{
		MessageBox.Show("Quantity Number Missing!");
		return;
		}
		if (MyDate.Text == "")
		{
		MessageBox.Show("Date Missing!");
		return;
		}
			
		EpiDataView edvCallContextBpmData = ((EpiDataView)(this.oTrans.EpiDataViews["CallContextBpmData"]));
		System.Data.DataRow edvCallContextBpmDataRow = edvCallContextBpmData.CurrentDataRow;
		edvCallContextBpmDataRow["Character01"] = MyPartNum.Text;
		edvCallContextBpmDataRow["Character03"] = epiRevs.Value.ToString();
		edvCallContextBpmDataRow["Character07"] = epiStatus.Value.ToString();
		edvCallContextBpmDataRow["Character02"] = epiJobs.Value.ToString();
		edvCallContextBpmDataRow["Character05"] = baqComboC1.Value.ToString(); //warehouse
		edvCallContextBpmDataRow["Character04"] = epiUltraComboC1.Value.ToString(); //bin
		edvCallContextBpmDataRow["Character06"] = MyNotes.Text;
		edvCallContextBpmDataRow["Number01"] = MyQuantity.Text;		
		edvCallContextBpmDataRow["Date01"] = MyDate.Text;
		
		var edvV = oTrans.Factory("V_UD_OpenJobInventory_1View");
		BAQRunCustomAction(edvV, "AddRow");

 	   RefreshPage();
		
	}


	private void getJobs()
	{
		cmbJobs = (Ice.Lib.Framework.EpiUltraCombo)csm.GetNativeControlReference("ab3e6a13-bcc2-45bb-8f27-e93f11951026");

		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("Jobs");
		qeds.ExecutionParameter.Clear();

		qeds.ExecutionParameter.AddExecutionParameterRow("part", MyPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");
		qeds.ExecutionParameter.AddExecutionParameterRow("rev", epiRevs.Value.ToString(), "nvarchar", false, Guid.NewGuid(), "A");

		dqa.ExecuteByID("Jobs", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbJobs.DataSource = dqa.QueryResults.Tables["Results"];
			cmbJobs.DisplayMember = "JobHead_JobNum";
			cmbJobs.ValueMember = "JobHead_JobNum";
			cmbJobs.DropDownStyle = Infragistics.Win.UltraWinGrid.UltraComboStyle.DropDownList;
			oTrans.NotifyAll();
		}
		else
		{
		MessageBox.Show("No Open Jobs!");
		}
	}


	private void getBins()
	{
		cmbBins = (Ice.Lib.Framework.EpiUltraCombo)csm.GetNativeControlReference("886dc91a-429b-4b5b-b900-9e87438facfc");

		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("Bins");
		qeds.ExecutionParameter.Clear();

		qeds.ExecutionParameter.AddExecutionParameterRow("Ware", baqComboC1.Value.ToString(), "nvarchar", false, Guid.NewGuid(), "A");

		dqa.ExecuteByID("Bins", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbBins.DataSource = dqa.QueryResults.Tables["Results"];
			cmbBins.DisplayMember = "WhseBin_BinNum";
			cmbBins.ValueMember = "WhseBin_BinNum";
			cmbBins.DropDownStyle = Infragistics.Win.UltraWinGrid.UltraComboStyle.DropDownList;
			oTrans.NotifyAll();
		}
		else
		{
		MessageBox.Show("No Bins in Warehouse!");
		}
	}

private void getRevs()
	{
		cmbRevs = (Ice.Lib.Framework.EpiUltraCombo)csm.GetNativeControlReference("a03dd350-74a0-4382-b1cb-251c5e41ed9a");

		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("getPartRev");
		qeds.ExecutionParameter.Clear();

		qeds.ExecutionParameter.AddExecutionParameterRow("part", MyPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");

		dqa.ExecuteByID("getPartRev", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbRevs.DataSource = dqa.QueryResults.Tables["Results"];
			cmbRevs.DisplayMember = "PartRev_RevShortDesc";
			cmbRevs.ValueMember = "PartRev_RevShortDesc";
			cmbRevs.DropDownStyle = Infragistics.Win.UltraWinGrid.UltraComboStyle.DropDownList;
			oTrans.NotifyAll();
		}
		else
		{
		cmbRevs.DataSource = "";
		cmbRevs.DisplayMember = "";
		cmbRevs.ValueMember = "";
		oTrans.NotifyAll();
		MessageBox.Show("Part Not Found in Any Open Jobs!");
		}
	}

	private void MyPartNum_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if (MyPartNum.Text!="")  
		{
		getRevs();
		cmbRevs.ForceRefreshList();
		}
	}


	private void epiRevs_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if (epiRevs.Value.ToString()!="")  
		{
		getJobs();
		cmbJobs.ForceRefreshList();
		MessageBox.Show("If the revision is not listed below, please enter the correct revision in the Notes section.");
		//MessageBox.Show("Getting Jobs for part: " + MyPartNum.Text + " rev: " + epiRevs.Value.ToString());
		}
	}

	private void baqComboC1_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if (baqComboC1.Value.ToString()!="")  
		{
		//MessageBox.Show("Trying to Bet Bins...");
		getBins();
		epiUltraComboC1.ForceRefreshList();
		}
	}

	private void epiButtonC1_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
	RefreshPage();
	}

	private void epiJobs_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if (epiJobs.Value.ToString()!="")  
		{
		MessageBox.Show("The system does not track split lots. If this job has been split, please document the split lot information in the Notes section.");
		}
	}
}

I have deployed this dashboard to kinetic and I am looking at it in Application Studio. I want to add all the same data entry fields I used in classic. I am not sure about how to add the customization code that allows the drop-down boxes to show relevant data. I also use that custom code to validate the field contents before populating the next field. For example, the function getJobs() looks at the part number and tries to find jobs for that part. If jobs are found, then the combo is populated with the list of jobs to choose from. If jobs are not found, an error message notifies the user to check the data. I am also not sure how to use my “Add” button to trigger my uBAQs BPM.
I also pass values to BPM call context. How do I do that from Application Studio?
I am guessing none of this is possible in Kinetic, but I may be a bit cynical.

I have added buttons to my form from Panel Grid Card > Advanced > Action Data. There I found the actions from my uBAQ.

Now I am implementing the data validation on each field. For example: on the Part number. I want the user to enter a part number, then have the revision combo box populate with the possible revs for that part. There is a BAQ to feed that combo, but I have to pass in some parameters. I am a bit lost on that, so I thought I woudl start east, and see if I can even get the condition to detect if my part number is blank. My condition statement keeps passing true, regardless of if my part number is blank or not. I put a couple of dialogs on the true and false sides of the condition. I have tried these syntax combinations in the condition’s parameter expression:

"{myPartNum<>Null}"
"{myPartNum<>''}"
"{myPartNum<>""}"

None of these ever returned false to show that there is a blank value. What syntax should I use to detect if my form field has a value? Then, what component do I pull in to the action to change the data source for the revision combo box, similar to what I do here (from classic):

private void getRevs()
	{
		cmbRevs = (Ice.Lib.Framework.EpiUltraCombo)csm.GetNativeControlReference("a03dd350-74a0-4382-b1cb-251c5e41ed9a");

		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("getPartRev");
		qeds.ExecutionParameter.Clear();

		qeds.ExecutionParameter.AddExecutionParameterRow("part", MyPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");

		dqa.ExecuteByID("getPartRev", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbRevs.DataSource = dqa.QueryResults.Tables["Results"];
			cmbRevs.DisplayMember = "PartRev_RevShortDesc";
			cmbRevs.ValueMember = "PartRev_RevShortDesc";
			cmbRevs.DropDownStyle = Infragistics.Win.UltraWinGrid.UltraComboStyle.DropDownList;
			oTrans.NotifyAll();
		}
		else
		{
		cmbRevs.DataSource = "";
		cmbRevs.DisplayMember = "";
		cmbRevs.ValueMember = "";
		oTrans.NotifyAll();
		MessageBox.Show("Part Not Found in Any Open Jobs!");
		}
	}

I’m actually pretty sure most of this is possible; it’s a tall order, though.

Try {myPartNum} === undefined

1 Like

I tried:

{myPartNum} === undefined
"{myPartNum} === undefined"

Both gave the same results for null and not null values in the myPartNum text field.
KineticCondition

You’re doing {MyView.MyPartNum} right? And not just {MyPartNum}?

1 Like

Ugggh damn views… No. I haven’t setup any views.
What’s the best way to setup this temporary dataview? Does the dataview need to point to my uBAQ, or to the UD09 table? I think i just need a blank dataview to hold on to the values until I can pass them into the uBAQ through callcontext (still gotta get there).

1 Like

If you just need a temp dataview, you can use TransView; it’s a runtime view. Whenever you go to assign your partnum variable, assign it to TransView.PartNum (or whatever) and it will create that column on the fly to be used throughout the session.

If it’s data from a BAQ and you’re already making a call to the BAQ, you might as well set the dataview up for it and just return data to that BAQ view.

3 Likes

Do you mean I should set my epiBinding for the part num text field to TransView.myPartNum?

Partially yes.

But you also need to get your myPartNum data from somewhere. Where ever/whenever you’re actually getting the value of myPartNum, create an event with a row-update to set that myPartNum value to TransView.PartNum.

The user supplies the part number. I want the user to type in a part number. If they forget to type in a number I want to catch that null value and warn the user they need to provide a value there. If it is not null I want to move to the next step of populating the revision combo box.

Okay, then yes. Bind the textbox to TransView.PartNum. Out of curiosity–what do you currently have it bound to when you were trying the compare earlier?

1 Like

I tried setting up a temp data view. I called it TempUD09, and made its data source my uBAQ. Then I bound the textbox to TempUD09.Key1 (which is my part number field).

This seems to work. Kind of. When I first open the form the true/false dialgos show properly. After I have entered a value in the part number (and get the not null dialog) then I remove the value, I no longer get the false dialog box even when I leave the part number field while it is empty.

Change the trigger from OnBlur to DataTable > Column Changing/Changed.

The event fires on the first couple of attempts, then the event stops firing and the value disappears. This is so frustrating!

KineticAction

Huh. Enable logging and look at DevTools. Any errors firing when it stops?

I originally changed === to !== to invert the condition. I see in console:

function body  !== undefined thrown exception SyntaxError: Unexpected token '!=='

So I changed it back to ===, and still get this error:

function body  === undefined thrown exception SyntaxError: Unexpected token '==='

Well, that’s… something, lol.

Try adding some single quotes; I’m not confident that will change the behavior, but it’s worth a shot.

'{TransView.myPartNum}' !== 'undefined'

No more error! But it is still not quite giving me the right results. Is it this difficult for everyone?
KineticDebugging

When previewing use CTRL+ALT+8 to turn on debugging so you can see what comparison is happening when it’s checking the blank record. You may have to do something like:

'{TransView.myPartNum}' !== 'undefined' && '{TransView.myPartNum}' !== ''
1 Like