Ok. Happy Friday everyone! I am stumped. I have a BPM that is supposed to copy some information to UD38 table. I have troubleshooted this thing as far as I can. It’s a data directive on the JobProd table. So when a new job is created, I filter to ones that meet one of two conditions. Either it’s a traditional part that is Make Direct on the order, or a configured part. I am passing all my milemarkers. I have messages setup to alert me to which conditions are met. I also have a message box that shows a bunch of variables that I am using in my Execute Custom Code block. Everything appears to be working as it should. But…
If the part is a regular part, it will update the UD38 table as expected. Using the exact same execute custom code block, it will not update a UD38 if it is a configured part. When one condition is met it updates and when it’s the other (in the same conditional logic block) it does not. No errors. I don’t even know what else to say. It “should” be working but it just isn’t. It’s executing the custom code just the same, it just doesn’t update the table at the end. Any ideas?
try {
var getOrderDtl = (from r in ttJobProd
join o in Db.OrderDtl on new { r.OrderNum, r.OrderLine } equals new { o.OrderNum, o.OrderLine }
join p in Db.Part on r.PartNum equals p.PartNum
where r.RowMod == "A"
select new { OrderNum = r.OrderNum, OrderLine = r.OrderLine, JobNum = r.JobNum, Configured = o.vanIsParent_c, StaticProgram = p.StaticProgram_c, RelNum = r.OrderRelNum }).FirstOrDefault();
// we only want to update Configured UD orders
if (getOrderDtl.Configured == true || getOrderDtl.StaticProgram == true) {
string orderNum = !String.IsNullOrEmpty(getOrderDtl.OrderNum.ToString()) ? getOrderDtl.OrderNum.ToString() : "";
string orderLine = !String.IsNullOrEmpty(getOrderDtl.OrderLine.ToString()) ? getOrderDtl.OrderLine.ToString() : "";
string relNum = !String.IsNullOrEmpty(getOrderDtl.RelNum.ToString()) ? getOrderDtl.RelNum.ToString() : "";
string jobNum = !String.IsNullOrEmpty(getOrderDtl.JobNum) ? getOrderDtl.JobNum : "";
var UDrows = (from r in Db.UD38
where r.Key1 == orderNum
&& r.Key2 == orderLine
&& r.Key3 == relNum
select r);
if (UDrows != null)
{
foreach (var eachRow in UDrows)
{
string serialNum = eachRow.Key5;
Ice.Contracts.UD38SvcContract boUD38 = null;
Ice.Tablesets.UD38Tableset dsUD38 = new Ice.Tablesets.UD38Tableset();
boUD38 = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.UD38SvcContract>(Db);
dsUD38 = boUD38.GetByID(orderNum, orderLine, relNum, "", serialNum);
if (dsUD38 != null) {
var rowToUpdate = (from r in dsUD38.UD38
select r).FirstOrDefault();
JJJ += rowToUpdate.Key1 + "~" + rowToUpdate.Key2 + "~" + rowToUpdate.Key3 + "~" + rowToUpdate.Key4 + "~" + rowToUpdate.Key5;
rowToUpdate.Key4 = "LOOOL";
rowToUpdate.Character06 = "LOOOL";
rowToUpdate.RowMod = "U";
boUD38.Update(ref dsUD38);
}
}
}
}
} catch (Exception ex) {
throw new Ice.BLException(ex.Message);
}
I am showing variable JJJ in the message box after the execute custom code block and it successfully shows the variables as though everything is working correctly.
Well, this question has evolved. It turns out, after typing all this to you guys I finally figured out what was happening. The configurator is deleting and then re-creating the rows when the job wizard is running. I definitely didn’t expect that because it’s only supposed to execute the code that populates the UD38 table when the context entity is OrderDtl. However, apparently it’s still executing despite that it’s the job wizard. So it’s doing it’s job. It thinks I am editing the configuration, in which case it should delete the existing rows and then recreate them with the new configuration parameters.
So, new question: how can I filter other than using Context Entity. I need it to not run that code in the configurator when it’s creating the job.
It’s probably best if Configurator code only alters the configuration process, not external tables. Have this functionality run off a BO related to the Job creation.
I saw your reply in a different thread. You had mentioned firing a BPM and having the BPM access the BO. Any tips/suggestions when/what would work best?
One of the main reasons I did it the way I did it was that I don’t know how to get the parameters out of a configuration externally. I know there are some PC tables but I think I saw that it’s not directly accessible. Are you familiar with this at all?
I think you understood it. I am just all over the place.
Configurator is supposed to copy values from the configuration to my UD table only in the OrderDtl context. In other words, I’m actually configuring/editing something. This involves adding a new row to the UD table for the order line.
When the job is created, I have a BPM that fires and is supposed to add the JobNum to the row. That actually is working as expected - contrary to my belief when I first started this post.
My problem is that when the job is created, it is apparently executing the code in the configurator that sets up the new row so it’s finding the row already there, deleting it, and then re-creating it… which wipes out the update I do using the BPM. So I’m trying to stop that from executing when I run Order Job Wizard… but evidently because Order Job Wizard launces from the Order screen, it uses OrderDtl as the Context Entity.
I think the thing that might be throwing you off, is the concept of the “Context Entity” in the configurator. I think that is used by other processes that use the configurator, but the configurator itself doesn’t know what context it’s being used in. This is my educated guess, and not a hard fact.
So the flow and actions would be:
In Order Entry, run configurator for part
Add/Update UD38 from inside the configurator. Field for JobNum in UD38 will be blank
During job creation, Update field used for JobNum in UD38
What if someone edits the configuration after the job has been created?
Yes, that’s the work flow. We don’t allow editing of the Configuration if there’s a job already created… It’s our way to make sure everything stays in sync. The Configurator checks when it’s launched and if it finds a job, it prompts the user with a message and sets everything to read only.
So the problem is that the code in the configurator is always updating UD38, because it doesn’t know if it’s being run from Order Entry or Job Creation.
And the configurator window (the one you make in Cfg Designer) doesn’t actually show, so it is code in Cfg Entry (Document Rules) or in Cfg Rules?
I’ve not used them, but have you looked into the Document Variables?
Correct. To be honest, I think I know the answer. I thought I was being efficient when I first wrote it. Rather than try to evaluate every parameter being passed to check if it was different, I simply said to delete the row if it finds one and then re-create it using the values in the configurator. I think I need to evolve that to be an update instead of a delete. And I will only update things that are different than what’s already there. This should then handle the rogue firing of the rule when the job is created.
Just a follow-up. I did go back and review my code and it now checks first if there are any existing rows in my UD38 table, if it finds them, I check each field to see if it changed from what’s already there… it then only updates if it finds a change. If it finds no changes, then it exits the script with no changes.