Remove Hold not triggering addition to Hold History (BPM Custom Code)


Hello All!
I am working on automatic BPM hold creation and removal for jobs with non-conforming sub-assemblies. I am at the part where I would like to have a Hold be released when the entire Non-Conf qty is deemed good and can return to the job from the inspection module.

The issue comes when I am trying to remove the hold from the Job. I can get the data set, update the BpHoldAttachment.RowMod to “D” then call the bpHold Service update method to remove the hold, but this is not triggering the addition of that hold to the BpHoldAttachHist.

I wanted to know if I am missing a statement, or if I should be using a different approach to remove this hold…

Now, on to the fun part!

In Erp.InspProcessing.InspectOperation / Pre-Processing


In the custom code section:

  using(Ice.Contracts.BpHoldsSvcContract bpHoldSrvc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.BpHoldsSvcContract>(Db))
    string whereClauseBpHoldType = string.Format("HoldTypeID = '{0}' and ClassName = 'JobEntry' and SystemCode = 'ERP' BY HoldTypeID", HoldType);
    string whereClauseBpHoldAttachHist = string.Empty;
    string whereClauseBpHoldAttachment = string.Format("HoldSysRowID = '{0}'", activeHold.HoldSysRowID);
    int pageSize = 100;
    int absolutePage = 0;
    bool morePages = false;
    Ice.Tablesets.BpHoldsTableset bpHoldDs = null;
      bpHoldDs = bpHoldSrvc.GetRows(whereClauseBpHoldType, whereClauseBpHoldAttachHist, whereClauseBpHoldAttachment, pageSize, absolutePage, out morePages);
    catch(Exception x)
      throw new Ice.BLException(x.Message);
    if(bpHoldDs == null)
    bpHoldDs .BpHoldAttachment[0].SetRowState(IceRowState.Deleted);
    bpHoldSrvc.Update(ref bpHoldDs );

using this method, I am showing gaps in my history…

I haven’t tried the drag and drop Invoke BO Methods, but I would really love to know why this wouldn’t trigger the same triggers as deleting the hold from the BPM Holds screen.

Thank you!



