after gridPriceValue has been set by the users after they click a button (has word “Uno” in it in screen shot) where they make price list and historical decisions on a new custom sheet
That part is fine and working for me.
However, now for each material in the quote I was hoping the user could click one new button (has word “Muchos” in it in screen shot) to loop through all the Mtl: nodes in the Quote
and automatically click the “Uno” button on each. This would be a big time saver for them since they would only have to make decisions once
for that material that occurs repeatedly through the quote e.g. multiple lines, sub assemblies, etc. since I hold the previous part and price in a datatable so I can use it again.
I thought I might be able to loop thought the nodes with something like the following code, but fieldInfo is always null and raising an error.
Does anyone see the problem with this approach or have another to suggest?
Here's the details
using System.Reflection;
//Is there another table I should be using below? I've tried edvJobMtl, edvJobHead & edvQuoteHed
private void edvQuoteDtl_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))
{
Ice.Lib.Framework.JobLib.MethodTree methodTree = default(Ice.Lib.Framework.JobLib.MethodTree);
FieldInfo fieldInfo = default(FieldInfo);
Ice.Lib.Framework.JobLib.MethodTreePanel treeviewPanel = default(Ice.Lib.Framework.JobLib.MethodTreePanel);
fieldInfo = typeof(Erp.UI.App.QuoteEntry.QuoteForm).GetField("mfgDetailsJobTreePanel1", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
treeviewPanel = (Ice.Lib.Framework.JobLib.MethodTreePanel)fieldInfo.GetValue(QuoteForm);
methodTree = treeviewPanel.MethodTree;
foreach (UltraTreeNode rootNode in methodTree.Nodes)
IterateNodes(rootNode);
}
}
}
private void IterateNodes(UltraTreeNode node)
{
foreach (UltraTreeNode childNode in node.Nodes)
{
if (childNode.ToString().StartsWith("Mtl: "))
{
MessageBox.Show("Test - On a Mtl Node");
//childNode.ExpandAll(); //click my button that allows the user to make custom decisions
}
IterateNodes(childNode);
}
}
Additionally, has anyone had any success implementing the AfterSelect event for the Tree?
e.g.
private void ultraTree1_AfterSelect(object sender, SelectEventArgs e)
{
UltraTreeNode node = e.NewSelections[0];
//Determine by checking the key of the selected node
Console.WriteLine(node.Key);
//Determine by checking the Text property
Console.WriteLine(node.Text);
//Determine the Level of the node; Root nodes are level 0. //Children of the root are Level 1, etc.
Console.WriteLine(node.Level);
}
So I did come up with a prototype that will loop though materials for each group of materials that a user clicks in (whether it be general materials or in a sub assembly) and make the updates based on user decisions. However I really need a one click solution that for each material, will apply the update for all instances of that material in the quote. So what is the proper Epicor approach for handling a problem like this? e.g. get a list of all material in a quote, have some UI for each material and then update the set of data for each material.
BTW, Here is a code snippet from my prototype.
int assemblySeq;
EpiDataView edvJobMtl = (EpiDataView)(this.oTrans.EpiDataViews["JobMtl"]);
assemblySeq = (int)edvJobMtl.CurrentDataRow["AssemblySeq"];
string filter = String.Format("APSAddResType = 'M' and AssemblySeq = {0}", assemblySeq);
foreach (DataRow partRow in edvJobMtl.dataView.Table.Select(filter))
...
//Then I just break when UI needs to happen, then restart it and make the appropiate tests to proceess as needed
There is a .dataView which has filters typically associated to the Parent QuoteAsm. If you want to loop through all the JobMtl’s in that Asm then you can do something like.
EpiDataView edvJM = this.oTrans.Factory("JobMtl"); // I have JobMtl, perhaps its QuoteMtl in Quote.
foreach (DataRowView drJM in edvJM.dataView)
{
// Variables
decimal vQP = Convert.ToDecimal(drJM["QtyPer"]);
string vPC = drJM["Class"].ToString();
// Calculate Per Order & Quantity Per Year
drJM["MtlCalcQtyOrder"] = Math.Round(vQQ * vQP, 2);
drJM["MtlCalcQtyYear"] = Math.Round(vSEQ * vQP, 2);
}
// Probably followed by a
this.oTrans.Update(); // you can try without it first so it doesnt commit data until user actually saves
If you ever want to loop through all JobMtl’s, sometimes depending on the Table Epicor will load all the data in and show it in the DataTable.
For DataTable Foreach its
EpiDataView edvJobMtl = this.oTrans.Factory("JobMtl");
foreach(DataRow dr in edvJobMtl.dataView.Table.Rows)
{
dr["OverrideRates"] = true;
dr["ProdLabRate"] = prevWageRate;
}
When to Trigger?
So when do you want to call the above first loop?
You could set a AfterFieldChange on JobMtl and then look for when someone changes the Price Column.
You could also listen for the QuoteDtl Engineered Checkbox and do it then, for all?
Perhaps a Better Option?
Use a BPM when JobMtl Column changes and then update all the other Materials via a BPM?
So I’ve been able to loop through all the lines knowing this:
edvQuoteDtl.dataView.Table.Rows.Count
and I do this
edvQuoteDtl.Row = indexQuoteDtl;
And I know the count of assemblies in each Line knowing this:
edvJobAsmbl.dataView.Table.Rows.Count
and I do this
edvJobAsmbl.Row = indexJobAsmbl;
And I can loop through and set using this:
EpiDataView edvJobMtl = (EpiDataView)(this.oTrans.EpiDataViews[“JobMtl”]);
or
EpiDataView edvJobMtl = oTrans.Factory(“JobMtl”);
followed by an index I maintain for this:
edvJobMtl.Row = cntPartRow;
Then I can set whatever I want using
edvJobMtl.dataView.Table.Rows[cntPartRow][“EstUnitCost”] = whatever;
HOWEVER, I’m not having any success in trying to get edvJobMtl to be anything other than default AssemblySeq 0 materials,
so I can set the same for materials in Subassemblies/Operations.
Is there a version of this or something
EpiDataView edvJobMtl = oTrans.Factory(“JobMtl”);
that can return the AssemblySeq that I want when I know what the seq and index is?
BTW, I know how to filter the DV…that’s no what I’m asking for.