BPM works on second attempt, never on first

,

I’m working on a BPM that passes an RMA line’s serial number back to the related HDCase record. I’m using the RMAProc.CheckSerialNumbers method (Post-Processing). The first time I enter a serial number for an RMA line, nothing happens. But if I remove that serial number and try adding it again, it successfully adds that serial number to the HDCase record. Here is my code:

    using (System.Transactions.TransactionScope txScope = Erp.ErpContext.CreateDefaultTransactionScope())
    {
    string Serial;
    foreach (var ttSerialRow in ttSelectedSerialNumbers)
    {
    Ice.Diagnostics.Log.WriteEntry("Walrus Serial " + ttSerialRow.SerialNumber);
    Serial = ttSerialRow.SerialNumber;

    foreach (var ttRMArow in ttRMADtl.Where(ttRMA_row=>ttRMA_row.SysRowID == ttSerialRow.SourceRowID))
    {
    Ice.Diagnostics.Log.WriteEntry("Walrus RMA " + ttRMArow.RMANum);
    foreach (var HD_iterator in Db.HDCase.Where(HDCase_row=>HDCase_row.RMANum == ttRMArow.RMANum))
    {
    HD_iterator.SerialNumber = Serial;
    Ice.Diagnostics.Log.WriteEntry("Walrus Serial2 " + HD_iterator.SerialNumber);
    }

    }
    }
    Db.Validate();
    txScope.Complete();
    }

I would guess it has to do with the sysrowid. The first time it will be like 00000000000 or as a new record. Once you have added a serial number to the record I would bet an update occurs and the sysrowid get a real number.

Hmm I don’t know, the BPM does print to the trace log on the first attempt. I removed it later, but earlier I had a line printing SelectedSerialNumbers.SourceRowID (which is how I discovered I could link it to RMADtl, and then HDCase.) It did have a non-000000 SysRowID by the time I added a serial number to it.

did you put a message box in the code. to see where it is not running.

Yes I have. I added back the Log.WriteEntry line for the sysrowID (referred to as SourceRowID in ttSelectedSerialNumbers) and this is what was written to the log on my FIRST attempt:

<Op Utc="2017-12-05T19:50:21.4170723Z" act="Erp:BO:RMAProc/RMAProcSvcContract/CheckSerialNumbers" dur="24.0313" cli="172.17.2.115:53750" usr="lreynolds" machine="EPIC" pid="24960" tid="403">
  <IceAppServer msg="Walrus Serial TESTSERIAL" />
  <IceAppServer msg="Walrus RowID 23c70636-a1ac-498d-8e9c-a08cf71a4ebb" />
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTSERIAL" />
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTSERIAL" />
  <BpmCustomization Source="DB" BpMethodCode="Erp.HDCase" Type="In Transaction Trigger" Duration="0">
    <BpmDirective Type="InTrans" ID="ee400f43-f70d-42a2-921a-4ca852467964" Name="rmaTrans" VisibilityScope="0" Duration="0" />
  </BpmCustomization>
  <BpmCustomization Source="BO" BpMethodCode="Erp.RMAProc.CheckSerialNumbers" Type="BO Customization" Duration="12">
    <BpmDirective Type="PostProcessing" ID="887555d4-cfe6-4a4a-bef2-f12c606ad5bf" Name="lol" VisibilityScope="0" Duration="10" />
  </BpmCustomization>
</Op>

Note that the line titled “Walrus Serial2” is the HDCase.SerialNumber field. After this BPM fires, the serial number field in Case Entry is still blank, even after refreshing the form. Very confusing.

Writing the code like this does it work. I have had better luck with the scope closest to the actual change.

string Serial;
foreach (var ttSerialRow in ttSelectedSerialNumbers)
{
	Ice.Diagnostics.Log.WriteEntry("Walrus Serial " + ttSerialRow.SerialNumber);
	Serial = ttSerialRow.SerialNumber;

	foreach (var ttRMArow in ttRMADtl.Where(ttRMA_row=>ttRMA_row.SysRowID == ttSerialRow.SourceRowID))
	{
		Ice.Diagnostics.Log.WriteEntry("Walrus RMA " + ttRMArow.RMANum);
		using (System.Transactions.TransactionScope txScope = Erp.ErpContext.CreateDefaultTransactionScope())
		{

			foreach (var HD_iterator in Db.HDCase.Where(HDCase_row=>HDCase_row.RMANum == ttRMArow.RMANum))
			{
				HD_iterator.SerialNumber = Serial;
				Ice.Diagnostics.Log.WriteEntry("Walrus Serial2 " + HD_iterator.SerialNumber);
			}
			Db.Validate();
			txScope.Complete();
		
		}
	}
}

