InventoryTransfer BPM to write to a UD field between FromBin to ToBin

Environment: ERP 10.2.100.32

I’ve been struggling with this for a few days.
The end goal I have is that I have a UD field PartBin.scPartialJobNum_c for the FromBin in Inventory Transfer that needs to be carried over to the ToBin for partials. A Bin always starts with a “P” for partials.

I believe the issue I am running in to is that the ToBin does not exist for me to write to the ToBin.scPartialJobNum_c.

Code

/*
Directive Name: UpdateToBinPartialJobNum(PRE)
Method: InvTransfer.CommitTransfer
Pre-Processing
*/
Erp.Tables.PartBin FromPartBin;
                       
var ttInvTrans_xRow = (from ttInvTrans_Row in ttInvTrans
                       where ttInvTrans_Row.Company == Session.CompanyID
                       select ttInvTrans_Row).LastOrDefault();
  
if(!ttInvTrans_xRow.FromBinNum.ToString().StartsWith("P")){return;}

FromPartBin = (from PartBin_Row in Db.PartBin
           where PartBin_Row.Company == ttInvTrans_xRow.Company 
           && PartBin_Row.PartNum == ttInvTrans_xRow.PartNum 
           && PartBin_Row.LotNum == ttInvTrans_xRow.FromLotNumber 
           && PartBin_Row.BinNum == ttInvTrans_xRow.FromBinNum
           select PartBin_Row).FirstOrDefault(); 

if (FromPartBin == null){return;}

callContextBpmData.ShortChar01 = ttInvTrans_xRow.PartNum.ToString();
callContextBpmData.ShortChar02 = ttInvTrans_xRow.FromBinNum.ToString();
callContextBpmData.ShortChar03 = ttInvTrans_xRow.ToBinNum.ToString();
callContextBpmData.ShortChar04 = FromPartBin.scPartialJobNum_c.ToString();
callContextBpmData.ShortChar05 = ttInvTrans_xRow.ToWarehouseCode.ToString();
/*
Directive Name: UpdateToBinPartialJobNum(POST)
Method: InvTransfer.CommitTransfer
Post-Processing
*/

Erp.Tables.PartBin ToPartBin;

string strPartNum = callContextBpmData.ShortChar01;
string strFromBin = callContextBpmData.ShortChar02;
string strToBin = callContextBpmData.ShortChar03;
string strPartialJobNum = callContextBpmData.ShortChar04;
string strToWarehouseCode = callContextBpmData.ShortChar05;

//this.PublishInfoMessage("POST:" + strPartNum +
//                        "\n\r"  + strFromBin + 
//                        "\n\r" + strToBin + 
//                        "\n\r" + strPartialJobNum + 
//						  "\n\r" + strToWarehouseCode,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
//

foreach (var ttInvTrans_iterator in (from ttInvTrans_Row in ttInvTrans
                                     where string.Compare(ttInvTrans_Row.ToBinNum, strToBin, true) == 0
                                     && ttInvTrans_Row.ToBinNum.StartsWith("P")
                                     select ttInvTrans_Row)) 
{
   var ttInvTrans_xRow = ttInvTrans_iterator;
   ToPartBin = (from PartBin_Row in Db.PartBin
                where PartBin_Row.Company == ttInvTrans_xRow.Company 
                && PartBin_Row.PartNum == strPartNum 
                && PartBin_Row.WarehouseCode == strToWarehouseCode
                && PartBin_Row.BinNum == strToBin
                select PartBin_Row).FirstOrDefault();
   
    if (ToPartBin == null){return;}
    ToPartBin.scPartialJobNum_c = strPartialJobNum; 
}

I have tested that the Pre is passing to POST correctly, just can not get the ToBin.scPartialJobNum_c written to.

Any help will be appreciated.

Those string comparison (such as PartBin_Row.PartNum == strParNum) never worked for me.

Try replacing the string comparison to:
string.Compare(PartBin_Row.PartNum, strPartNum, true) == 0

The issue might be that the Partbin is never found and always returns null.To test this, use the messagebox popup to show something from parbin at the post.

