JobEntry BO perfomance help

So I’m going to dig into this again, for another project. I would really like to use the BO to make the changes I need in the Job for a project in which I need to flip the backflush flag off, do some stuff then turn it back on. The BO to change one row, that one field takes 12 seconds (x2 to turn it back on afterwords). And that’s on a medium sized job, it slows down for bigger jobs. (which is when I really need it to work faster) So this is simply too slow to work at the scale I will need it to work at.

@Bart_Elia mentioned adding some indexes to the DB which sounds like it might be a viable solution to speed it up, however, simply querying the tables isn’t a problem, it’s the BO that actually makes the update that is taking so long. So, does anyone know how I would go about finding which indexes I would need to add to make whatever the BO is doing speed up? I don’t want to just start randomly adding indexes to the DB.

My last resort is obviously LINQ right to to the field, but that is a last resort, and even then I would rather not. But if anyone has any other ideas that reside on the right side of the Epicor rules, I would love any other ideas. (for example, when I complete operations, can I hijack the backflush field so it doesn’t backflush the material when this specific process is being done??)

It’s a long shot, but maybe when you are turning off backflush, this forces a Cost Rollup of the Job.
Have you traced it?
Try turning this ‘Suspend Cost and Quantity Rollups’ on before changing the rows.

image

Man that seemed promising, but, when checking out the UI, in order to suspend that I would have to un-released, unengineer, make the change, then re-engineer, re-release, do my quantity completions, then do it all over again to change it back… That seems like it would take longer. … sigh.

image

At this point, the most viable “right” way to do it that I can think of, is to make my own BPM to backflush materials so that I can control when it does and doesn’t without that flag checked so I can leave it unchecked by default… Actually the BPM that I am going to write for my integration will pretty much be that anyways, I just replace the actuals that I would be getting from out nesting software with the estimated amount like backflush does currently… :thinking:

I don’t know when you wan’t to make your changes, but if it’s from a bpm, it could be asynchronous (bpm). No waiting time.

I thought about that, but this would end up being possibly hundreds of transactions, so even with asynchronous, I don’t want it to take that much time because I want to minimize the chances of collisions. But I will definitely test and see how it works.

I wonder if its taking too long because folks usually don’t pass in the Unchanged Row to the BO so Epicor assumes that everything changed? (Me being one of those who usually doesnt, despite Epicor doing it in their Code)

What Epicor usually does in their code when they call a BO is pass the Unchanged Row and Updated Row, which may help the Triggers with performance to determine what actually changed? (Tags @Bart_Elia)

If one Reflects on Job BO you will see plenty of code where they preserve the old row and pass it to the Update.

if (ttJobProd.RowMod.Equals("U", StringComparison.OrdinalIgnoreCase))
{
	newJobProdRow = new Erp.Tablesets.JobProdRow();
	CurrentFullTableset.JobProd.Add(newJobProdRow);
	BufferCopy.Copy(ttJobProd, ref newJobProdRow);
	newJobProdRow.RowMod = "";
	// More code
}
ttJobProd = new Erp.Tablesets.JobProdRow();
CurrentFullTableset.JobProd.Add(ttJobProd);
BufferCopy.Copy(JobProd, ref ttJobProd);
ttJobProd.RowMod = "D";
Db.JobProd.Delete(JobProd);
Db.Validate(JobProd);

Snippet of Example:

UD02Tableset ds = UD02svc.GetByID(udRow.Key1,udRow.Key2,udRow.Key3,udRow.Key4,udRow.Key5);
// Create a Var to Store the Unchanged Row
UD02Row OriginalRecord = (UD02Row)ds.UD02.NewRow();
// Before we do anything to the row, copy it to OriginalRecord
BufferCopy.Copy(ds.UD02[0], OriginalRecord);
// Add it to the DataSet
ds.UD02.Add(OriginalRecord);

// Now Let's make changes
ds.UD02[0].Date02 = DateTime.Today;
ds.UD02[0].CheckBox01 = false;
ds.UD02[0].RowMod = IceRow.ROWSTATE_UPDATED;
UD02svc.Update(ref ds);

Also @josecgomez has a little more experience with Job Entry and UpdateExt and its pitfalls and successes. :slight_smile: (Tags Jose) and @Chris_Conn recently dealt with some Job BO BPMs.

1 Like

Why? If its simply a UD field not bound by the heavy BO logic code, why not simply bypass all that and set the field directly in the Db?

It’s not a UD field. (That was a different project…)

I had another thought, but I’m having trouble trying to figure this one out. Can I stop the backflush with a BPM on the backflush process? Say the user reporting the quantity is a specific user, then create an exception on the method to stop the issue of material. The problem is, I can’t figure out what method is being called on the issue material, since it’s on the server. I tried setting and exception on PerformMaterialMovement, and that didn’t seem to stop anything.

Any ideas or help on that possible solution?