Merge Dirty Tableset onto GetByID tableset?

Hi folks.
I’m trying to add a comment to the next operation after a few different operations, if they have a SendAheadOffset configured.

I have a BPM on JobEntry.Update() which is looking for the aforementioned operations, but with only the dirty dataview coming in into Update(), I need to GetByID to know for sure that I also have the subsequent operation.

For the life of me, I can’t figure out how to do this. I was hoping BufferCopy wouldn’t demolish the dirty dataview’s change data when I copy in the GetByID result, but it seems to.

When I work entirely within the GetByID result and attach back to it, my changes propagate, but then I lose the actual change the user just saved.

Up until now I’ve been working mostly inside Efx scope.
What am I doing wrong here?

/*
Julie F.
CompanyName

SetSendAheadCommentBPM();
Prepends delay information to the subsequent operation when a Send Ahead Offset is specified.

Parameters(JobEntryTableSet ds)
Returns(JobEntryTableSet ds)
*/
if (ds.JobOper.Count > 0)
{
  var jes = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(Db);
  JobEntryTableset fillDS = jes.GetByID(ds.JobOper.First().JobNum);
  BufferCopy.Copy(fillDS, ds);
  
  foreach (var localOperRow in ds.JobOper.ToList())
  {

    if ((decimal)localOperRow["SendAheadOffset"] != 0)
    {
      int    delayDays   =    (int)localOperRow["DelayDays_c"];
      string localOpCode = (string)localOperRow["OpCode"];
      string appendMessage = "";
      switch (localOpCode)
      {
        case "BOND":
          appendMessage = $"You Gotta Wait {delayDays} DAYS!" + System.Environment.NewLine;
          break;
        case "E-BOND":
          appendMessage = $"You Gotta Wait {delayDays} DAYS!" + System.Environment.NewLine;
          break;
        case "NULL": // tbd
          appendMessage =$"You Gotta Wait {delayDays} DAYS!" + System.Environment.NewLine;
          break;
        case "VOID": // tbd
          appendMessage = $"You Gotta Wait {delayDays} DAYS!" + System.Environment.NewLine;
          break;
        default:
          continue;
      }

      // entry if non-default case
      var nextOperRC = (from           nextOperRow in ds.JobOper
                        where     (int)nextOperRow["OprSeq"]      >     (int)localOperRow["OprSeq"] &&
                               (string)nextOperRow["JobNum"]      == (string)localOperRow["JobNum"] &&
                                  (int)nextOperRow["AssemblySeq"] ==    (int)localOperRow["AssemblySeq"]
                        orderby   (int)nextOperRow["OprSeq"]
                        select         nextOperRow);

      if (nextOperRC != null)
      {
        if (nextOperRC.Count() > 0)
        {
          JobOperRow nextOperRowOld = nextOperRC.First();
          JobOperRow nextOperRowUp = new JobOperRow();
          BufferCopy.Copy<JobOperRow, JobOperRow>(nextOperRowOld, nextOperRowUp);
          ds.JobOper.Add(nextOperRowUp);

          string firstcheck = (string)nextOperRowOld["CommentText"];
          if(firstcheck.StartsWith(appendMessage))
          {
            continue;
          }

          string curOpComment = (string)nextOperRowOld["CommentText"] != null ? (string)nextOperRowOld["CommentText"] : "";
          string newOpComment = string.Concat(appendMessage, curOpComment);

          nextOperRowUp["CommentText"] = newOpComment;
          nextOperRowUp["RowMod"] = "U";
        }
      } 
    }
  }
  this.dsHolder.Attach(ds);
}

I still have some error and edge-case checking to write into here, but I’m stumped trying to get the full dataset (including screenspace changes) into a single object. Am I dumb?

1 Like

I think you need to just add the additional row you are trying to update instead of buffer copy. Did you try asking chatgpt or equivalent this question? It can probably reconstruct this for you so you don’t lose the changes from the dirty row.

TL;DR

BufferCopy.Copy(fillDS, ds); is the thing that’s “demolishing” your dirty view. Remove it.

Treat GetByID (or Db.JobOper) as a read-only lookup.

Always apply your changes on the BPM ds tableset and mark rows as “U” or “A”.

1 Like

This makes sense. I thought about what Alisa said, and now I’m trying this by either pulling the ds row if it exists, or the db row if it doesn’t, and adding it to the dataset. everything else in the lookup dataset is irrelevant to the actual update being called, so that makes sense to me.

