How to Add Fields in DataView

Hello there,
We are trying to add the following fields: OrderHed.ShortChar02 and OrderDtl.DocExtPriceDtl in Customer Tracker > Orders > Open list view but it’s not available in the dataview OrderOpen. Is there a way to add those fields?


Thank you and stay safe,
Daisy

Hey there Daisy,

Hope this finds you well. I’m not on Kinetics so take everything I say with a grain of salt.

Since these fields aren’t available on the OrderOpen Dataset, you’ll need to add them to the grid. Here’s an example which helped me with a similar problem a while back:

You can try using this thread to add the needed fields to the datagrid when the form loads.

That’s only half the battle. We need to actually populate these fields with data, and since they aren’t on the Dataset, you’ll need to add them.

Add an EpiUltraGrid InitializeRow event to the OrdersOpen grid. Since it’s not a custom control you can’t do this through the wizard, but you can use the wizard as a guide and grab the native control using the csm.GetNativeControlReference(“EpiGuidHere”) method.

Then in the InitializeRow method, you can call GetList or another method to pull in the sales order information for each row and populate the added fields ShortChar02 and DocExtPriceDtl.

WARNING
This will slow down customer tracker when you click the “Retrieve” button. Depending on how many open orders exist for the customer, the performance hit could be significant.

Let me know if this makes sense or if I need to clarify anything.

Hi Wesley,

Thank you for your response. Our system was upgraded to Kinetic version as we using cloud-based platform, but we are still using the original UI version.

I’ve tried your codes in ResourceSchedForm to check if it will work on our end, unfortunately I am getting this error:

image

I’m not sure if it’s because we’re on cloud-based platform and they have it restricted. Please advise. Thank you.

Hey Daisy,

Sure thing. So for starters we need to add the two fields to the grid. Since you’re using the classic forms I believe you should be golden.

The first step is to add the custom columns to the grid.

Code for adding columns to the Grid

Here all I’m doing is adding the column headers to the grid. At this stage, this is basically meaningless as the columns won’t be populated. However, you should see 2 new columns in Customer Tracker > Order. You shouldn’t need to add any using statements at this stage - just grab the EpiUltraGrid and add the two columns. We’ll fill these in later.

// **************************************************
// Custom code for CustomerTrackerForm
// Created: 9/9/2021 11:59:38 AM
// **************************************************

extern alias Erp_Contracts_BO_Customer;
extern alias Erp_Contracts_BO_CreditManager;
extern alias Erp_Contracts_BO_Company;
extern alias Erp_Contracts_BO_ARInvoice;
extern alias Erp_Contracts_BO_Quote;
extern alias Erp_Contracts_BO_CustCnt;
extern alias Erp_Contracts_BO_ARLOC;
extern alias Erp_Contracts_BO_CashDtlSearch;
extern alias Erp_Contracts_BO_ServiceContract;
extern alias Erp_Contracts_BO_CustShip;
extern alias Erp_Contracts_BO_CashRecSearch;
extern alias Erp_Contracts_BO_ARPromissoryNotes;
extern alias Erp_Contracts_BO_SalesOrdHedDtl;
extern alias Erp_Contracts_BO_OrderDtlSearch;
extern alias Erp_Contracts_BO_ShipDtlSearch;
extern alias Erp_Contracts_BO_ARAgingTracker;

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.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;

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 **
	private EpiUltraGrid _custOrdGrid;

	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

		// End Wizard Added Custom Method Calls
		_custOrdGrid = (EpiUltraGrid)csm.GetNativeControlReference("741857dd-a984-45d3-ad73-94903e9abcd2"); 
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("UserChar1","User Char 1");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("DocExtPriceDtl","Ext Price Detail");
	}

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

		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
		
	}
}

Now that we have added two columns, we can fill them with data as the grid populates.
This more directly deals with the error message you sent over.

Populating the Grid Part 1

First, we need to add an assembly reference to the “Ice.Contracts.Lib.BOReader” dll
image
image


Now that we’ve added our assembly reference, let’s define the BOReader object we’ll use to populate the added columns

Declare a new private property:

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 **
	private EpiUltraGrid _custOrdGrid;
	private BOReaderImpl _boRdr;

Then add _boRdr = WCFServiceSupport line to the InitializeCustomCode method:

	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

		// End Wizard Added Custom Method Calls
		_custOrdGrid = (EpiUltraGrid)csm.GetNativeControlReference("741857dd-a984-45d3-ad73-94903e9abcd2");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("UserChar1","User Char 1");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("DocExtPriceDtl","Ext Price Detail");

		_boRdr = WCFServiceSupport.CreateImpl<BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);
	}

Now it’s time to add our event which we will use to trigger a BO Method to populate the data on the grid. Add an InitializeRow event to our EpiUltraGrid. At this point, the custom script should look similar to this

// **************************************************
// Custom code for CustomerTrackerForm
// Created: 9/9/2021 11:59:38 AM
// **************************************************

