BPM to Ship All from Bin

So, I have a request from the users to be able to enter a single bin number and ship everything that has a LEFT(LotNum,6) == OrderNum.

I traced the data and I’m trying to loop through each item in the bin and add the line to the shipment.
The first line adds fine, but any subsequent ones fail with and Object Ref error.
It seems to error out on the shipBO.GetNewOrdrShipDtl method.
I’ve tried so many variations, I can’t remember them all.
Anyone know why this might be erroring on this line?

Trace with adding 2 lines:
TraceData32220.txt (442.5 KB)

Code:

var tt = ttShipHead.FirstOrDefault();
callContextBpmData.Character03 = "";

if( tt != null )
{ 

   string bin = Convert.ToString(callContextBpmData.Character01);
   string oNum = Convert.ToString(tt.OTSOrderNum);
   string pNum = "";
   string whse = "";
   int ioNum = Convert.ToInt32(tt.OTSOrderNum);
   int ioLine = 0;
   int ioRel = 0;
   int packNum = Convert.ToInt32(tt.PackNum);
   int shipCustNum = 0;
   decimal qty = Decimal.Zero;
   
   shipCustNum = (
     from oh in Db.OrderHed.With(LockHint.NoLock)
     where oh.Company == Session.CompanyID &&
                oh.OrderNum == ioNum
     select oh.ShipToCustNum).DefaultIfEmpty(0).FirstOrDefault();
   
   
   
   var binList = (
     from pb in Db.PartBin.With(LockHint.NoLock)
     where pb.Company == Session.CompanyID &&
                pb.LotNum.Substring(0,6) == oNum
     select new {pb}).ToList();

   if( binList.Count > 0 )
   {
      foreach(var daBin in binList)
      {
         whse = daBin.pb.WarehouseCode;
         pNum = daBin.pb.PartNum;
         qty = daBin.pb.OnhandQty;
         if( daBin.pb.LotNum.Length >= 10 )
         {
            ioLine = Int32.Parse(daBin.pb.LotNum.ToString().Substring(7,1));
            ioRel = Int32.Parse(daBin.pb.LotNum.ToString().Substring(9,1));
         }
         
         if( ioLine != 0 && ioRel != 0 )
         {
            
            try
            { 
               using(var shipBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.CustShipSvcContract>(Db) )
               {
                  CustShipTableset shTS = new CustShipTableset(); 
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before GetByID" + Environment.NewLine;
                  shTS = shipBO.GetByID(packNum);
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before GetNewOrdrShipDtl" + Environment.NewLine;
                  // Params: CustShip Dataset, Pack Number, Order Number
                  if( shTS.ShipDtl.Count == 0 )
                    shipBO.GetNewOrdrShipDtl(ref shTS, packNum, 0);
                  else
                    shipBO.GetNewOrdrShipDtl(ref shTS, packNum, ioNum); //<<<<< Object Ref Error

                  if( shTS.ShipDtl.Count == 1 )
                    shTS.ShipDtl[0].RowMod = "A";
                  else
                    shTS.ShipDtl[shTS.ShipDtl.Count - 1].RowMod = "A";
                  
                  
                  // Params: Order Number, Credit Message, CustShip Dataset
                  string creditMessage = "";
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before GetOrderInfo" + Environment.NewLine;
                  if( shTS.ShipDtl.Count == 1 )
                  shipBO.GetOrderInfo(ioNum, out creditMessage, ref shTS);
                  
                  
                  // Params: Order Number, Pack Num, Dataset  
                  //shTS.ShipHead[0].RowMod = "U";
                  //shipBO.GetManifestInfo(ioNum, packNum, ref shTS);
                  
                  // Params: Order, CustNum, shipToList
                  string shipToList = "";
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before 1st ShipToList" + Environment.NewLine;
                  shipBO.BuildShipToList(ioNum, shipCustNum, out shipToList);
                  
                  // Params: Part, Order, Line, MsgText, SubAvail, MsgType, origPart
                  string partParam = "";
                  string vMsgText = "";
                  string vMsgType = "";
                  string origPart = "";
                  bool vSubAvail = false;
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before CheckPrePartInfo" + Environment.NewLine;
                  shipBO.CheckPrePartInfo(ref partParam, ioNum, ioLine, out vMsgText, out vSubAvail, out vMsgType, out origPart);
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before GetOrderLineINfo" + Environment.NewLine;
                  // Params: Dataset, Pack Line, Order Line, Part Num
                  shipBO.GetOrderLineInfo(ref shTS, 0, ioLine, pNum);
                  
                  if( shTS.ShipDtl.Count > 1 )
                  {
                     // Params: PackNum, OrderNum, Line, Rel, askUser
                     bool askUser = false;
                     
                     callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before AskForShipToChange" + Environment.NewLine;
                     shipBO.AskForShipToChange(packNum, ioNum, ioLine, ioRel, ref askUser);
                  }
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before GetOrderRelInfo" + Environment.NewLine;
                  // Params: Dataset, Pack Line, Order Rel Num, AllowNewShipTo
                  shipBO.GetOrderRelInfo(ref shTS, 0, ioRel, true);
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before 2nd ShipToList" + Environment.NewLine;
                  // Params: Order, CustNum, shipToList
                  shipBO.BuildShipToList(ioNum, shipCustNum, out shipToList);
                  
                  // Params: Dataset, Pack Line?, belongToAnotherPC, pcOutMessage
                  string pcOutMessage = "";
                  int lineNum = 0;
                  bool belongToAnotherPC = false;
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before CheckPCBinOutLoc" + Environment.NewLine;
                  shipBO.CheckPCBinOutLocation(ref shTS, out lineNum, out belongToAnotherPC, out pcOutMessage);
                  
                  
                  using( var lotBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.LotSelectUpdateSvcContract>(Db) )
                  {
                     LotSelectUpdateTableset lotTS = new LotSelectUpdateTableset();

                     callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before LotGetByID" + Environment.NewLine;
                     if( shTS.ShipDtl.Count == 1 )
                      lotTS = lotBO.GetByID(shTS.ShipDtl[0].PartNum, shTS.ShipDtl[0].LotNum); 
                     else 
                      lotTS = lotBO.GetByID(shTS.ShipDtl[shTS.ShipDtl.Count - 1].PartNum, shTS.ShipDtl[shTS.ShipDtl.Count - 1].LotNum); 
                     
                     callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before LotUpdate" + Environment.NewLine;
                     lotBO.Update(ref lotTS);
                     
                  }
                  
                  /*  <parameters>
                       <parameter name="ds" type="Erp.BO.CustShipDataSet">
                          <CustShipDataSet xmlns="http://www.epicor.com/Ice/300/BO/CustShip/CustShip" />
                       </parameter>
                       <parameter name="doValidateCreditHold" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="doCheckShipDtl" type="System.Boolean"><![CDATA[True]]></parameter>
                       <parameter name="doLotValidation" type="System.Boolean"><![CDATA[True]]></parameter>
                       <parameter name="doCheckOrderComplete" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="doPostUpdate" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="doCheckCompliance" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="ipShippedFlagChanged" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="ipPackNum" type="System.Int32"><![CDATA[99255]]></parameter>
                       <parameter name="ipBTCustNum" type="System.Int32"><![CDATA[0]]></parameter>
                       <parameter name="opReleaseMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opCompleteMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opShippingMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opLotMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opInventoryMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opLockQtyMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opAllocationMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opPartListNeedsAttr" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opLotListNeedsAttr" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="shipCreditMsg" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="cError" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="compError" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="msg" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="opPostUpdMessage" type="System.String"><![CDATA[]]></parameter>
                       <parameter name="updateComplete" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="checkComplianceError" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="changeStatusError" type="System.Boolean"><![CDATA[False]]></parameter>
                       <parameter name="checkShipDtlAgain" type="System.Boolean"><![CDATA[False]]></parameter>
                    </parameters> 
                */

                  string a = "";
                  string b = "";
                  string c = "";
                  string d = "";
                  string e = "";
                  string f = "";
                  string g = "";
                  string h = "";
                  string i = "";
                  string j = "";
                  string k = "";
                  string l = "";
                  bool aB = false;
                  bool bB = false;
                  bool cB = false;
                  bool dB = false;
                  bool eB = false;
                  bool fB = false;  
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before UpdateMaster" + Environment.NewLine;
                  shipBO.UpdateMaster(ref shTS,
                  false,
                  false,
                  false,
                  false,
                  false,
                  false,
                  false,
                  packNum,
                  0,
                  out a,
                  out b,
                  out c,
                  out d,
                  out e,
                  out f,
                  out g,
                  out h,
                  out i,
                  out j,
                  out aB,
                  out bB,
                  out k,
                  out l,
                  out cB,
                  out dB,
                  out eB,
                  out fB);
                  //var ds1 = shipBO.GetByID(packNum);
                  //this.dsHolder.Attach(ds1); 
                  
                  // Params: Order, Pack, pcWarningMsg
                  string pcWarningMsg = "";
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before POGEtNEw" + Environment.NewLine;
                  shipBO.POGetNew(ioNum, packNum, out pcWarningMsg);
                  
                  // Params: Pack, PCID, Order, PackMode, cWarning
                  string cWarning = "";
                  string packMode = "PACK";
                  
                  callContextBpmData.Character03 += (shTS.ShipDtl.Count).ToString() + " " + "Before POGetDtl" + Environment.NewLine;
                  shipBO.POGetDtlList(packNum, "", 0, packMode, out cWarning);
                  
                  callContextBpmData.Character03 += "--------------------------------------------------------" + Environment.NewLine;
               }
            }
            catch(Exception e)
            {
               callContextBpmData.Character03 += e.Message.ToString() + Environment.NewLine;
               callContextBpmData.Character03 += "--------------------------------------------------------" + Environment.NewLine;
            }
         }       
      }                  
   }
}