I’ll post the final code when I’m done in case anyone runs into this pattern-selection problem.

2 Likes

This isn’t perfect by any means; my original goal was to do this to the whole serverside dataset (this requires an update to the Operation in question) but this seems like it’s along the right lines.

If the rows exist in the Update dataset, this code uses them; if not, it retrieves the relevant rows from the server-side copy of the entire dataset coming in from GetByID.

Might rework this at some point to be driven by the server-side copy, but for the moment it works and that’s all I need.

/*
Julie F.
AccraFab

SetSendAheadCommentBPM();
Prepends delay information to the subsequent operation when a Send Ahead Offset is specified.
*/
var jes = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(Db);
JobEntryTableset searchDS = jes.GetByID(ds.JobOper.First().JobNum);

foreach (var dsOpRow in ds.JobOper.ToList())
{
    if ((decimal)dsOpRow["SendAheadOffset"] != 0)
    {
        int delayDays = (int)dsOpRow["DelayDays_c"];
        string localOpCode = (string)dsOpRow["OpCode"];
        string appendMessage = "";

        switch (localOpCode)
        {
            case "BOND":
            case "E-BOND":
            case "NULL":
            case "VOID":
                appendMessage = $"You Gotta Wait {delayDays} DAYS!" + System.Environment.NewLine;
                break;
            default:
                continue;
        }

        var nextOperRCDS =
            from nextOperRow in ds.JobOper
            where (int)nextOperRow["OprSeq"] > (int)dsOpRow["OprSeq"]
               && (string)nextOperRow["JobNum"] == (string)dsOpRow["JobNum"]
               && (int)nextOperRow["AssemblySeq"] == (int)dsOpRow["AssemblySeq"]
            orderby (int)nextOperRow["OprSeq"]
            select nextOperRow;

        var nextOperRCDB =
            from nextOperRow in searchDS.JobOper
            where (int)nextOperRow["OprSeq"] > (int)dsOpRow["OprSeq"]
               && (string)nextOperRow["JobNum"] == (string)dsOpRow["JobNum"]
               && (int)nextOperRow["AssemblySeq"] == (int)dsOpRow["AssemblySeq"]
            orderby (int)nextOperRow["OprSeq"]
            select nextOperRow;

        JobOperRow nextOpRowOld = new JobOperRow();
        JobOperRow nextOpRowNew = new JobOperRow();

        int dbCount = nextOperRCDB?.Count() ?? 0;
        int dsCount = nextOperRCDS?.Count() ?? 0;

        if (dsCount > 0)
        {
            var nextRow = nextOperRCDS.First();

            if (nextRow.RowMod == "A")
            {
                // next dataset row is being added, copy it directly
                BufferCopy.Copy(nextRow, nextOpRowOld);
                BufferCopy.Copy(nextRow, nextOpRowNew);
            }
            else if (nextRow.RowMod == "D")
            {
                // next dataset row is being deleted, append to subsequent row if it exists
                var subsequentRow = nextOperRCDS.Skip(1).FirstOrDefault();
                if (subsequentRow != null)
                {
                    BufferCopy.Copy(subsequentRow, nextOpRowOld);
                    BufferCopy.Copy(subsequentRow, nextOpRowNew);
                }
                else if (dbCount > 0)
                {
                    // fallback to DB next row if dataset has no subsequent row
                    var dbNextRow = nextOperRCDB.First();
                    BufferCopy.Copy(dbNextRow, nextOpRowOld);
                    BufferCopy.Copy(dbNextRow, nextOpRowNew);
                }
                else
                {
                    continue; // nothing to append to
                }
            }
            else if (nextRow.RowMod == "U")
            {
                // next dataset row is being updated
                BufferCopy.Copy(nextRow, nextOpRowOld);
                BufferCopy.Copy(nextRow, nextOpRowNew);
            }
        }
        else
        {
            // dataset has no next row, pull from DB if exists
            if (dbCount > 0)
            {
                var nextRow = nextOperRCDB.First();
                BufferCopy.Copy(nextRow, nextOpRowOld);
                BufferCopy.Copy(nextRow, nextOpRowNew);

                ds.JobOper.Add(nextOpRowOld);
                ds.JobOper.Add(nextOpRowNew);
            }
            else
            {
                continue; // nothing to modify
            }
        }

        string curOpComment = nextOpRowOld["CommentText"] as string ?? "";
        string newOpComment = string.Concat(appendMessage, curOpComment);

        nextOpRowNew["CommentText"] = newOpComment;
    }
}
1 Like