extern alias Erp_Contracts_BO_Customer;
extern alias Erp_Contracts_BO_CreditManager;
extern alias Erp_Contracts_BO_Company;
extern alias Erp_Contracts_BO_ARInvoice;
extern alias Erp_Contracts_BO_Quote;
extern alias Erp_Contracts_BO_CustCnt;
extern alias Erp_Contracts_BO_ARLOC;
extern alias Erp_Contracts_BO_CashDtlSearch;
extern alias Erp_Contracts_BO_ServiceContract;
extern alias Erp_Contracts_BO_CustShip;
extern alias Erp_Contracts_BO_CashRecSearch;
extern alias Erp_Contracts_BO_ARPromissoryNotes;
extern alias Erp_Contracts_BO_SalesOrdHedDtl;
extern alias Erp_Contracts_BO_OrderDtlSearch;
extern alias Erp_Contracts_BO_ShipDtlSearch;
extern alias Erp_Contracts_BO_ARAgingTracker;
extern alias Ice_Contracts_Lib_BOReader;

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.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.Proxy.Lib;
using Ice.UI.FormFunctions;

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 **
	private EpiUltraGrid _custOrdGrid;
	private BOReaderImpl _boRdr;

	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

		// End Wizard Added Custom Method Calls
		_custOrdGrid = (EpiUltraGrid)csm.GetNativeControlReference("741857dd-a984-45d3-ad73-94903e9abcd2");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("UserChar1","User Char 1");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("DocExtPriceDtl","Ext Price Detail");

		_boRdr = WCFServiceSupport.CreateImpl<BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);

		_custOrdGrid.InitializeRow += new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(_custOrdGrid_InitializeRow);
	}

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

		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
		_custOrdGrid.InitializeRow -= new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(_custOrdGrid_InitializeRow);
		
	}

	private void _custOrdGrid_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs args)
	{
		// this is where we will actually populate the datagrid
	}
}

Now to tie it all together and populate the 2 columns we’ve added to the grid.

Populating the Grid Part 2

We’ll be using the “OrderNum” field to retrieve the UserChar1 and DocExtPriceDtl columns for each order.

private void _custOrdGrid_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs args)
{
    // this is where we will actually populate the datagrid
    if(!string.IsNullOrEmpty(args.Row.Cells["OrderNum"].Value.ToString()))
    {
        DataSet orderHedDS = _boRdr.GetRows("Erp:BO:SalesOrder","OrderNum = \'" + args.Row.Cells["OrderNum"].Value.ToString() + "\'", "UserChar1,DocExtPriceDtl");
        args.Row.Cells["UserChar1"].Value = orderHedDS.Tables[0].Rows[0]["UserChar1"].ToString();
        args.Row.Cells["DocExtPriceDtl"].Value = orderHedDS.Tables[3].Rows[0]["DocExtPriceDtl"].ToString();
    }
}

The final custom script should resemble the below code block:

// **************************************************
// Custom code for CustomerTrackerForm
// Created: 9/9/2021 11:59:38 AM
// **************************************************

extern alias Erp_Contracts_BO_Customer;
extern alias Erp_Contracts_BO_CreditManager;
extern alias Erp_Contracts_BO_Company;
extern alias Erp_Contracts_BO_ARInvoice;
extern alias Erp_Contracts_BO_Quote;
extern alias Erp_Contracts_BO_CustCnt;
extern alias Erp_Contracts_BO_ARLOC;
extern alias Erp_Contracts_BO_CashDtlSearch;
extern alias Erp_Contracts_BO_ServiceContract;
extern alias Erp_Contracts_BO_CustShip;
extern alias Erp_Contracts_BO_CashRecSearch;
extern alias Erp_Contracts_BO_ARPromissoryNotes;
extern alias Erp_Contracts_BO_SalesOrdHedDtl;
extern alias Erp_Contracts_BO_OrderDtlSearch;
extern alias Erp_Contracts_BO_ShipDtlSearch;
extern alias Erp_Contracts_BO_ARAgingTracker;
extern alias Ice_Contracts_Lib_BOReader;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.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.Proxy.Lib;
using Ice.UI.FormFunctions;

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 **
	private EpiUltraGrid _custOrdGrid;
	private BOReaderImpl _boRdr;

	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

		// End Wizard Added Custom Method Calls
		_custOrdGrid = (EpiUltraGrid)csm.GetNativeControlReference("741857dd-a984-45d3-ad73-94903e9abcd2");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("UserChar1","User Char 1");
		_custOrdGrid.DisplayLayout.Bands[0].Columns.Add("DocExtPriceDtl","Ext Price Detail");

		_boRdr = WCFServiceSupport.CreateImpl<BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);

		_custOrdGrid.InitializeRow += new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(_custOrdGrid_InitializeRow);
	}

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


		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
		_custOrdGrid.InitializeRow -= new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(_custOrdGrid_InitializeRow);
		_boRdr.Dispose();
	}

	private void _custOrdGrid_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs args)
	{
		// this is where we will actually populate the datagrid
		if(!string.IsNullOrEmpty(args.Row.Cells["OrderNum"].Value.ToString()))
		{
			DataSet orderHedDS = _boRdr.GetRows("Erp:BO:SalesOrder","OrderNum = \'" + args.Row.Cells["OrderNum"].Value.ToString() + "\'", "UserChar1,DocExtPriceDtl");
			args.Row.Cells["UserChar1"].Value = orderHedDS.Tables[0].Rows[0]["UserChar1"].ToString();
			args.Row.Cells["DocExtPriceDtl"].Value = orderHedDS.Tables[3].Rows[0]["DocExtPriceDtl"].ToString();
		}
	}
}

DISCLAIMER
I would highly recommend coming up with a better solution than this in the long run. As it stands, the GetRows method will run for every row in the grid. Ideally, you should populate whereClause in the InitializeRow event and then run _boRdr.GetRows once and loop through the grid to populate each column with the returned dataset.

Hopefully this will help in getting you started. Let me know if you have questions. I will respond as I am able :slight_smile: