Splitting Job via Function resulting in 2x requested qty on Child Job

Hello,

I’ve written a function to automate splitting jobs, taking two inputs,
JobNum(nvarchar)
ChildJobQty(decimal)

For the moment, i’ve hardcoded the output jobnum for testing (input jobnum + “-test4”)

For some reason that I can’t put my finger on, my child job is coming out with exactly double the quantities requested for split, everywhere except the make to stock demand link, which is coming out as expected.
image
917315 is source job, ive done all the job splits in the screenshot with the same child job qty, 917315-test and 917315-test4 programmatically, the rest via job entry → split job.

Following the trace, I can’t seem to find any difference in my input vs. Split Job - anyone have any insight?

Code below:

SplitJobTableset sjts = new SplitJobTableset();
JobEntryTableset jets = new JobEntryTableset();

this.CallService<Erp.Contracts.JobEntrySvcContract>(svcJE => {
  jets = svcJE.GetByID(JobNum);
});

this.CallService<Erp.Contracts.SplitJobSvcContract>(svcSJ => {
  Assembly Erp_Contracts_BO_SplitJob = Assembly.Load("Erp.Contracts.BO.SplitJob");
  Type typeJobProdRow = Erp_Contracts_BO_SplitJob.GetType("Erp.Tablesets.JobProdRow");
  dynamic jp = Activator.CreateInstance(typeJobProdRow);
  string whereClauseJobProd = "JobNum = '" + JobNum + "'";
  string whereClauseLegalNumGenOpts = "";
  string whereClauseSelectedSerialNumbers = "";
  string whereClauseSNFormat = "";
  int pageSize = 0;
  int absolutePage = 0;
  bool morePages = false;
  sjts = svcSJ.GetRows(whereClauseJobProd, whereClauseLegalNumGenOpts, whereClauseSelectedSerialNumbers, whereClauseSNFormat, pageSize, absolutePage, out morePages);
  sjts.JobProd[0].SplitQty = SplitJobQty;
  sjts.JobProd[0].RowMod = "U";
  svcSJ.ValidateJobProd(sjts.JobProd[0].SysRowID.ToString(), ref sjts);
  string opLbrMessage = "";
  string opSerialMatchMsg = "";
  string opSerialNumber = "";
  bool opSerialMatchErr = false;
  string opLLTrkWarning = "";
  bool opPartTranCreation = false;
  svcSJ.PreProcessValidate(JobNum, SplitJobQty.ToString(), true, ref sjts, out opLbrMessage, out opSerialMatchMsg, out opSerialNumber, out opSerialMatchErr, out opLLTrkWarning, out opPartTranCreation);
  bool RequiresUserInput = false;
  string SerialNumberQtyAlert = "";
  svcSJ.PreProcessSplitJob(ref sjts, DateTime.Today, out RequiresUserInput, out SerialNumberQtyAlert);
  string opLegalNumberMessage = "";
  svcSJ.ProcessSplitJob(JobNum, JobNum + "-test4", DateTime.Today, opPartTranCreation, out opLegalNumberMessage, ref sjts);
});

I would double check the trace dataset, but it appears you get 2 records for the manual split where there is only one record for your programmatic split… Maybe you are missing a record the resultant split amount to the 2nd job and it is leaving it at the original amount? I have not done a trace just guessing from the dataset appearance.

1 Like

The screenshot may be slightly misleading,
Each visible row there is an independent job split (separate run-through of split job)
*-1.18 is the correct amount that should be split off given my input,
*-2.36 is the doubled amount.

The screenshot shows 6 independent runs of job split, all at the same child qty. 4 were done with the Job Split module, and 2 with the function.

I was having the same issue on Kinetic 2023.2.35. Just sharing my 2 cents here.

After several hours of trial and error, I found that skipping the ValidateJobProd() method call fixed the issue. The method apparently performs some validations and sets JobProd_Row.Valid to true, so skipping it means we have to manually set JobProd_Row.Valid to true. That said, I’m unsure whether skipping the validation has any consequences, but it fixed the doubled split qty issue.

I have made some modifications to your code:

SplitJobTableset sjts = new SplitJobTableset();
JobEntryTableset jets = new JobEntryTableset();

this.CallService<Erp.Contracts.JobEntrySvcContract>(svcJE => {
  jets = svcJE.GetByID(JobNum);
});

this.CallService<Erp.Contracts.SplitJobSvcContract>(svcSJ => {
  Assembly Erp_Contracts_BO_SplitJob = Assembly.Load("Erp.Contracts.BO.SplitJob");
  Type typeJobProdRow = Erp_Contracts_BO_SplitJob.GetType("Erp.Tablesets.JobProdRow");
  dynamic jp = Activator.CreateInstance(typeJobProdRow);
  string whereClauseJobProd = "JobNum = '" + JobNum + "'";
  string whereClauseLegalNumGenOpts = "";
  string whereClauseSelectedSerialNumbers = "";
  string whereClauseSNFormat = "";
  int pageSize = 0;
  int absolutePage = 0;
  bool morePages = false;
  sjts = svcSJ.GetRows(whereClauseJobProd, whereClauseLegalNumGenOpts, whereClauseSelectedSerialNumbers, whereClauseSNFormat, pageSize, absolutePage, out morePages);
  sjts.JobProd[0].SplitQty = SplitJobQty;
  sjts.JobProd[0].RowMod = "U";

  // *** Start of Modified Lines ***
  // svcSJ.ValidateJobProd(sjts.JobProd[0].SysRowID.ToString(), ref sjts);
  sjts.JobProd[0].Valid = true;
  // *** End of Modified Lines ***

  string opLbrMessage = "";
  string opSerialMatchMsg = "";
  string opSerialNumber = "";
  bool opSerialMatchErr = false;
  string opLLTrkWarning = "";
  bool opPartTranCreation = false;
  svcSJ.PreProcessValidate(JobNum, SplitJobQty.ToString(), true, ref sjts, out opLbrMessage, out opSerialMatchMsg, out opSerialNumber, out opSerialMatchErr, out opLLTrkWarning, out opPartTranCreation);
  bool RequiresUserInput = false;
  string SerialNumberQtyAlert = "";
  svcSJ.PreProcessSplitJob(ref sjts, DateTime.Today, out RequiresUserInput, out SerialNumberQtyAlert);
  string opLegalNumberMessage = "";
  svcSJ.ProcessSplitJob(JobNum, JobNum + "-test4", DateTime.Today, opPartTranCreation, out opLegalNumberMessage, ref sjts);
});
1 Like

Interesting, thank you for the insight!

As I recall, i was able to implement the same logic in a widget-based function (using all the same inputs and outputs), but experienced this odd behavior in a code-based function with the same workflow. Scratched my head for a while and moved on with the widget based function (which does work with ValidateJobProd!)

3 Likes