I replaced my code with yours and tried again. Same end result, with a slightly different structure to the log:

<Op Utc="2017-12-05T20:27:21.9083379Z" act="Erp:BO:RMAProc/RMAProcSvcContract/CheckSerialNumbers" dur="27.1635" cli="172.17.2.115:53750" usr="lreynolds" machine="EPIC" pid="24960" tid="54">
  <IceAppServer msg="Walrus Serial TESTINGSERIAL" />
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTINGSERIAL" />
  <BpmCustomization Source="DB" BpMethodCode="Erp.HDCase" Type="In Transaction Trigger" Duration="0">
    <BpmDirective Type="InTrans" ID="ee400f43-f70d-42a2-921a-4ca852467964" Name="rmaTrans" VisibilityScope="0" Duration="0" />
  </BpmCustomization>
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTINGSERIAL" />
  <BpmCustomization Source="BO" BpMethodCode="Erp.RMAProc.CheckSerialNumbers" Type="BO Customization" Duration="15">
    <BpmDirective Type="PostProcessing" ID="887555d4-cfe6-4a4a-bef2-f12c606ad5bf" Name="lol" VisibilityScope="0" Duration="13" />
  </BpmCustomization>
</Op>

messing around here.

how about this.

string Serial;
foreach (var ttSerialRow in ttSelectedSerialNumbers)
{
	Ice.Diagnostics.Log.WriteEntry("Walrus Serial " + ttSerialRow.SerialNumber);
	Serial = ttSerialRow.SerialNumber;

	foreach (var ttRMArow in ttRMADtl.Where(ttRMA_row=>ttRMA_row.SysRowID == ttSerialRow.SourceRowID))
{
	Ice.Diagnostics.Log.WriteEntry("Walrus RMA " + ttRMArow.RMANum);
	using (System.Transactions.TransactionScope txScope = Erp.ErpContext.CreateDefaultTransactionScope())
	{
			
		foreach (var HD_iterator in (from thisHDCase in Db.HDCase.With(LockHint.UpdLock) where thisHDCase.RMANum  == ttRMArow.RMANum))
		{
			HD_iterator.SerialNumber = Serial;
			Ice.Diagnostics.Log.WriteEntry("Walrus Serial2 " + HD_iterator.SerialNumber);
			Db.Validate();
		}
		
		txScope.Complete();
	
	}
}

}

Tried that too, same deal. First attempt’s log entry looked the same as last time, but I went ahead and entered the serial a second time, which worked, and here’s what that looks like:

<Op Utc="2017-12-05T21:39:24.4686257Z" act="Erp:BO:RMAProc/RMAProcSvcContract/CheckSerialNumbers" dur="12.6541" cli="172.17.2.115:60389" usr="lreynolds" machine="EPIC" pid="24960" tid="323">
  <IceAppServer msg="Walrus Serial TESTTEST" />
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTTEST" />
  <IceAppServer msg="Walrus Serial2 TESTTEST" />
  <IceAppServer msg="Walrus RMA 29040" />
  <IceAppServer msg="Walrus Serial2 TESTTEST" />
  <IceAppServer msg="Walrus Serial2 TESTTEST" />
  <BpmCustomization Source="BO" BpMethodCode="Erp.RMAProc.CheckSerialNumbers" Type="BO Customization" Duration="4">
    <BpmDirective Type="PostProcessing" ID="887555d4-cfe6-4a4a-bef2-f12c606ad5bf" Name="lol" VisibilityScope="0" Duration="4" />
  </BpmCustomization>
</Op>

It’s posting the HDCase serial number twice, and actually saves it to the DB. Does this signify something? Do we know why it’s sending another line on the second attempt?

turn on trace.

what is going on there? Is there something different with the dataset? datachanged.

Activated my user trace. I think this is the relevant section… Kind of hard to read :stuck_out_tongue:

