Need a better event than EpiViewNotification Initialize

So on the order entry screen I want to add the drawing number associated with the quote that the order line was made from to the order line grid. So I made a BAQ to look up the drawings for the quote and tie them to the order lines. Right now I add a column and run the BAQ on EpiTransaction.NotifyType.Initialize but it turns out that is triggered waaayyyy to many times for what I want to do. Is there a better event for this?

You could add a FKV maybe and pull in the entire QuoteHed and it will feel native.
You could add a RowRule and then run your BAQ.
You could copy the field to a CustomField_c before Quote is created.

Sometimes I just use the AfterAdapter GetByID:

	private void oTrans_partAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
		// ** Argument Properties and Uses **
		// ** args.MethodName **
		// ** Add Event Handler Code **

		switch (args.MethodName)
			case "GetByID":


	private void SetInternalPartCrossRef(string sPartNum)
		EpiDataView edvPart = this.oTrans.Factory("Part");
		string sValue = string.Empty;

		if (!string.IsNullOrEmpty(sPartNum))
			bool recSelected;
			string whereClause = "PartNum = '" + sPartNum + "'";
			DataSet ds = SearchFunctions.listLookup(this.oTrans, "InternalPartCrossRefAdapter", out recSelected, false, whereClause);

			if (recSelected) {
				sValue = ds.Tables[0].Rows[0]["XRefPartNum"].ToString();

		if (edvPart.dataView.Count > 0) {
			edvPart.dataView[0]["InternalPartNum"] = sValue;

It looks like Epicor already has views for Quote created? Is there some way to re-use those to show the quote number for each line and skip the BAQ all together?

Almost all my OrderHed EpiViewNotifications look like this so i only do stuff when the order number changes. Haso’s AfterAdapter has the advantage that it will run on a refresh.

	int currentOrder = 0;
	private void edvOrderHed_EpiViewNotification(EpiDataView view, EpiNotifyArgs args)
		// ** Argument Properties and Uses **
		// view.dataView[args.Row]["FieldName"]
		// args.Row, args.Column, args.Sender, args.NotifyType
		// NotifyType.Initialize, NotifyType.AddRow, NotifyType.DeleteRow, NotifyType.InitLastView, NotifyType.InitAndResetTreeNodes
		if ((args.NotifyType == EpiTransaction.NotifyType.Initialize))
			if ((args.Row > -1))
				if (currentOrder != (int)view.dataView[args.Row]["OrderNum"])
					currentOrder = (int)view.dataView[args.Row]["OrderNum"];
				currentOrder = 0;



Easy Way:
The way I started just doing it, if I need to show a column on 1 table I make MyNewColumn_c just like Epicor makes the DspField_c, it becomes much easier and I could even do the lookup in the BPM then and fill it.

Background on UltraGrid:
The grid will show whatever data is in the data source you give it. But the grid cannot have more than one root-level table, nor can it have more than one data source. So you could create a data source with a dummy root-level table with one row and then two child bands (which are siblings to each other) and display your two tables that way, but then you have a parent/child. There isn’t a effective way to mix tables into 1 single row.

Another Way:
Look at InitializeRow and look it up that way. I would query your BAQ once and store it in memory as a Global and then just look-up against the variable. Don’t do many BAQ Lookups.

Third Way (Prob break some functionality):
Create a New DataView on UI

Fourth Way (I Love this way, but I broke Epicor using this method):
I add a Column to the DataTable in the UI and it behaves natively then I can use RowRules to populate it etc… but apparently Epicors caching Engine will scream if you use another UI Screen with the same DataTable and it lacks that “temporary column”. Some screens have a NoBoundField table, same concept.

Same idea that you have now, just cache the results of your BAQ, dont hit the BAQ over and over again… it’ll be faster if you just pull 1000 rows in memory than running it a 1000x, then you can Search through your BAQ Results variable.

1 Like

I like this because you say its easy and it sounds like it works via BPM and not a customization so it should handle upgrades better. Unfortunately I have no idea what you are referring to. Can you elaborate on this a little? (Probably going to find out I can’t do this on epicors cloud offering… )

Just make a new column on OrderDtl and call it DspQuoteDrawNum_c, or perhaps they give you ShortChar01, ShortChar02… in the cloud.

Then add a BPM on GetByID or GetRows or GetList for the Quote and populate the DspQuoteDrawNum_c

Oh, I see now. You just mean use a UD field to store the drawing number and keep it in sync. Hmm

The easy part is adding a field to the UI and binding it to any table you want. The harder part is when you have a 100 rows, keeping them all in sync since the UltraGrid only likes to show 1 table per row.

So having a DspQuoteDrawNum_c column, makes both easy.

Maybe not even keep it in Sync… just look it up in GetRows, GetList, GetByID - or keep it in sync.

ANOTHER PLUS is… now that column becomes avail on BAQs, Reports etc… without you having to do Joins etc… I would hate for you to customize RDDs for 1 column on 5-10 reports. So having it be a UD Column, saves you time later as well.

1 Like

So you would have it go back and check the quote each time GetRows, GetList, GetByID is called for the OrderDtl?

Since the drawing could possibly change on the quote.

Yes that is one way, or you make another BPM on QuoteDtl to sync it to Orders that are open (when Order DrawNum Field Changes).

See I like what Epicor does with Order -> ShipDtl -> Invoice, they don’t reference the fields on those tables… They copy them, so if someone does change a setting then it doesn’t affect what’s in play already.

If you create ShipDtl from an Order and then go change the ShipTo on the Order “too bad, its a process issue”.

If you convert a Quote to a Order, why bother touching the quote again? Isn’t it considered done? The drawings shouldn’t change in my opinion. :slight_smile: