I (we) should be enjoying this Saturday morning with a coffee and maybe some YouTubes or a video game, but this has me by the ears!
I’ve got my coffee!
UpdateExt worked on JobHead.
Let me see if I can find something to update on JobOper.
Won’t let me do anything on JobOper, but I don’t have any UD fields.
Adding one, and doing a regen. Give me a sec.
Ok, UD field on JobHead → UpdateExt works fine.
UD field on JobOper → UpdateExt is a no go.
You’ll either have to unrelease, unengineer, change it, and put it back,
or change the field with the Db Context.
Wow. So in your tests, you were calling via the REST API? Just trying to document your testing process.
Also, by “DbContext” is that synonomous with our BMP using the IceDataContext?
No, but it doesn’t matter. The call is the call.
Yes.
Here is a function that will do what you want, you can call this:
/*
Ref: Table -> Erp.JobOper (Remember to set Library Read/Write & Check box to enable write on table in references tab.)
Ref: Assembly: Newtonsoft.Json
Sig -> Input
JobNum -> String
AssemblySeq -> Int32
OprSeq -> Int32
FieldDictionaryJson -> String (json of a Dictionary<string, object>)
*/
var fieldsToSet = JsonConvert.DeserializeObject<Dictionary<string, object>>(FieldDictionaryJson);
var oper = Db.JobOper.Where(o =>
o.Company == Session.CompanyID &&
o.JobNum == JobNum &&
o.AssemblySeq == AssemblySeq &&
o.OprSeq == OprSeq)
.FirstOrDefault();
if(oper != null)
{
//oper.Test_c = "Hello Margaret...";
foreach(var field in fieldsToSet)
{
oper[field.Key] = field.Value;
}
}
Db.SaveChanges();
Ok, so this is new for me – as to how to reproduce an equiv of this that operates via the REST API.
You can’t.
You’ll need to call a function to use the Db Context. (Or a BPM etc)
I’m not sure how to call a function with that library you are using, but make one like I provided, and you can call it with those arguments.
The Dictionary Json object could be created something like this:
var fieldsToSend = new Dictionary<string, object>()
{
{"UD_SetName_c", setName},
{"UD_Config_c", configSet}
};
string fieldsToSendJson = JsonConvert.SerializeObject(fieldsToSend);
Probably something like this: (if I read @josecgomez notes correctly)
var arguments = new
{
JobNum = "YourJobNum",
AssemblySeq = 0,
OprSeq = 10,
FieldDictionaryJson = fieldsToSendJson //from above
};
EpicorRest.EfxPost("YourLibrary", "YourFunction", arguments);
I don’t either … so dug a little into the EpicorRest thread to see how to do this. Unfortunately for this project, the base requirement for calling Functions from the client is V2 …
…this project is still using V1

So, while I super appreciate the Saturday morning assists/discovery here, I’ve been gated until we upgrade it to V2 apparently. @josecgomez (assuming this is still the case? Also, can V1 do this update via an UBAQ?)
Well, then I’ll come back later and show you a UBAQ Example.
BAQ →
ForJeff.baq (24.2 KB)
Explanation →
Advanced BPM Update checked.
No need to add a custom action, but add a base directive on custom action in the BPM designer.
Add condition that actionID begins with “{” (We are passing it Json)
True side goes to custom code that does this
UBAQ BPM → Base Custom Action
//Template Argument
var argumentTemplate = new
{
JobNum = "",
AssemblySeq = (int)0,
OprSeq = (int)0,
FieldDictionaryJson = ""
};
//Deserialize the "actionID", we just passed it json
var functionArguments = JsonConvert.DeserializeAnonymousType(actionID, argumentTemplate);
//Deserialize fields Dictionary
var fieldsToSet = JsonConvert.DeserializeObject<Dictionary<string, object>>(functionArguments.FieldDictionaryJson);
//Get Operation
var oper = Db.JobOper.Where(o =>
o.Company == Session.CompanyID &&
o.JobNum == functionArguments.JobNum &&
o.AssemblySeq == functionArguments.AssemblySeq &&
o.OprSeq == functionArguments.OprSeq)
.FirstOrDefault();
//set Field
if(oper != null)
{
//oper.Test_c = "Hello Margaret...";
foreach(var field in fieldsToSet)
{
oper[field.Key] = field.Value;
}
Db.SaveChanges();
}
Call from external would be something like this:
string _queryID = "ForJeff";
string jobNum = "YourJob";
int assemblySeq = 0;
int oprSeq = 10;
var fieldsToSend = new Dictionary<string, object>()
{
{"UD_SetName_c", setName},
{"UD_Config_c", configSet},
};
string fieldsToSendJson = JsonConvert.SerializeObject(fieldsToSend);
var actionID = new
{
JobNum = jobNum,
AssemblySeq = assemblySeq,
OprSeq = oprSeq,
FieldDictionaryJson = fieldsToSendJson //from above
};
string actionIDJson = JsonConvert.SerializeObject(actionID);
var postData = new
{
queryID = _queryID,
actionID = actionIDJson,
queryResultDataset = new {}
};
EpicorRest.DynamicPost("Ice.BO.DynamicQuerySvc", "RunCustomActionByID", postData);
I’m going to give this a shot later today! Thanks for the effort!
Made some progress… but getting some errors. Sent you a DM about how to add the Newtonsoft assembly (not sure how to do that as cloud hosted). I converted to native System.Text.Json to get past that but getting errors…
I attached my BAQ to that post. You can always copy it and rename then edit if needed.
I’ve reproduced and re-ran my test. I see the updates happen, get an OK result, re-query Epicor using GetByID and see the values … however, when I run the query in the BAQ designer and via other REST API GetByIDs afterwards I see blank field values again – is this transactional? I can’t figure out why they don’t persist. Not getting any errors.
I definitely appreciate the help and don’t want to overstep – any other suggestions?
Sounds to me like you have something resetting them.
If your getbyid returns the correct values after you set them, it’s set.
lol, with me, probably not.
I love a puzzle.
Good.
So right after the call to the UBAQ call completes (the code you provided), I run a new GetByID …
… you can see if I hover the return object from the GetByID that the UD values are present.
So I let that finish and the session ends. Then, outside of the REST API app, when I then query the BAQ directly in the Epicor client (filtering for the same JobNum), the values are blank… like it never happened; even tho we witnessed it.
…which is why I was asking if there was some sort of transactional revert that was happening or something. It’s like it never saved.