Hello all,
I am having trouble with a form customization on the RMA Processing form. I have created a pared-down version of the customization I am working with to demonstrate the issue. I am hoping someone can help me figure out this problem.
The basic problem is that I am using the RMAProc adapter to grab a record and create a receipt – and it appears to work as far as the data is concerned, but I cannot get the form to show the data correctly – it only comes up in the tree view and on the grid views.
Here is the method:
private void btnGetSpecificRecord_Click(object sender, System.EventArgs args)
{
//Existing RMA detail
int RMANum = 10877;
int RMALine = 1;
string LotNum = "162228-6546";
//Get adapter
RMAProcAdapter rMAProcAdapter = ((Erp.Adapters.RMAProcAdapter)oTrans.AdapterList[0]);
rMAProcAdapter.BOConnect();
//Get existing RMA
if(rMAProcAdapter.GetByID(RMANum))
{
//Create new receipt
if (rMAProcAdapter.GetNewRMARcpt(RMANum, RMALine))
{
DataRow detailRow = rMAProcAdapter.RMAProcData.RMARcpt[rMAProcAdapter.RMAProcData.RMARcpt.Rows.Count - 1];
detailRow["LotNum"] = LotNum;
detailRow["RequestMove"] = false;
rMAProcAdapter.Update();
}
}
//Try to get oTrans to see the change - but these no combination of these appear to be getting me what I want
oTrans.Update();
oTrans.NotifyAll();
oTrans.Refresh();
//Cleanup adapter
rMAProcAdapter.Dispose();
}
When I click the button, this happens:
The data is showing up in the list views, just not the details:
But all the data shows up on the details tab:
My question is how can I get the data to show in all the applicable places? Am I missing some magic oTrans method that will tell the form that it needs to refresh the entry forms? Any help would be greatly appreciated!
Sorry if my formatting is not up to snuff, this is my first time posting.
Since you’re using the RMA form to do this, you don’t need to instantiate a new RMA Adapter, since that will be disconnected from the UI.
You can instead use the native adapter which is going to be tied into the UI.
here is an example of using a native adapter to do work and then notify the form for UI changes.
Pay attention to the following code:
var adapterInsp = ((InspProcessingAdapter)(this.csm.TransAdaptersHT["oTrans_inspAdapter"])); //native adapter
// **************************************************
// Custom code for InspectionProcessingEntryForm
// Created: 12/5/2017 11:39:08 AM
// Modified: 12/5/17 AMM
// Add custom tool to actions menu that allows one to search by special parameters
// **************************************************
extern alias Erp_Contracts_BO_InspProcessing;
extern alias Erp_Contracts_BO_DMRProcessing;
extern alias Erp_Contracts_BO_Receipt;
extern alias Erp_Contracts_BO_SupplierXRef;
extern alias Erp_Adapters_InspProcessing;
extern alias Erp_Adapters_PO;
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;
using System.Collections;
using System.Collections.Generic;
public class Script
{
// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables' Comments! **
// Begin Wizard Added Module Level Variables **
private EpiDataView edvporView;
private EpiDataView edvuiView;
private EpiDataView edvinvView;
// End Wizard Added Module Level Variables **
// Add Custom Module Level Variables Here **
private ReceiptAdapter adapterReceipt;
public void InitializeCustomCode()
{
// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
// Begin Wizard Added Variable Initialization
this.InspectionProcessingEntryForm.BeforeToolClick += new Ice.Lib.Framework.BeforeToolClickEventHandler(this.InspectionProcessingEntryForm_BeforeToolClick);
this.edvporView = ((EpiDataView)(this.oTrans.EpiDataViews["porView"]));
this.edvuiView = ((EpiDataView)(this.oTrans.EpiDataViews["uiView"]));
this.edvinvView = ((EpiDataView)(this.oTrans.EpiDataViews["invView"]));
// End Wizard Added Variable Initialization
// Begin Wizard Added Custom Method Calls
// 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.InspectionProcessingEntryForm.BeforeToolClick -= new Ice.Lib.Framework.BeforeToolClickEventHandler(this.InspectionProcessingEntryForm_BeforeToolClick);
this.edvporView = null;
this.edvuiView = null;
this.edvinvView = null;
// End Wizard Added Object Disposal
// Begin Custom Code Disposal
// End Custom Code Disposal
}
//custom tools
public void AddPOReceiptTool()
{
if(!baseToolbarsManager.Tools.Exists("ActionsMenu")) return;
var actionsMenu = baseToolbarsManager.Tools["ActionsMenu"] as Infragistics.Win.UltraWinToolbars.PopupMenuTool;
if(actionsMenu==null) return;
var tool = new Infragistics.Win.UltraWinToolbars.ButtonTool("Disposition Misc. Receipt");
tool.SharedProps.Caption = "Disposition Misc. Receipt";
baseToolbarsManager.Tools.Add(tool);
actionsMenu.Tools.Add(tool);
actionsMenu.Tools[tool.Key].InstanceProps.IsFirstInGroup = false;
}
public void AddInventoryNonConformanceTool()
{
if(!baseToolbarsManager.Tools.Exists("ActionsMenu")) return;
var actionsMenu = baseToolbarsManager.Tools["ActionsMenu"] as Infragistics.Win.UltraWinToolbars.PopupMenuTool;
if(actionsMenu==null) return;
var tool = new Infragistics.Win.UltraWinToolbars.ButtonTool("Disposition Inventory Non-Conformance");
tool.SharedProps.Caption = "Disposition Inventory Non-Conformance";
baseToolbarsManager.Tools.Add(tool);
actionsMenu.Tools.Add(tool);
actionsMenu.Tools[tool.Key].InstanceProps.IsFirstInGroup = false;
}
//Launch special search form
private void InspectionProcessingEntryForm_BeforeToolClick(object sender, Ice.Lib.Framework.BeforeToolClickEventArgs args)
{
if(args.Tool.Key == "Disposition Misc. Receipt")
{
//launch special search to retrieve pending PO receipts by Donor Number
object ret = ProcessCaller.InvokeAdapterMethod
(oTrans.EpiBaseForm, "QuickSearchAdapter", "ShowQuickSearchForm", new object[]
{oTrans.EpiBaseForm, "SearchByDonor", true/* multi-select */, new DataTable() });
// user cancelled
if (ret == null) return;
ArrayList list = (ArrayList)ret;
//Return type is a calculated field, which is PackNum + ~ + VendorID
//Handle Multiple Pack Slips
for(int i = 0; i<list.Count; i++)
{
string pcPurPoint = string.Empty;
string pcPackSlip = string.Empty;
int piVendorNum = 0;
string value = list[i].ToString();
char delimiter = '~';
string[] substrings = value.Split(delimiter);
//set variables, first index is pack slip, second index is vendor num
pcPackSlip = substrings[0];
piVendorNum = Convert.ToInt32(substrings[1]);
//Find PO Receipt Data by Donor Number as Pack Slip
adapterReceipt = new ReceiptAdapter(oTrans);
adapterReceipt.BOConnect();
var adapterInsp = ((InspProcessingAdapter)(this.csm.TransAdaptersHT["oTrans_inspAdapter"]));
//call a get by ID method and return all dtl within a specific pack slip
bool result = adapterReceipt.GetByID(piVendorNum, "", pcPackSlip);
if(result)
{
//Find RcvDtl records that haven't been received yet (InspectionPending = false)
//create list to store InspectionPending records line numbers
List<int> inspPending = new List<int>();
//Find RcvDtl records that haven't been received yet (InspectionPending = true)
int index = 0;
foreach(DataRow row in adapterReceipt.ReceiptData.RcvDtl)
{
if(adapterReceipt.ReceiptData.RcvDtl[index].InspectionPending)
{
inspPending.Add(adapterReceipt.ReceiptData.RcvDtl[index].PackLine);
}
index++;
}
//if no records waiting to be inspected, exit method
if(inspPending.Count==0)
{
MessageBox.Show(string.Format("Pack {0} has no Inspection Pending Receipt Detail records.", pcPackSlip));
return;
}
//copy list to array for easy index crawling
int piPackLine = 0;
int[] array = new int[inspPending.Count];
inspPending.CopyTo(array);
foreach(int line in array)
{
piPackLine = line;
adapterInsp.GetReceiptByID(piVendorNum, "",pcPackSlip,piPackLine);
oTrans.NotifyAll();
}
oTrans.NotifyAll();
oTrans.NotifyAll(EpiTransaction.NotifyType.Initialize, edvporView);
Erp.UI.Controls.Combos.InspectrCombo cmb = (Erp.UI.Controls.Combos.InspectrCombo)csm.GetNativeControlReference("fd9fe6a9-c62e-4a1e-86cf-57f55bb73815");
cmb.Focus();
}
else
MessageBox.Show("Unable to find Pack Slip...");
adapterReceipt.Dispose();
}
}
if(args.Tool.Key == "Disposition Inventory Non-Conformance")
{
//launch special search by Donor Number to retreive any non-conformance lots associated. Return value is NonConf.TranID
object ret = ProcessCaller.InvokeAdapterMethod
(oTrans.EpiBaseForm, "QuickSearchAdapter", "ShowQuickSearchForm", new object[]
{oTrans.EpiBaseForm, "SearchNonConformByDonor", true/* multi-select */, new DataTable() });
// user cancelled
if (ret == null) return;
ArrayList list = (ArrayList)ret;
//Return value is NonConf.TranID
//Add each returned value from list into a real adapter, then will pass dataset into a native adapter method
var adapterInsp = ((InspProcessingAdapter)(this.csm.TransAdaptersHT["oTrans_inspAdapter"])); //native adapter
for(int i=0;i<list.Count;i++)
{
string value = list[i].ToString();
int convertValue = Convert.ToInt32(value);
adapterInsp.GetByID(convertValue);
oTrans.NotifyAll();
oTrans.NotifyAll(EpiTransaction.NotifyType.Initialize, edvinvView);
}
oTrans.NotifyAll();
oTrans.NotifyAll(EpiTransaction.NotifyType.Initialize, edvinvView);
Erp.UI.Controls.Combos.InspectrCombo cmb = (Erp.UI.Controls.Combos.InspectrCombo)csm.GetNativeControlReference("69eac31b-3e9c-4e3f-9962-45220b10f738");
cmb.Focus();
}
}
private void InspectionProcessingEntryForm_Load(object sender, EventArgs args)
{
// Add Event Handler Code
InspectionProcessingEntryForm.StartPosition = FormStartPosition.CenterScreen;
AddPOReceiptTool();
AddInventoryNonConformanceTool();
}
}
Hey Aaron! Thanks for the quick response.
In addition to switching to the native adapter, it looks like this piece of code is also important. I guess I thought the oTrans.NotifyAll() would work by itself but it appears I needed to give it the specific data view in this case the native RMAHead data view. Either way looks to be working now, appreciate the help!
Here is the final working code for my example for those interested:
// **************************************************
// Custom code for RMAProcForm
// Created: 1/21/2022 9:18:03 AM
// **************************************************
extern alias Erp_Contracts_BO_RMAProc;
extern alias Erp_Contracts_BO_SalesOrder;
extern alias Erp_Adapters_SalesOrder;
extern alias Erp_Adapters_RMAProc;
extern alias Erp_Contracts_BO_Customer;
extern alias Erp_Contracts_BO_ShipTo;
extern alias Erp_Contracts_BO_Part;
extern alias Erp_Contracts_BO_OrderRelSearch;
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 EpiDataView edvRMAHead;
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.btnGetSpecificRecord.Click += new System.EventHandler(this.btnGetSpecificRecord_Click);
// End Wizard Added Custom Method Calls
edvRMAHead = (EpiDataView) this.oTrans.EpiDataViews["RMAHead"];
//this.edvRMAHead = ((EpiDataView)(this.oTrans.EpiDataViews["porView"]));
}
public void DestroyCustomCode()
{
// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
// Begin Wizard Added Object Disposal
this.btnGetSpecificRecord.Click -= new System.EventHandler(this.btnGetSpecificRecord_Click);
// End Wizard Added Object Disposal
// Begin Custom Code Disposal
// End Custom Code Disposal
}
private void btnGetSpecificRecord_Click(object sender, System.EventArgs args)
{
//Existing RMA detail
int RMANum = 10877;
int RMALine = 1;
string LotNum = "162228-6546";
decimal ReceivedQty = 1.0M;
//Get adapter
RMAProcAdapter rmaProcAdapter = ((RMAProcAdapter)this.csm.TransAdaptersHT["oTrans_rmaAdapter"]);
rmaProcAdapter.BOConnect();
//Get existing RMA
if(rmaProcAdapter.GetByID(RMANum))
{
//Create new receipt
if (rmaProcAdapter.GetNewRMARcpt(RMANum, RMALine))
{
DataRow detailRow = rmaProcAdapter.RMAProcData.RMARcpt[rmaProcAdapter.RMAProcData.RMARcpt.Rows.Count - 1];
detailRow["LotNum"] = LotNum;
detailRow["RequestMove"] = false;
detailRow["ReceivedQty"] = ReceivedQty;
rmaProcAdapter.Update();
}
}
//Try to get oTrans to see the change - but these do no combination of these appear to be getting me what I want
oTrans.NotifyAll();
oTrans.NotifyAll(EpiTransaction.NotifyType.Initialize, edvRMAHead);
//Cleanup adapter
rmaProcAdapter.Dispose();
}
}
1 Like