<tracePacket>
  <businessObject>Erp.Proxy.BO.SelectedSerialNumbersImpl</businessObject>
  <methodName>CreateSerialNum</methodName>
  <appServerUri>net.tcp://epic/EpicorTest2/</appServerUri>
  <returnType>System.Void</returnType>
  <localTime>12/5/2017 15:48:08:3614394 PM</localTime>
  <executionTime>14</executionTime>
  <parameters>
    <parameter name="ds" type="SelectedSerialNumbersDataSet">
      <SelectedSerialNumbersDataSet xmlns="http://www.epicor.com/Ice/300/BO/SelectedSerialNumbers/SelectedSerialNumbers">
        <SNFormat>
          <Company>IBI</Company>
          <Plant>MfgSys</Plant>
          <PartNum>7310092</PartNum>
          <NumberOfDigits>0</NumberOfDigits>
          <SNMask></SNMask>
          <SNBaseDataType>CHARACTER</SNBaseDataType>
          <SNFormat>x(30)</SNFormat>
          <LeadingZeroes>false</LeadingZeroes>
          <SNPrefix></SNPrefix>
          <SNMaskSuffix></SNMaskSuffix>
          <SNMaskPrefix></SNMaskPrefix>
          <SNLastUsedSeq></SNLastUsedSeq>
          <HasSerialNumbers>false</HasSerialNumbers>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <BitFlag>0</BitFlag>
          <PartPricePerCode>E</PartPricePerCode>
          <PartTrackLots>false</PartTrackLots>
          <PartTrackSerialNum>true</PartTrackSerialNum>
          <PartTrackDimension>false</PartTrackDimension>
          <PartSalesUM>EA</PartSalesUM>
          <PartIUM>EA</PartIUM>
          <PartSellingFactor>1.00000000</PartSellingFactor>
          <PartPartDescription>Zoll X-Series Defib Masimo w/Pacing</PartPartDescription>
          <SerialMaskMaskType>0</SerialMaskMaskType>
          <SerialMaskMask></SerialMaskMask>
          <SerialMaskExample></SerialMaskExample>
          <SerialMaskDescription></SerialMaskDescription>
          <RowMod></RowMod>
        </SNFormat>
      </SelectedSerialNumbersDataSet>
    </parameter>
    <parameter name="PartNum" type="System.String"><![CDATA[7310092]]></parameter>
    <parameter name="xrefPartNum" type="System.String"><![CDATA[]]></parameter>
    <parameter name="xrefPartType" type="System.String"><![CDATA[]]></parameter>
    <parameter name="xrefCustNum" type="System.Int32"><![CDATA[0]]></parameter>
    <parameter name="baseSerialNum" type="System.String"><![CDATA[TESTING]]></parameter>
    <parameter name="SourceRowID" type="System.String"><![CDATA[150913ae-5706-43bd-8ae5-e6634cc5b85f]]></parameter>
    <parameter name="transType" type="System.String"><![CDATA[]]></parameter>
    <parameter name="plantID" type="System.String"><![CDATA[MfgSys]]></parameter>
    <parameter name="fullSerialNum" type="System.String"><![CDATA[]]></parameter>
  </parameters>
</tracePacket>