//this.PublishInfoMessage(,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");

Debugging Flags:

0 Before GetByID
0 Before GetNewOrdrShipDtl
1 Before GetOrderInfo
1 Before 1st ShipToList
1 Before CheckPrePartInfo
1 Before GetOrderLineINfo
1 Before GetOrderRelInfo
1 Before 2nd ShipToList
1 Before CheckPCBinOutLoc
1 Before LotGetByID
1 Before LotUpdate
1 Before UpdateMaster
1 Before POGEtNEw
1 Before POGetDtl
--------------------------------------------------------
0 Before GetByID
1 Before GetNewOrdrShipDtl
Order: 556443 Pack: 99255
Object reference not set to an instance of an object.
--------------------------------------------------------
0 Before GetByID
1 Before GetNewOrdrShipDtl
Order: 556443 Pack: 99255
Object reference not set to an instance of an object.
--------------------------------------------------------

So unfortunately just ran into this issue myself. The BO for CustShip is retarded and wants you to send it exactly 1 ShipDtl record not the WHOLE ShipDtl (multiple lines)
So when you do GetNewShipDtl ()
you need to basically build a separate dataset (or clear out the old one) to make the subsequent calls.
I’m looking to see where the issue is is one or two of the calls that don’t want multiple lines.

So yeah it is GetNewShipDtl… it was written stupid. Just send an empty ShipDtl (table) in your dataset.