I decided to test the UpdateExt method to see if it delete the hold and create the history. and it did.

    Ice.Tablesets.UpdExtBpHoldsTableset bpHoldUpdDs = new Ice.Tablesets.UpdExtBpHoldsTableset();
    Ice.Tablesets.BpHoldAttachmentRow bpHoldAtchRow = new Ice.Tablesets.BpHoldAttachmentRow(){
        Comment = bpHoldDs.BpHoldAttachment[0].Comment,
        Company = bpHoldDs.BpHoldAttachment[0].Company,
        CreatedOn = bpHoldDs.BpHoldAttachment[0].CreatedOn,
        CreateUserID = bpHoldDs.BpHoldAttachment[0].CreateUserID,
        HoldAttachID = bpHoldDs.BpHoldAttachment[0].HoldAttachID,
        HoldSysRowID = bpHoldDs.BpHoldAttachment[0].HoldSysRowID,
        HoldTypeID = bpHoldDs.BpHoldAttachment[0].HoldTypeID,
        SysRowID = bpHoldDs.BpHoldAttachment[0].SysRowID,
        SysRevID = bpHoldDs.BpHoldAttachment[0].SysRevID


    Ice.Tablesets.BpHoldTypeRow bpHoldTypeRow = new Ice.Tablesets.BpHoldTypeRow(){
        ClassName = bpHoldDs.BpHoldType[0].ClassName,
        Company = bpHoldDs.BpHoldType[0].Company,
        DataTableID = bpHoldDs.BpHoldType[0].DataTableID,
        Description = bpHoldDs.BpHoldType[0].Description,
        HistoryLength = bpHoldDs.BpHoldType[0].HistoryLength,
        HoldTypeID = bpHoldDs.BpHoldType[0].HoldTypeID,
        ObjectNS = bpHoldDs.BpHoldType[0].ObjectNS,
        SysRowID = bpHoldDs.BpHoldType[0].SysRowID,
        SystemCode = bpHoldDs.BpHoldType[0].SystemCode,
        SystemFlag = bpHoldDs.BpHoldType[0].SystemFlag

    bool errorsOccurred = false;
    Ice.BOUpdErrorTableset rtn = bpHoldSrvc.UpdateExt(ref bpHoldUpdDs, false,true,out errorsOccurred);
    BpmContext.BpmData.Checkbox01 = errorsOccurred;
      BpmContext.BpmData.Character01 = rtn.BOUpdError[0].ErrorText;

This achieved my goal, but I am curious if there isn’t a way to have the Update method trigger the addition of hold history.

I wish I had my old BPM code to show you, but I can only seem to find my Client customization code that adds/removes lot holds. Perhaps it will be illuminating

Add hold:

private void PerformAttachment(string holdType, Guid sysRowID, string lotNum)
		BpHoldsAdapter adapterBpHolds = new BpHoldsAdapter(oTrans);

		//check for existing holds of the same type
		foreach(DataRow dr in adapterBpHolds.BpHoldsData.BpHoldAttachment)
				MessageBox.Show(String.Format("Hold Type {0} already exists on  Lot {1}!", dr["HoldTypeID"].ToString(), lotNum));
		int rowCount = adapterBpHolds.BpHoldsData.BpHoldAttachment.Rows.Count;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].Company = oTrans.CoreSession.CompanyID.ToString();								
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].HoldTypeID = holdType;								
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].HoldAttachID = 0;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].CreateUserID = oTrans.CoreSession.UserID.ToString();						
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].CreatedOn = System.DateTime.Now;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].Comment = String.Format("Hold {0}: From Dashboard", holdType);
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].HoldSysRowID = sysRowID;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].SysRowID = Guid.Empty;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].BitFlag = 0;
		adapterBpHolds.BpHoldsData.BpHoldAttachment[rowCount-1].RowMod = "A";		

Remove Hold:

private void btnRemove_Click(object sender, System.EventArgs args)
		// ** Place Event Handling Code Here **
		//check at least one marked row.
		int check = 0;
		foreach (UltraGridRow selectedRow in grdLots.Rows)
			if((bool)selectedRow.Cells["Select"].Value == true){ 	
		//this removes the specific hold to the records selected
				string holdType = cmbHoldType.Value.ToString();
				//call BPHolds Adapter
				BpHoldsAdapter adapterBpHolds = new BpHoldsAdapter(oTrans);
				List<DataRow> rowsToRemove = new List<DataRow>();
				List<Guid> markedRows = new List<Guid>();	
				Guid sysRowID = Guid.Empty;
				Guid holdSysRowID = Guid.Empty;
				//loop thru lots grid and grab sysRowIDs
				foreach (UltraGridRow selectedRow in grdLots.Rows)
					if((bool)selectedRow.Cells["Select"].Value == true)
						//MessageBox.Show("Adding Row to markedRows");						
				foreach(DataRow dr in adapterBpHolds.BpHoldsData.BpHoldAttachment.Rows)
					holdSysRowID = (Guid)dr["HoldSysRowID"];
					foreach(Guid markedRow in markedRows)
						if(holdSysRowID == markedRow)
							//MessageBox.Show("Match Found between data and list");					
				//removal loop	
				foreach(DataRow drDelete in rowsToRemove)
			catch(Exception ex){
				MessageBox.Show(ex.Message + "\r\n"+ ex.InnerException);
			MessageBox.Show("No Rows Selected!");


Thanks for the sample code. It looks like we’re doing roughly the same thing. Does your customization trigger the archiving of the hold?

Yes it does. I think it needed to be called in a certain way in order to add the record (automatically) to the hold history table though, so that’s why it’s pretty vanilla in how the adapter is being called

hmm, I’ll have to do some more snooping around the forums. I’m calling it as I saw in the tracing, so I’m sure there is some special sauce I need to sprinkle on this code.