Is anyone using Epicor Functions to expose BAQs or should we be continuing to use the BAQSvc for this?
?? But why?? Expose how in what context? What’s the use case?
I will run a BAQ in a function then take the resulting dataset, convert to Json, and send the result to the client, who rehydrates it to a dataset, and then uses it in ASP.Net pages. So the only use case I can think of right now is if you don’t want OData.
Should have been more clear. Working on a re-work of an existing integration to utilize functions (hopefully exclusively) and I wasn’t sure if there is a mechanism to call a BAQ from a function .
Otherwise, I’ll need to expose my app to both the function library and the BAQ service, not a big deal just wondering if that’s the way it is
So it does sound like you’re able to call an existing BAQ from a function? Would you be able to share how to? I am sure I’m overlooking something obvious
Sure. I added some logic to version the query, so I’ve left that off. But this is the basic:
1.) Execute Invoke BO
2.) Fill in the Parameters using Fill Table by Query. (This is a single parameter BAQ in this case but you just have to make sure that you’ve filled out all mandatory parameters).
3.) Execute the query using the Invoke BO again
4.) Convert result to json and return using Custom Code. Remember to add your reference for Newtonsoft if you use it!
try {
oResult = Newtonsoft.Json.JsonConvert.SerializeObject(dsQueryResult);
oError = “OK”;
oErrorMsg ="";
}
catch (Exception e) {
oResult = “”;
oError = “ERROR”;
oErrorMsg = e.Message;
}
iEmail is my input parameter that I pass to the query and oResult, oError, and oErrorMsg are return variables.
Exactly what I was hoping for, thank you!
Oh, make sure to use the RowMod “A” when filling the parameter table.
Aaaaaand, I name any BAQs used in functions with a leading API- because there is no “Where Used” for function calls. But that’s just me…
This is fantastic. Just wondering what happens if you want to return the results as a table, rather than Json?
For instance, I have function ANXStorageReqsGetWHBinsForPart with input parameter of PartNum and response parameter dsAcceptableBins of type Erp.Tablesets.IMWhseBinTableset in which I’d like a list of the available bins to be returned into, do I just to a foreach in the dsQueryResult and insert into the AcceptableBins return dataset?
Unless someone has a better way, I’ve answered my own question. Basically, just insert them as follows:
foreach(DataRow BAQRow in tsBAQQueryResults.Tables[0].Rows)
{
Erp.Tablesets.IMWhseBinRow NewWhseBin = new Erp.Tablesets.IMWhseBinRow();NewWhseBin.Company = BAQRow[“WhseBin_Company”].ToString();
NewWhseBin.WarehouseCode = BAQRow[“WhseBin_WarehouseCode”].ToString();
NewWhseBin.BinNum = BAQRow[“WhseBin_BinNum”].ToString();
NewWhseBin.Description = BAQRow[“WhseBin_Description”].ToString();AcceptableBins.IMWhseBin.Insert(0,NewWhseBin);
}
Sorry to bring back this old thread. First time playing with functions and trying to wrap my head around step 2 (Fill Parameters). Are you able to show what your ParameterQuery query looks like? Also, my BAQ has 2 parameters and not sure how that is handled (does the Binding values need to be comma separated?). Thank you very much!
Here’s a snippet from a multi-parameter BAQ I use in my Bartender API integration. You can also skip the GetQueryExecutionParametersByID method entirely and build a QueryExecutionDataSet entirely manually. The method below only saves a handful of lines.
This particular snippet is probably straight from a BPM, but the only thing you’d change in a function (maybe) is the using statement.
baqName = "ReceiptLabel";
using (var svc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.DynamicQuerySvcContract>(Db))
{
//Get parameter object from the BAQ that's about to be called.
qeds = svc.GetQueryExecutionParametersByID(baqName);
//Set parameters. Extra verbose because I can't guarantee row ordering
qeds.ExecutionParameter[0].ParameterID = "PackSlip";
qeds.ExecutionParameter[0].ParameterValue = ipPackSlip;
qeds.ExecutionParameter[0].ValueType = "nvarchar";
qeds.ExecutionParameter[1].ParameterID = "VendorNum";
qeds.ExecutionParameter[1].ParameterValue = ipVendorNum.ToString();
qeds.ExecutionParameter[1].ValueType = "int";
qeds.ExecutionParameter[2].ParameterID = "Client";
qeds.ExecutionParameter[2].ParameterValue = Session.ClientComputerName;
qeds.ExecutionParameter[2].ValueType = "nvarchar";
//Execute baq with paramaters entered above
baqds = svc.ExecuteByID(baqName, qeds);
}
I strongly recommend messing around with the Business Logic Tester tool. It’s great at visualizing the objects returned by various methods.
Or the Swagger/OpenAPI pages if you move over to REST.
I think he was more looking at more clarification on populating the call with the widgets,
but I could be wrong.
Yes with the widgets. I think I figured out the ParameterQuery query as my function now works, but using a 1 parameter BAQ. It is when using BAQs with multiple parameters that I still scratch my head
Thanks jtownsend but Im looking for a widget solution like Mark shared above.
Then use the code above as your blueprint for the widgets. Call the BO, fill the resulting table, call the other BO…etc.
I use both, though it’s usually quicker to just fire up BL Tester since I don’t need to bother with API keys.
Sorry for the late response @maxtin, Like @hmwillett, @josecgomez has me working instead of replying to messages on EpiUsers.
Basically, I would do expressions for the Bindings using nested tertiary operators to make a case statement using the parameter name to update the QueryCtrlValues:
(dsBAQQueryCtrlValuesRow.ID == "Parm1") ? "Parm Value 1" :
(dsBAQQueryCtrlValuesRow.ID == "Parm2") ? "Parm Value 2" : ""
Haven’t tested this, but hopefully you get the idea how to do that with either the Fill Table by Query or the Update Table by Query widgets.