1 Like

I thought by having the using inside to bin loop and getting a new tableset/GetByID each time, it would essentially be doing that?

No GetByID returns the entire Ship dataset including all existing ShipDtls…
so at First
GetNew() adds 1 ShipDtl everything is golden
Update
Loop
GetByID
returns the line above as part of the dataset
GetNew() now adds another line to ShipDtl now you have 2 in the dataset. Now it gets upset.

Here’s our work around (fix stupid ass Epicor logic is what you want) the rest is just gravy
It took 2 days to figure this stupid thing out, we had to Debug Step into the Epicor Server logic to see what the error was… IMO this is a bug… but you try explaining this to support.

csts = csSvc.GetByID(packNum);
 csts.ShipDtl.Clear(); // Fix stupid ass Epicor Logic
    csSvc.GetNewOrdrShipDtl(ref csts, packNum, tt.OrderRel_OrderNum);    
    var currPackLine = csts.ShipDtl.Where(x => x.Added()).FirstOrDefault();     
    
    // Load order info
    currPackLine.OrderNum = tt.OrderRel_OrderNum;
    csSvc.GetOrderInfo(tt.OrderRel_OrderNum, out outMessage, ref csts);
    if(!string.IsNullOrEmpty(outMessage))
    {
      throw new Ice.BLException(outMessage); 
    }  
    
    
    
    // Get order line rel info
    currPackLine.OrderLine = tt.OrderRel_OrderLine;
    csSvc.GetOrderLineInfo(ref csts, currPackLine.PackLine, tt.OrderRel_OrderLine, string.Empty);
    
    currPackLine.OrderRelNum = tt.OrderRel_OrderRelNum;
    csSvc.GetOrderRelInfo(ref csts, currPackLine.PackLine, tt.OrderRel_OrderRelNum, true); 
//Fix stupid ass Part number
    string outPartNum = tt.OrderRel_PartNum;
    string outStr2 = "";
    bool outBool;
    currPackLine.PartNum = outPartNum;
    csSvc.GetPartInfo(ref csts, currPackLine.PackLine, ref outPartNum, Guid.Empty,string.Empty,out outStr2,out outStr2,out outBool, out outStr2);
        // Load the job number if it's from job.
    if(!string.IsNullOrEmpty(tt.Calculated_JobNum))
    {
      currPackLine.JobNum = tt.Calculated_JobNum;

      currPackLine.OurJobShipQty = tt.Calculated_ShipQty;
      currPackLine.WIPWarehouseCode = tt.Calculated_Whse;
      currPackLine.WIPBinNum = tt.Calculated_BinNum;
      csSvc.GetQtyInfo(ref csts, currPackLine.PackLine, 0.00M, tt.Calculated_ShipQty);
    }    
    else
    {
      // Ensure job info empty
      currPackLine.JobNum = string.Empty;
      currPackLine.OurJobShipQty = 0.00M;
      currPackLine.WIPWarehouseCode = string.Empty;
      currPackLine.WIPBinNum = string.Empty;
      
      // Fill Inv info
      currPackLine.OurInventoryShipQty = tt.Calculated_ShipQty;
      currPackLine.WarehouseCode = tt.Calculated_Whse;
      currPackLine.BinNum = tt.Calculated_BinNum;
      csSvc.GetQtyInfo(ref csts, currPackLine.PackLine, tt.Calculated_ShipQty, 0.00M);
    }          
    
    csSvc.Update(ref csts);
7 Likes

Now we’re getting somewhere! Thanks!

1 Like

Clear the ShipDtl dataset before to add a new line in the loop is definetly working, you saved my life!, thanks.