Issue Materials With a Custom Epicor Kinetic Screen
By Doug Jacobson
Have you ever needed to issue material from a custom screen?
Epicor provides a stock Issue Material screen that works great in most scenarios.
Recently we had a client come to us with a request to be able to issue material from a custom screen. Their custom screen allows them to create Dynamic Attribute Sets. In addition, they wanted to be able to issue material to inventory or directly to a job. Additionally, they needed to apply the correct Dynamic Attribute Set information. In their UI, they had a value, we'll call it OurNO, that could be used to retrieve the Dynamic Attribute Set.
We accomplished this via Function Library and a couple of Functions. A primary Function "IssueMaterial" that issues the material and a helper Function "GetAttributeSetInfo" that retrieves certain properties from the correct Dynamic Attribute Set.
Note - The details of the custom screen are outside proprietary and outside the scope of this discussion.
We started by tracing the business calls made by the stock Issue Material screen. This gave us the proper business methods with their signatures. Now we just needed to create a Function that did the same thing.
The great thing about Functions is that they work with both Classic and Kinetic screens. Upgrading from the Classic UI to Kinetic can be challenging, but Functions simply work in both cases.
Without further ado, let's dive into the code.
Primary Function: IssueMaterial
From the UI, the following parameters are passed to our primary function.
| Name | Type |
|---|---|
| inJobNum | System.String |
| inOurNO | System.String |
| inAssmblyNum | System.Int32 |
| inMtlSeq | System.Int32 |
| inTranQty | System.Decimal |
| inPartNum | System.String |
| inFromWhse | System.String |
| inFromBin | System.String |
this.CallService<Erp.Contracts.IssueReturnSvcContract>(issueReturnSvc => {
var job = Db.JobHead.FirstOrDefault(x=>x.Company==CompanyID && x.JobNum == inJobNum);
if(job == null)
{
throw new BLException("Job " + inJobNum.ToString() + " not found.");
}
/*--- set up parameters used in business method calls ---*/
string pcTranType = "STK-MTL";
Guid pcMtlQueueRowID = new Guid();
string pCallProcess= "IssueMaterial";
string pcMessage = string.Empty;
Erp.Tablesets.SelectedJobAsmblTableset selectedJobAsmblTS = new Erp.Tablesets.SelectedJobAsmblTableset();
/*--- jsonSnapShot was used during testing to view our data and compare it to the trace information---*/
//string jsonSnapShot = Newtonsoft.Json.JsonConvert.SerializeObject(selectedJobAsmblTS);
var newSelectedJobAsmblRow = selectedJobAsmblTS.SelectedJobAsmbl.NewRow();
selectedJobAsmblTS.SelectedJobAsmbl.Add(newSelectedJobAsmblRow);
var selectedJobAsmbl = selectedJobAsmblTS.SelectedJobAsmbl.FirstOrDefault();
selectedJobAsmbl.Company = CompanyID;
selectedJobAsmbl.JobNum = inJobNum;
selectedJobAsmbl.AssemblySeq = inAssmblyNum;
selectedJobAsmbl.RowMod = "A";
var issueReturnTS = issueReturnSvc.GetNewJobAsmblMultiple(pcTranType,pcMtlQueueRowID, pCallProcess, ref selectedJobAsmblTS, out pcMessage);
int piToJobSeq = inMtlSeq;
var issueReturn = issueReturnTS.IssueReturn.FirstOrDefault();
issueReturn.RowMod = "A";
issueReturnSvc.OnChangingToJobSeq(piToJobSeq, ref issueReturnTS);
issueReturn.ToJobSeq = inMtlSeq;
issueReturn.RowMod = "A";
issueReturnSvc.OnChangeToJobSeq(ref issueReturnTS, pCallProcess, out pcMessage);
issueReturn.RowMod = "U";
issueReturn.PartNum = inPartNum;
issueReturnSvc.OnChangePartNum( ref issueReturnTS, pCallProcess);
issueReturn.RowMod = "A";
issueReturn.FromWarehouseCode = inFromWhse;
issueReturnSvc.OnChangeFromWarehouse(ref issueReturnTS, pCallProcess);
issueReturn.RowMod = "A";
issueReturn.FromBinNum = inFromBin;
issueReturnSvc.OnChangeFromBinNum(ref issueReturnTS);
/*-------------------------------------------------*/
/*
ThisLib.GetAttributeSetInfo is the helpder Function mentioned previously. It is not included in the scope of this article. That Function returns over a dozen parameters.
We only care about three of them in the context our Issue Material function
*/
/*-------------------------------------------------*/
int attributeSetID = (int)ThisLib.GetAttributeSetInfo(inOurNO).outAttributeSetID;
issueReturn.AttributeSetID = attributeSetID;
issueReturn.AttributeSetShortDescription = ThisLib.GetAttributeSetInfo(inOurNO).outAttributeSetShortDesc;
issueReturn.AttributeSetDescription = ThisLib.GetAttributeSetInfo(inOurNO).outAttributeSetDesc;
issueReturn.EnableAttributeSetSearch = true;
issueReturn.RowMod = "A";
issueReturnSvc.OnChangeTranQty(inTranQty, ref issueReturnTS);
issueReturn.RowMod = "U";
bool requiresUserInput = false;
issueReturnSvc.PrePerformMaterialMovement(ref issueReturnTS, out requiresUserInput);
/*--- set up parameters used in MasterInventoryBinTests method call ---*/
string pcNeqQtyAction = "";
string pcNeqQtyMessage = "";
string pcPCBinAction = "";
string pcPCBinMessage = "";
string pcOutBinAction = "";
string pcOutBinMessage = "";
issueReturnSvc.MasterInventoryBinTests(ref issueReturnTS, out pcNeqQtyAction, out pcNeqQtyMessage, out pcPCBinAction, out pcPCBinMessage, out pcOutBinAction, out pcOutBinMessage);
/*--- set up parameters used in PerformMaterialMovement method call ---*/
string legalNumberMessage = "";
string partTranPKs = "";
bool plNegQtyAction = false;
/*--- commented out the following, which was useful during development to see what was going on with our data ---*/
/*
string jsonSnapShot2 = Newtonsoft.Json.JsonConvert.SerializeObject(issueReturnTS);
throw new BLException("jsonSnapShot: " + Environment.NewLine + jsonSnapShot2);
*/
issueReturnSvc.PerformMaterialMovement(plNegQtyAction, ref issueReturnTS, out legalNumberMessage, out partTranPKs);
});
We hope you find this article helpful, and if you need help with an Epicor Kinetic uplift give us a call!
Thanks from your pals at Butiq.