<tracePacket>
  <businessObject>Erp.Proxy.BO.SelectedSerialNumbersImpl</businessObject>
  <methodName>GetNextSN</methodName>
  <appServerUri>net.tcp://epic/EpicorTest2/</appServerUri>
  <returnType>System.Void</returnType>
  <localTime>12/5/2017 15:48:08:3784394 PM</localTime>
  <executionTime>10</executionTime>
  <parameters>
    <parameter name="ds" type="SelectedSerialNumbersDataSet">
      <SelectedSerialNumbersDataSet xmlns="http://www.epicor.com/Ice/300/BO/SelectedSerialNumbers/SelectedSerialNumbers">
        <SelectedSerialNumbers>
          <Company>IBI</Company>
          <SerialNumber>TESTING</SerialNumber>
          <Scrapped>false</Scrapped>
          <ScrappedReasonCode></ScrappedReasonCode>
          <Voided>false</Voided>
          <Reference></Reference>
          <ReasonCodeType></ReasonCodeType>
          <ReasonCodeDesc></ReasonCodeDesc>
          <PartNum>7310092</PartNum>
          <SNPrefix></SNPrefix>
          <SNBaseNumber>TESTING</SNBaseNumber>
          <SourceRowID>150913ae-5706-43bd-8ae5-e6634cc5b85f</SourceRowID>
          <TransType></TransType>
          <PassedInspection>false</PassedInspection>
          <Deselected>false</Deselected>
          <KitWhseList></KitWhseList>
          <RawSerialNum>TESTING</RawSerialNum>
          <KBLbrAction>0</KBLbrAction>
          <KBLbrActionDesc></KBLbrActionDesc>
          <PreventDeselect>false</PreventDeselect>
          <XRefPartNum></XRefPartNum>
          <XRefPartType></XRefPartType>
          <PreDeselected>false</PreDeselected>
          <poLinkValues></poLinkValues>
          <SNMask></SNMask>
          <NotSavedToDB>true</NotSavedToDB>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <RowMod>A</RowMod>
        </SelectedSerialNumbers>
        <SNFormat>
          <Company>IBI</Company>
          <Plant>MfgSys</Plant>
          <PartNum>7310092</PartNum>
          <NumberOfDigits>0</NumberOfDigits>
          <SNMask></SNMask>
          <SNBaseDataType>CHARACTER</SNBaseDataType>
          <SNFormat>x(30)</SNFormat>
          <LeadingZeroes>false</LeadingZeroes>
          <SNPrefix></SNPrefix>
          <SNMaskSuffix></SNMaskSuffix>
          <SNMaskPrefix></SNMaskPrefix>
          <SNLastUsedSeq></SNLastUsedSeq>
          <HasSerialNumbers>false</HasSerialNumbers>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <BitFlag>0</BitFlag>
          <PartPricePerCode>E</PartPricePerCode>
          <PartTrackLots>false</PartTrackLots>
          <PartTrackSerialNum>false</PartTrackSerialNum>
          <PartTrackDimension>false</PartTrackDimension>
          <PartSalesUM></PartSalesUM>
          <PartIUM></PartIUM>
          <PartSellingFactor>1</PartSellingFactor>
          <PartPartDescription></PartPartDescription>
          <SerialMaskMaskType>0</SerialMaskMaskType>
          <SerialMaskMask></SerialMaskMask>
          <SerialMaskExample></SerialMaskExample>
          <SerialMaskDescription></SerialMaskDescription>
          <RowMod></RowMod>
        </SNFormat>
      </SelectedSerialNumbersDataSet>
    </parameter>
    <parameter name="snPartNum" type="System.String"><![CDATA[7310092]]></parameter>
    <parameter name="xrefPartNum" type="System.String"><![CDATA[]]></parameter>
    <parameter name="xrefPartType" type="System.String"><![CDATA[]]></parameter>
    <parameter name="xrefCustNum" type="System.Int32"><![CDATA[0]]></parameter>
    <parameter name="plantID" type="System.String"><![CDATA[MfgSys]]></parameter>
    <parameter name="nextBaseSN" type="System.String"><![CDATA[]]></parameter>
    <parameter name="snPrefix" type="System.String"><![CDATA[]]></parameter>
    <parameter name="nextFullSN" type="System.String"><![CDATA[]]></parameter>
    <parameter name="snCounterMax" type="System.Boolean"><![CDATA[False]]></parameter>
  </parameters>
  <paramDataSetChanges>
    <paramDataSet name="ds" useDataSetNbr="0">
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="Company"><![CDATA[IBI]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SerialNumber"><![CDATA[TESTING]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="Scrapped"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="ScrappedReasonCode"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="Voided"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="Reference"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="ReasonCodeType"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="ReasonCodeDesc"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="PartNum"><![CDATA[7310092]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SNPrefix"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SNBaseNumber"><![CDATA[TESTING]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SourceRowID"><![CDATA[150913ae-5706-43bd-8ae5-e6634cc5b85f]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="TransType"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="PassedInspection"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="Deselected"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="KitWhseList"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="RawSerialNum"><![CDATA[TESTING]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="KBLbrAction"><![CDATA[0]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="KBLbrActionDesc"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="PreventDeselect"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="XRefPartNum"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="XRefPartType"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="PreDeselected"><![CDATA[False]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="poLinkValues"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SNMask"><![CDATA[]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="NotSavedToDB"><![CDATA[True]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="SysRowID"><![CDATA[00000000-0000-0000-0000-000000000000]]></changedValue>
      <changedValue tableName="SelectedSerialNumbers" rowState="Added" rowNum="0" colName="RowMod"><![CDATA[A]]></changedValue>
    </paramDataSet>
  </paramDataSetChanges>
</tracePacket>

Thinking out loud here.

This might be better to put the BPM on the update of the RMA. That way you aren’t updating the HDCase on each serial number change, just when the RMA is updated.

Just tried it as an Update post-proc, no noticeable difference there either. This thing’s pretty persistent!

what about a Update pre proc?

Same results. Is there a way to make this BPM automatically run twice? If I can just automate that then it might work as intended.

put the code on the update. Run a trace. attach the full log. There has to be something we are overlooking.

There is no other action in the BPM, just the code.

TraceData.txt (344.1 KB)
Okay, here’s the full log after testing the pre-processing one again. And no, there is only the “Execute Custom Code” block in the BPM.

How about something this? This code is not fully tested.

string Serial;
foreach (var ttSerialRow in ttSelectedSerialNumbers)
{
	Ice.Diagnostics.Log.WriteEntry("Walrus Serial " + ttSerialRow.SerialNumber);
	Serial = ttSerialRow.SerialNumber;

	var ttRMArow = ttRMADtl.Where(tt=>tt.SysRowID == ttSerialRow.SourceRowID).FirstOrDefault();
	
	if(ttRMArow != null)
	{
		Ice.Diagnostics.Log.WriteEntry("Walrus RMA " + ttRMArow.RMANum);
		
		var ttRMAHeadrow = RMAHead.Where(tt=>tt.RMANum== ttRMArow.RMANum).FirstOrDefault();
		if(ttRMAHeadrow != null)
		{
			using (System.Transactions.TransactionScope txScope = Erp.ErpContext.CreateDefaultTransactionScope())
			{
					
				var HD_iterator = Db.HDCase.Where(tt=>tt.HDCaseNum== ttRMAHeadrow.HDCaseNum).FirstOrDefault();
				
				if(HD_iterator != null)
				{
					HD_iterator.SerialNumber = Serial;
					Ice.Diagnostics.Log.WriteEntry("Walrus Serial2 " + HD_iterator.SerialNumber);
					Db.Validate();
				}
				
				txScope.Complete();
			
			}
		}
	}
}

It cuts out somewhere after the “Walrus RMA” log entry, seen below:

<IceAppServer msg="Walrus Serial TESTINGBPM" />
  <IceAppServer msg="Walrus RMA 29042" />
  <BpmCustomization Source="BO" BpMethodCode="Erp.RMAProc.Update" Type="BO Customization" Duration="0">
    <BpmDirective Type="PreProcessing" ID="54b77494-1df1-4a4a-8d8a-7a014627f735" Name="lol" VisibilityScope="0" Duration="0" />
  </BpmCustomization>

now try this.

string Serial;
foreach (var ttSerialRow in ttSelectedSerialNumbers)
{
	Ice.Diagnostics.Log.WriteEntry("Walrus Serial " + ttSerialRow.SerialNumber);
	Serial = ttSerialRow.SerialNumber;

	var ttRMArow = ttRMADtl.Where(tt=>tt.SysRowID == ttSerialRow.SourceRowID).FirstOrDefault();
	
	if(ttRMArow != null)
	{
		Ice.Diagnostics.Log.WriteEntry("Walrus RMA " + ttRMArow.RMANum);
		
		var ttRMAHeadrow = Db.RMAHead.Where(tt=>tt.RMANum== ttRMArow.RMANum).FirstOrDefault();
		if(ttRMAHeadrow != null)
		{
			using (System.Transactions.TransactionScope txScope = Erp.ErpContext.CreateDefaultTransactionScope())
			{
					
				var HD_iterator = Db.HDCase.Where(tt=>tt.HDCaseNum== ttRMAHeadrow.HDCaseNum).FirstOrDefault();
				
				if(HD_iterator != null)
				{
					HD_iterator.SerialNumber = Serial;
					Ice.Diagnostics.Log.WriteEntry("Walrus Serial2 " + HD_iterator.SerialNumber);
					Db.Validate();
				}
				
				txScope.Complete();
			
			}
		}
	}
}