Job Receipt To Inventory (or Mfg)

I am trying to write a BPM to receive co-parts to stock from an updatable dashboard. The bpm code is as below, but the partTran transaction is never created.

Works fine in a customisation, the only difference there being that I use a dataset and in the bpm a tableset appears to be required.

Is the coding for my tableset correct?

Customisation code for dataset
Erp.BO.ReceiptsFromMfgDataSet JobRcptDS = new Erp.BO.ReceiptsFromMfgDataSet();
JobRcptDS.Tables[“PartTran”].Rows[0][“PartNum”]= compPart;
BPM Code

‘’'cs if(rmfg != null)
writer.WriteLine(System.DateTime.Now.ToString() + " Issue co parts " + pcProcessID + " from " + refJobNum);
rmfg.GetNewReceiptsFromMfgJobAsm(refJobNum,piAssemblySeq,pcTranType,pcProcessID,ref tsRMFG);
writer.WriteLine(System.DateTime.Now.ToString() + " GetNewReceiptsFromMfgJobAsm from " + refJobNum + " part " + compPart);
string pcMessage = “”;
string pcPartTranPKs = string.Empty;
bool ipContinue = false;
rmfg.OnChangePartNum(ref tsRMFG,compPart,out pcMessage,ipContinue);
writer.WriteLine(System.DateTime.Now.ToString() + " OnChangePartNum, Job " + refJobNum);
rmfg.OnChangeActTranQty(ref tsRMFG,out pcMessage);
writer.WriteLine(System.DateTime.Now.ToString() + " OnChangeActTranQty, Job " + refJobNum);

      //var ttRM = (from ttRM_r in tsRMFG.PartTran where  ttRM_r.RowMod == "A" select  ttRM_r).FirstOrDefault();
      tsRMFG.PartTran[0]["TranQty"] = compQty;
      tsRMFG.PartTran[0]["JobNum2"] = fRMA;
      tsRMFG.PartTran[0]["WareHouseCode"] = "LINE 1";
      tsRMFG.PartTran[0]["BinNum"] = "Lineside";
      tsRMFG.PartTran[0]["ActTranQty"] = compQty;
      tsRMFG.PartTran[0]["ThisTranQty"] = compQty;
      tsRMFG.PartTran[0]["PartNum"] = compPart;
      writer.WriteLine(System.DateTime.Now.ToString() + " After var ttrm, Job " + refJobNum + " "+ pcMessage + tsRMFG.PartTran[0]["PartNum"].ToString());
      rmfg.OnChangeJobNum2(ref tsRMFG, out pcMessage);
      tsRMFG.PartTran[0]["JobSeq2"] = 10; 
      tsRMFG.PartTran[0]["WareHouseCode"] = "LINE 1";
      tsRMFG.PartTran[0]["BinNum"] = "Lineside";
      tsRMFG.PartTran[0]["Plant2"] = callContextClient.CurrentPlant;
      tsRMFG.PartTran[0]["PartNum"] = compPart;
      tsRMFG.PartTran[0]["TranReference"] = "Co_Part " + refJobNum;

      tsRMFG.PartTran[0]["RowMod"] = "U";
      rmfg.OnChangeJobSeq2(ref tsRMFG, out pcMessage);
      writer.WriteLine(System.DateTime.Now.ToString() + " OnChangeJobSeq2, Job " + refJobNum + " Msg: " + pcMessage + tsRMFG.PartTran[0]["PartNum"].ToString());
      tsRMFG.PartTran[0]["PartNumAsm"] = compPart;
      tsRMFG.PartTran[0]["PartNumJH"] = compPart;
      tsRMFG.PartTran[0]["PartNumMS"] = pNum;
      bool requiresUserInput = false;
      rmfg.PreUpdate(ref tsRMFG,out requiresUserInput);
      int piMsgType;
      string pcBinAction, pcBinMessage;
      rmfg.VerifySerialMatchAndPlanContract(ref tsRMFG, out pcMessage, out piMsgType, out pcBinAction, out pcBinMessage);
      writer.WriteLine(System.DateTime.Now.ToString() + " ReceiveMfgPartToJob After PreUpdate, Job " + refJobNum + "DsPartNum = "+ tsRMFG.PartTran[0]["PartNum"].ToString());
      decimal pdSerialNoQty = 0;
      rmfg.ReceiveMfgPartToInventory(ref tsRMFG, pdSerialNoQty,false,out pcMessage,out pcPartTranPKs,"RcptToInvEntry");
      //rmfg.ReceiveMfgPartToJob(ref tsRMFG, pdSerialNoQty, false, true,out pcMessage,out pcPartTranPKs,"RcptToJobEntry");
      writer.WriteLine(System.DateTime.Now.ToString() + " ReceiveMfgPartToJob, Job " + refJobNum + " Msg: " + pcMessage);
      writer.WriteLine(System.DateTime.Now.ToString() + " ds Company = "+ tsRMFG.PartTran[0]["Company"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds Plant = "+ tsRMFG.PartTran[0]["Plant2"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds JobNum = "+ tsRMFG.PartTran[0]["JobNum"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds JobNum2 = "+ tsRMFG.PartTran[0]["JobNum2"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds PartNum = "+ tsRMFG.PartTran[0]["PartNum"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds PartNumAsm = "+ tsRMFG.PartTran[0]["PartNumAsm"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds PartNumJH = "+ tsRMFG.PartTran[0]["PartNumJH"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds PartNumMS = "+ tsRMFG.PartTran[0]["PartNumMS"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds TranQty = "+ tsRMFG.PartTran[0]["TranQty"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds WareHouseCode = "+ tsRMFG.PartTran[0]["WareHouseCode"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds BinNum = "+ tsRMFG.PartTran[0]["BinNum"].ToString());
      writer.WriteLine(System.DateTime.Now.ToString() + " ds RowMod = "+ tsRMFG.PartTran[0]["RowMod"].ToString());
  } //if (tCoPartRev != null)
     errorCount = errorCount+1;
     writer.WriteLine(System.DateTime.Now.ToString() + " No method found for " + compPart + " Will need to create job manually.");
  } '''

Initial setup for bpm, left off from initial post

        //Issue CoPart material from RMA Job
        Erp.Tablesets.ReceiptsFromMfgTableset tsRMFG = new Erp.Tablesets.ReceiptsFromMfgTableset();
        Erp.Contracts.ReceiptsFromMfgSvcContract rmfg = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ReceiptsFromMfgSvcContract>(Db);
        string refJobNum = trma + "-S1";
        //string pcTranType = "MFG-WIP";
        int piAssemblySeq = 0;
        //string pcProcessID = "RcptToJobEntry";
        string pcProcessID = "RcptToInvEntry";
        string pcTranType = "MFG-STK";```

The formatting for code is three ‘ticks’ (grave character on the same key with the tilde) and optional syntax ID, on a line by themselves.

‘’'cs if(rmfg != null)

should be


And can’t you just make a DS variable in the initial BO Method, copy the current BO’s DS to the new one, tweak the new one, and then call the BO from within your BPM?
(making sure that circular loops don’t exist with a check to see if the BO was called from itself.)

If you are on 10.2.500 or above, you can create BPM Function and call it from an Updatable BAQ.

Thanks Calvin

Worked out where the ``` is on my UK keyboard!! (above tab key).

I do not get any errors from my current BPM, just fails to save the partTran record. Is there anything wrong in the code which stops it from working, the last method called is the ReceiveMfgPartToInventory, which is same as in my customisation?

The customisation and BPM code are not related and do not work together, which I believe you response implies.


The customization that works is on the updatable dashboard?

Or do you mean if you customize the Job Receipt to Inventory screen?

I have a customisation that works in Time & Expense entry, which autoreceives co-parts to stock on completion of the final job operation.
I want to use a similar method in my updatable dashboard, but in this case I am using a DynamicQueryUpdate to fire a preprocessing BPM that creates jobs, and issues copart materials to the job. All working well, but stumbling on the issuing of the coparts to the newly created jobs. The ‘new’ jobs have methods with the co-parts in their BOMs.

I assume this created Job is “phantom” that is just used to join the co-parts into a new part. That correct?

And do all the components in the phantom job come for a single other job?

Is your goal something like:

  • Job 1234 makes 10 of part ABC-123, 5 of co-part CO-100, and 2 of co-part CO-999
  • Upon receipt of of Job 1234, to stock, co-pats CO-100 and CO-999 get received to stock
  • A phantom job is created (jobnum PJ-1001) to make part XYZ-321, from CO-100 and CO-999. (any other parts? either from inventory or co-parts from other jobs?)
  • Issue CO-100 and CO-999 to job PJ-1001
  • Receive XYZ-321 to stock.

Yes that is the general idea.
Job 1234 only ever has qty of 1, though co-parts may be 1, 2 or more parts per, as defined by job method. In fact job 1234 is a strip job, making multiple component parts (the co-parts). Later in the process all the overhauled and reused co-parts are re-assembled in the assembly job, the overhauled assembly is returned to the customer on completion of the (re)assembly job. Co-parts could be either partnum/OH (overhauled), partnum/RE (reusable)or scrap, hence the need for updatable dashboard where user decides “work content” required for all the co-parts.
Hope this makes sense!