ChangeJobOperEstScrap method having no effect in Epicor function

Hello,

Has anyone successfully modified the EstScrap fields on a job operation in a BPM or function? I’ve tried every approach I know of, but I cannot successfully change the value of this field.

I’ve tried:

  • Setting RowMod = “U” on the JobOper in question, setting the EstScrap and RunQty fields, then calling ChangeJobOperEstScrap. I then unset RowMod and then call Update. These are the same events that happen with logging changing this value in the UI. If I leave the RowMod as “U” when calling Update, I get the “Cannot manually update” errors I’ve seen before.
  • Flushing deferred changes after calling ChangeJobOperEstScrap.
  • Manually setting these fields within a transaction scope.
  • Calling the same BO methods as in the first bullet point, but in custom code from within a transaction scope.

No matter what, I can’t. get. the. value. to. change. I considered doing this in a data directive, and I am able modify this field there, but it’s not preferred.

Here’s my most recent attempt using the BO methods. I’ve confirmed that the tableset is actually being modified with the proper EstScrap and RunQty.

using(var tx = IceContext.CreateDefaultTransactionScope()) { 
  try {
    this.CallService<Erp.Contracts.JobEntrySvcContract>(js => {
      JobDS.JobOper[OpCounter].RowMod = "U";
      JobDS.JobOper[OpCounter].EstScrap = (decimal) OpScrap;
      JobDS.JobOper[OpCounter].RunQty = (decimal) (OpScrap / 100) + JobDS.JobOper[OpCounter].RunQty;
      js.ChangeJobOperEstScrap(ref JobDS);
      JobDS.JobOper[OpCounter].RowMod = "";      
      js.Update(ref JobDS);
    });
  } catch (Exception e) {
    error = e.Message;
  }
  
  Db.SaveChanges();
  tx.Complete();
}

Thoughts?

Send two JobOper records, an “unmodified” one with RowMod empty, and another modified with RowMod U and see what happens.

Send that to Update or to ChangeJobOperEstScrap?

Both, should only be done at the start of the logic.
ChangeJobOperEstScrap will work on the “modified” row, and the update will see the unmodified and modified row with whatever changes any method previously called did.

That worked! I wasn’t sure what the best way to create a duplicate JobOper row is, so I’m pulling a new one with GetNewJobOper. Anything particularly stupid I’m doing in this snippet?

this.CallService<Erp.Contracts.JobEntrySvcContract>(js => {
    // get a fresh joboper
    JobEntryTableset tmpDS = js.GetByID(JobNum);
    js.GetNewJobOper(ref tmpDS, JobNum, JobDS.JobOper[OpCounter].AssemblySeq);
    
    JobOperRow origRow = tmpDS.JobOper[OpCounter];
    JobOperRow updtRow = tmpDS.JobOper.Find((JobOperRow row) => row.RowMod == "A");
    
    // copy values from original row into new row
    foreach (var column in tmpDS.JobOper[OpCounter].Table.Columns) {    
      updtRow[column.ColumnName] = origRow[column.ColumnName];
    }  
    
    // set rowmod and new scrap values
    updtRow.RowMod = "U";
    updtRow.EstScrap = (decimal) OpScrap;
    updtRow.RunQty = (decimal) (OpScrap / 100) + origRow.RunQty;
    
    js.ChangeJobOperEstScrap(ref tmpDS);    
    js.Update(ref tmpDS);    
  });   

It’d be great if I didn’t need to pull a fresh tableset each time (I’m running this against a bunch of operations), but I couldn’t figure out a way to reuse it. Removing the newly created row before another cycle in my loop resulted in a “duplicate JobHead” error.

I modified your original snippet, try this and see if it works
IIRC any OnChange logic will retain the RowMod so you can call as many as needed, but the Update will return only one updated record without rowmod, I think :slight_smile:

using(var tx = IceContext.CreateDefaultTransactionScope()) { 
  try {
    this.CallService<Erp.Contracts.JobEntrySvcContract>(js => {
      var unmodifiedRow = JobDS.JobOper[OpCounter];
      var updatedRow = jobDS.JobOper.NewRow();
      BufferCopy.Copy(unmodifiedRow , updatedRow);
      JobDS.JobOper.Add(updatedRow);
      updatedRow.RowMod = "U";
      updatedRow.EstScrap = (decimal) OpScrap;
      updatedRow.RunQty = (decimal) (OpScrap / 100) + updatedRow.RunQty;
      js.ChangeJobOperEstScrap(ref JobDS);   
      js.Update(ref JobDS);
    });
  } catch (Exception e) {
    error = e.Message;
  }
  
  Db.SaveChanges();
  tx.Complete();
}
1 Like

Well that’s a far better way to copy a row! :slight_smile: I’ll give your code a whirl.