Example - this would return bin number instead of return.
this.PublishInfoMessage(ToPartBin.BinNum,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");

Thanks for your reply.

Changed POST code to the following

/*
Directive Name: UpdateToBinPartialJobNum
Method: InvTransfer.PreCommitTransfer
Post-Processing
*/

Erp.Tables.PartBin ToPartBin;

string strPartNum = callContextBpmData.ShortChar01;
string strFromBin = callContextBpmData.ShortChar02;
string strToBin = callContextBpmData.ShortChar03;
string strPartialJobNum = callContextBpmData.ShortChar04;
string strToWarehouseCode = callContextBpmData.ShortChar05;

//this.PublishInfoMessage("POST:" + strPartNum +
//                        "\n\r"  + strFromBin + 
//                        "\n\r" + strToBin + 
//                        "\n\r" + strPartialJobNum,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
//

foreach (var ttInvTrans_iterator in (from ttInvTrans_Row in ttInvTrans
                                     where string.Compare(ttInvTrans_Row.ToBinNum, strToBin, true) == 0
                                     && ttInvTrans_Row.ToBinNum.StartsWith("P")
                                     select ttInvTrans_Row)) 
{
   var ttInvTrans_xRow = ttInvTrans_iterator;
   ToPartBin = (from PartBin_Row in Db.PartBin
                where string.Compare(PartBin_Row.Company, ttInvTrans_xRow.Company, true) == 0
                && string.Compare(PartBin_Row.PartNum, strPartNum, true) == 0                
                && string.Compare(PartBin_Row.WarehouseCode, strToWarehouseCode, true) == 0  
                && string.Compare(PartBin_Row.BinNum, strToBin, true) == 0                   
                select PartBin_Row).FirstOrDefault();
   
    if (ToPartBin == null){return;}
    this.PublishInfoMessage("POST After ToPartBin Null:" + ToPartBin.PartNum +
                              "\n\r" + ToPartBin.BinNum + 
                              "\n\r" + ToPartBin.scPartialJobNum_c,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
    ToPartBin.scPartialJobNum_c = strPartialJobNum; 
}

I had the POST After ToPartBin Null InfoMessage in the code already, just removed it for clarity in the original post. Which lead to the following.

I believe the issue I am running in to is that the ToBin does not exist for me to write to the ToBin.scPartialJobNum_c.

I guess the main issue is how do I write to the ToBin?

Your original code should work```
ToPartBin.scPartialJobNum_c = strPartialJobNum;

Sometimes I have to put a brackets, like this
 ToPartBin["scPartialJobNum_c"] = strPartialJobNum;

Thank you for your reply.

The code will not get past the

if (ToPartBin == null){return;}

So the code will not get to that code.

I see that the code is passing the ToBinNum in a code trace and I see the POST is receiving ToBinNum.

But I can’t see the code get past the

if (ToPartBin == null){return;}

@wi11king777 If you are passing in all the data you need to write then just lookup the bin and update. The offical way to update a ud is using SetUDField. Try this to see if it gets any closer.

/*
Directive Name: UpdateToBinPartialJobNum(POST)
Method: InvTransfer.CommitTransfer
Post-Processing
*/

//Erp.Tables.PartBin ToPartBin;

string strPartNum = callContextBpmData.ShortChar01;
string strFromBin = callContextBpmData.ShortChar02;
string strToBin = callContextBpmData.ShortChar03;
string strPartialJobNum = callContextBpmData.ShortChar04;
string strToWarehouseCode = callContextBpmData.ShortChar05;

//this.PublishInfoMessage("POST:" + strPartNum +
//                        "\n\r"  + strFromBin + 
//                        "\n\r" + strToBin + 
//                        "\n\r" + strPartialJobNum + 
//						  "\n\r" + strToWarehouseCode,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
//


   var ToPartBin = Db.PartBin.Where(PartBin_Row => PartBin_Row.Company == Session.CompanyID 
                && PartBin_Row.PartNum == strPartNum 
                && PartBin_Row.WarehouseCode == strToWarehouseCode
                && PartBin_Row.BinNum == strToBin).FirstOrDefault();
   
    if (ToPartBin != null)
    {
    	ToPartBin.SetUDField<string>("scPartialJobNum_c",strPartialJobNum); 
    }


1 Like

If you’re going to update the database directly like that, I believe you have to enclose the code in a Transaction Scope and throw in a Db.Validate().

However, I don’t recommend that – it would be better to do updates through the Business Objects. Since you’re updating a UD field it’s not as important, but it’s good to get in the habit of going through the BOs.

1 Like

Thanks for your reply

I added your code and put in an InfoBox to see if it gets past the null.

string strPartNum = callContextBpmData.ShortChar01;
string strFromBin = callContextBpmData.ShortChar02;
string strToBin = callContextBpmData.ShortChar03;
string strPartialJobNum = callContextBpmData.ShortChar04;
string strToWarehouseCode = callContextBpmData.ShortChar05;

//this.PublishInfoMessage("POST:" + strPartNum +
//                        "\n\r"  + strFromBin + 
//                        "\n\r" + strToBin + 
//                        "\n\r" + strPartialJobNum,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
//

var ToPartBin = Db.PartBin.Where(PartBin_Row => PartBin_Row.Company == Session.CompanyID 
             && PartBin_Row.PartNum == strPartNum 
             && PartBin_Row.WarehouseCode == strToWarehouseCode
             && PartBin_Row.BinNum == strToBin).FirstOrDefault();

if (ToPartBin != null)
{
  this.PublishInfoMessage("POST After ToPartBin Null:" + ToPartBin.PartNum +
                          "\n\r" + ToPartBin.BinNum + 
                          "\n\r" + ToPartBin.scPartialJobNum_c,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
  ToPartBin.SetUDField<string>("scPartialJobNum_c",strPartialJobNum); 
}

The Infobox POST After ToPartBin Null did not show up when I tested.

Update to the problem:
After further testing, I have found out that if I InvXfr to a ToBin that already exists for the part the scPartialJobNum_c will be populated. However, if I InvXfr to a ToBin that does not exist for the part the scPartialJobNum_c will not be populated.

I feel that I am trying to write to ToBin before the system has created it. I thought that adding it to the InvTransfer.CommitTransfer (Post-Processing) would have the ToBin created so I could write to it.
Still, it is nulled so nothing happens.

@wi11king777 Go back and look at the trace again to see if there other processes that happen later that you could use. The context data will still be the same you just have to get past the bin getting created.

Looking at the trace of the Inventory Transfer, the next methods are GetList and GetTransferRecord. Both methods have no information about BIN’s

<tracePacket>
  <businessObject>Erp.Proxy.BO.InvTransferImpl</businessObject>
  <methodName>CommitTransfer</methodName>
  <appServerUri>net.tcp://taf2k16epc-test/ERP102100/</appServerUri>
  <returnType>System.Void</returnType>
  <localTime>9/14/2021 14:51:59:2251721 PM</localTime>
  <threadID>1</threadID>
  <executionTime total="289" roundTrip="287" channel="0" bpm="0" other="2" />
  <retries>0</retries>
  <parameters>
    <parameter name="ds" type="Erp.BO.InvTransferDataSet">
      <InvTransferDataSet xmlns="http://www.epicor.com/Ice/300/BO/InvTransfer/InvTransfer">
        <InvTrans>
          <Company>----</Company>
          <TranDate>2021-09-14T00:00:00-05:00</TranDate>
          <FromWarehouseCode>BG</FromWarehouseCode>
          <FromWarehouseDesc>Bowling Green</FromWarehouseDesc>
          <ToWarehouseCode>BG</ToWarehouseCode>
          <ToWarehouseDesc>Bowling Green</ToWarehouseDesc>
          <FromBinNum>P101</FromBinNum>
          <FromBinDesc>P101</FromBinDesc>
          <ToBinNum>P103</ToBinNum>
          <ToBinDesc>P103</ToBinDesc>
          <FromLotNumber></FromLotNumber>
          <ToLotNumber></ToLotNumber>
          <FromOnHandQty>1.00000000</FromOnHandQty>
          <ToOnHandQty>0</ToOnHandQty>
          <Plant>MfgSys</Plant>
          <Plant2>MfgSys</Plant2>
          <PartNum>001113A422N</PartNum>
          <TrackDimension>false</TrackDimension>
          <TrackSerialnumbers>false</TrackSerialnumbers>
          <TrackLots>false</TrackLots>
          <PartDescription>M5-0.8 X 8 PHIL PAN WASH HD MS</PartDescription>
          <SearchWord>M50PNW</SearchWord>
          <TranReference></TranReference>
          <FromPlant>MfgSys</FromPlant>
          <FromPlantTracking>false</FromPlantTracking>
          <ToPlant>MfgSys</ToPlant>
          <ToPlantTracking>false</ToPlantTracking>
          <FromOnHandUOM>K</FromOnHandUOM>
          <TransferQty>1.000</TransferQty>
          <TransferQtyUOM>K</TransferQtyUOM>
          <ToOnHandUOM>K</ToOnHandUOM>
          <TrackingUOM>K</TrackingUOM>
          <TrackingQty>1.000</TrackingQty>
          <TranDocTypeID></TranDocTypeID>
          <ToOrderNum>0</ToOrderNum>
          <ToOrderLine>0</ToOrderLine>
          <ToOrderRelNum>0</ToOrderRelNum>
          <PCID></PCID>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <RowMod>U</RowMod>
        </InvTrans>
      </InvTransferDataSet>
    </parameter>
    <parameter name="LegalNumberMessage" type="System.String"><![CDATA[]]></parameter>
    <parameter name="partTranPKs" type="System.String"><![CDATA[]]></parameter>
  </parameters>
  <paramDataSetChanges>
    <paramDataSet name="ds" useDataSetNbr="0" />
  </paramDataSetChanges>
</tracePacket>

<tracePacket>
  <businessObject>Erp.Proxy.BO.PartImpl</businessObject>
  <methodName>GetList</methodName>
  <appServerUri>net.tcp://taf2k16epc-test/ERP102100/</appServerUri>
  <returnType>Erp.Tablesets.PartListTableset</returnType>
  <localTime>9/14/2021 14:51:59:5151697 PM</localTime>
  <threadID>1</threadID>
  <executionTime total="9" roundTrip="5" channel="2" bpm="0" other="2" />
  <retries>0</retries>
  <parameters>
    <parameter name="whereClause" type="System.String"><![CDATA[PartNum='001113A422N']]></parameter>
    <parameter name="pageSize" type="System.Int32"><![CDATA[0]]></parameter>
    <parameter name="absolutePage" type="System.Int32"><![CDATA[0]]></parameter>
    <parameter name="morePages" type="System.Boolean"><![CDATA[False]]></parameter>
  </parameters>
</tracePacket>

<tracePacket>
  <businessObject>Erp.Proxy.BO.InvTransferImpl</businessObject>
  <methodName>GetTransferRecord</methodName>
  <appServerUri>net.tcp://taf2k16epc-test/ERP102100/</appServerUri>
  <returnType>Erp.Tablesets.InvTransferTableset</returnType>
  <localTime>9/14/2021 14:51:59:5251700 PM</localTime>
  <threadID>1</threadID>
  <executionTime total="11" roundTrip="10" channel="0" bpm="0" other="1" />
  <retries>0</retries>
  <parameters>
    <parameter name="iPartNum" type="System.String"><![CDATA[001113A422N]]></parameter>
    <parameter name="uomCode" type="System.String"><![CDATA[]]></parameter>
  </parameters>
</tracePacket>

Testing, I added the following code to GetTransferRecord

Erp.Tables.PartBin FromPartBin;
                       
var ttInvTrans_xRow = (from ttInvTrans_Row in ttInvTrans
                       where ttInvTrans_Row.Company == Session.CompanyID
                       select ttInvTrans_Row).LastOrDefault();

this.PublishInfoMessage("PRE: Message0",Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
if(ttInvTrans_xRow == null){return;}
this.PublishInfoMessage("PRE: Message2",Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
if(!ttInvTrans_xRow.FromBinNum.ToString().StartsWith("P")){return;}
this.PublishInfoMessage("PRE: Message3",Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");

FromPartBin = (from PartBin_Row in Db.PartBin
           where PartBin_Row.Company == ttInvTrans_xRow.Company 
           && PartBin_Row.PartNum == ttInvTrans_xRow.PartNum 
           && PartBin_Row.LotNum == ttInvTrans_xRow.FromLotNumber 
           && PartBin_Row.BinNum == ttInvTrans_xRow.FromBinNum
           select PartBin_Row).FirstOrDefault(); 
this.PublishInfoMessage("PRE: Message4",Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
if (FromPartBin == null){return;}
this.PublishInfoMessage("PRE: Message5",Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");
callContextBpmData.ShortChar01 = ttInvTrans_xRow.PartNum.ToString();
callContextBpmData.ShortChar02 = ttInvTrans_xRow.FromBinNum.ToString();
callContextBpmData.ShortChar03 = ttInvTrans_xRow.ToBinNum.ToString();
callContextBpmData.ShortChar04 = FromPartBin.scPartialJobNum_c.ToString();
callContextBpmData.ShortChar05 = ttInvTrans_xRow.ToWarehouseCode.ToString();


this.PublishInfoMessage("PRE:" + callContextBpmData.ShortChar01 +
                        "\n\r" + callContextBpmData.ShortChar02 + 
                        "\n\r" + callContextBpmData.ShortChar03 + 
                        "\n\r" + callContextBpmData.ShortChar04 + 
                        "\n\r" + callContextBpmData.ShortChar05,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");

Message0 was the only InfoBox that showed.

From the trace, you can see that the last method that has Bin is CommitTransfer

@wi11king777 You don’t need bins or that foreach you already saved that in the callcontext.
You just need the bin to exist, so you can do the update.

How do I connect the CommitTransfer(PRE) to the GetTransferRecord(POST) to get the callContextBpmData?

@wi11king777 They are in the same call so the callcontext data should be there. I would check in post that one of your variables is not string.Empty and then run the code I posted.

Probably a good idea to reset all of your variables back to string.Empty after you re done.

@gpayne Thanks for your help

Finished code

/*
Directive Name: UpdateToBinPartialJobNum(PRE)
Method: InvTransfer.CommitTransfer
Group: Shipping
Pre-Processing
Menu:
  Mtl Mgt/Inv Mgt/GenOps/InvTransfer
  HandHeld Menu --> 3. Material Handling --> 2. Inventory Process --> 3.MoveInventory
Notes:
  Ticket 1960: Transfer partial in InvXfr
  Works in tandem with InvTransfer.GetTransferRecord/UpdateToBinPartialJobNum(POST)  
Developer:
  Will King
Updated:
  09/15/2021
*/

Erp.Tables.PartBin FromPartBin;
                       
var ttInvTrans_xRow = (from ttInvTrans_Row in ttInvTrans
                       where ttInvTrans_Row.Company == Session.CompanyID                       
                       select ttInvTrans_Row).LastOrDefault();
  
if(!ttInvTrans_xRow.FromBinNum.ToString().StartsWith("P")){return;}

FromPartBin = (from PartBin_Row in Db.PartBin
               where string.Compare(PartBin_Row.Company, ttInvTrans_xRow.Company, true) == 0
               && string.Compare(PartBin_Row.PartNum, ttInvTrans_xRow.PartNum, true) == 0                
               && string.Compare(PartBin_Row.WarehouseCode, ttInvTrans_xRow.FromWarehouseCode, true) == 0
               && string.Compare(PartBin_Row.LotNum, ttInvTrans_xRow.FromLotNumber, true) == 0                 
               && string.Compare(PartBin_Row.BinNum, ttInvTrans_xRow.FromBinNum, true) == 0                
               select PartBin_Row).FirstOrDefault(); 

if (FromPartBin == null){return;}

callContextBpmData.ShortChar01 = ttInvTrans_xRow.PartNum.ToString();
callContextBpmData.ShortChar02 = ttInvTrans_xRow.FromBinNum.ToString();
callContextBpmData.ShortChar03 = ttInvTrans_xRow.ToBinNum.ToString();
callContextBpmData.ShortChar04 = FromPartBin.scPartialJobNum_c.ToString();
callContextBpmData.ShortChar05 = ttInvTrans_xRow.ToWarehouseCode.ToString();
/*
Directive Name: UpdateToBinPartialJobNum(POST)
Method: InvTransfer.GetTransferRecord
Group: Shipping
Post-Processing
Menu Location: 
  Mtl Mgt/Inv Mgt/GenOps/InvTransfer
  HandHeld Menu --> 3. Material Handling --> 2. Inventory Process --> 3.MoveInventory
Notes:
  Ticket 1960: Transfer partial in InvXfr
  Works in tandem with InvTransfer.CommitTransfer/UpdateToBinPartialJobNum(PRE) 
Developer:
  Will King
Date Last Updated:
  09/15/2021
*/
string strPartNum = callContextBpmData.ShortChar01;
string strFromBin = callContextBpmData.ShortChar02;
string strToBin = callContextBpmData.ShortChar03;
string strPartialJobNum = callContextBpmData.ShortChar04;
string strToWarehouseCode = callContextBpmData.ShortChar05;

//this.PublishInfoMessage("POST:" + strPartNum +
//                        "\n\r"  + strFromBin + 
//                        "\n\r" + strToBin + 
//                        "\n\r" + strPartialJobNum,Ice.Common.BusinessObjectMessageType.Information,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","Method");


var ToPartBin = Db.PartBin.Where(PartBin_Row => PartBin_Row.Company == Session.CompanyID 
             && PartBin_Row.PartNum == strPartNum 
             && PartBin_Row.WarehouseCode == strToWarehouseCode
             && PartBin_Row.BinNum == strToBin).FirstOrDefault();

 if (ToPartBin != null)
 {
   ToPartBin.SetUDField<string>("scPartialJobNum_c",strPartialJobNum); 
 }
 
callContextBpmData.ShortChar01 = string.Empty;
callContextBpmData.ShortChar02 = string.Empty;
callContextBpmData.ShortChar03 = string.Empty;
callContextBpmData.ShortChar04 = string.Empty;
callContextBpmData.ShortChar05 = string.Empty;