OrderAlloc.AllocateByLotBin returns "underlying provider failed on enlisttransaction"

In my continuing saga to automate the Epicor 10 Fulfillment screen, I have successfully mimicked the steps the screen executes to allocate by Lot/Bin each line in the grid. I am finally to the final step of actually doing the allocation step (OrderAlloc.AllocateByLotBin). From Epicor’s Object Browser, it looks like a pretty straight forward call. However, like OrderAlloc.GetListOfOrders, it isn’t straight forward and isn’t properly documented.

When I execute it, I receive a message stating “underlying provider failed on enlisttransaction”. Does this method require a transaction or am I missing something else in order to execute this that isn’t apparent? An online search doesn’t come up with anything concerning this error and an Epicor screen customization, so this appears to be a pretty rare issue.

1 Like

I have exactly the same issue. Did you ever find an answer to this?

Well I did find a solution, but I had to use a combination of the customization and a BPM to get it to work. I also bent the rules a bit and had the BPM update the necessary tables directly to complete the goal.

I know Epicor frowns on that, but when their data adapter isn’t working as expected and isn’t well documented, you have to do what you can with the tools provided.

Ouch. Ok, what I thought wasn’t going to be terribly difficult turns out to be. I’m going to try the BPM route as well. thank you!

Have you tried testing using BL Tester?

I’m working on building a screen that will allow Inventory Transfer for Allocated Items. I refer to it on this post: Inventory Transfer Allocated Stock - #12 by markdamen

I’ve just traced the necessary calls, and I have this list. All are within the OrderAlloc dll

GetListOfOrders
OrderAllocationGetRows
CheckDates
OneDemandType
GetLotOnHandByWhseCodeZoneBinType
AllocateByLotBin

Are you hitting all those calls?

OK, got it. I was able to get the error that you were getting. In the call to OrderAlloc.AllocateByLotBin, these were the minimum things that I needed to set in the dataset:

PartAllocLot[x] table (where x is the row that you want to allocate from)
Allocate - set to true
NewAllocatedQty = int

PartAllocTran table
ReleaseToPicking= true
Adhoc = true
RowMod = U

I think the thing that solves the error is making the PartAllocTran row dirty by changing a field. In my business case we want to release to Picking, and we don’t use allocation templates so changing these 2 fields to true makes the row U state and all is happy.

Thank you! I also found this morning that the Tran columns need to be set entirely.

Also, it’s either initiate all the columns or use the getlist then OrderAllocationGetRows to pre-fill it. I’m working on this now and will report back.

I was able to get it to work in BLTester without using these 2 calls:

CheckDates
OneDemandType

As listed in my previous post, I only have to set a few fields

Allocate(true), NewAllocatedQty(qty), ReleaseToPicking(true),Adhoc(true)

Thank you, Mark! I’ll let you know what happens. Saved me a lot of agony.

I was able to follow through what you have above and was able to allocate a LOT. The allocation shows up successfully in the PartAlloc table. However, the part bin record is not updating.

I’ll post back if I find something else.

Scratch that. I was adding a row to the PartAllocLot instead of using what was returned …

EDIT:

I was able to skip GetLotOnHandByWhseCodeZoneBinType and create my own PartAllocLot row from a baq. The key is to make sure to specify the warehouse on the AllocateByLotBin call. That makes the PartBin record update.

Also, the PartAllocTran column for Adhoc is “AddHoc” in the datatable… this threw me a few times

Hi Mark,

Did you get this to work fully? I’m trying Allocate by Lot in a BPM - no errors just nothing in the PartAlloc Table. Not the prettiest bit of code as I am hacking away at gettng an example working. Any ideas where I am goiong wrong?

Erp.Tablesets.PartAllocLotRow PAllocLR = new Erp.Tablesets.PartAllocLotRow();
    PAllocLR["Company"] = "CABP";
    PAllocLR["PartNum"] = "1000522";
    PAllocLR["WarehouseCode"] = "WCAS";
    PAllocLR["BinNum"] = "PUTAWAY";
    PAllocLR["OrderNum"] = 2320;
    PAllocLR["Orderline"] = 1;
    PAllocLR["OrderRelNum"] = 1;
    PAllocLR["LotNum"] = "515";
    PAllocLR["Allocate"] = true;
    PAllocLR["NewAllocatedQty"] = Qty  ;
    PAllocLR["RelatedToSchemaName"] = "Erp"  ;
    PAllocLR["RelatedToTableName"] = "OrderRel"  ;
    
    Guid OrderRel =new Guid("272B6BCE-5863-42DC-AE55-AD73AB0E0088");
    System.Guid.NewGuid().ToString();
    PAllocLR["RelatedToSysRowID"] = OrderRel  ;
    
    PAllocLR["RowMod"] = "A"  ;
           
    oat.PartAllocLot.Add(PAllocLR);
        
    oa.AllocateByLotBin(ref oat,"","All",out Message,out res);

Yep I did. It doesn’t look like you’ve implemented what I suggested above from the code you have there.

You need to deal with the PartAllocTran table as well as PartAllocLot table.

OK, got it. I was able to get the error that you were getting. In the call to OrderAlloc.AllocateByLotBin, these were the minimum things that I needed to set in the dataset:

PartAllocLot table (where x is the row that you want to allocate from)
Allocate - set to true
NewAllocatedQty = int

PartAllocTran table
ReleaseToPicking= true
Adhoc = true
RowMod = U

Hi Mark,

Thanks for the quick response - sorry I didn;t post the whole code - I did implement what you suggested - just no records are created.
Apologies in advance again - the code is a mess whilst I work out what I’m doing wrong:

//Epicor.Customization.Bpm.InfoMessage.Publish("0");
//string OrderNum = "2320";
string Message = "";


bool res = false;

Erp.Tablesets.OrderAllocTableset oat = new Erp.Tablesets.OrderAllocTableset();
Erp.Tablesets.OrderAllocListTableset oatl = new Erp.Tablesets.OrderAllocListTableset();

//Erp.Tablesets.OrderAllocListTableset padt = new Erp.Tablesets.OrderAllocTableset.PartAllocTableset();
//OrderAllocDataSet.PartAllocLotDataTable

Erp.Contracts.OrderAllocSvcContract oa = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.OrderAllocSvcContract>(Db);
string ordHed = "OrderHed.OrderNum = "+ 2320;
string orderDtl = "OrderDtl.OrderLine = 1 ";
string ordeRel = "OrderRel.OrderRelNum = 1";

using(oa)
{
  string PartAllocWhereClause = "NoFilter,NoFilter,NoFilter,NoFilter";
  oatl = oa.GetListOfOrders("", ordHed, orderDtl, ordeRel, "", PartAllocWhereClause, "", "", "", "", "", "", 0, 0, out res, Session.CompanyID);   ////////////////////////////////////////////   One
  foreach (var row in oatl.OrderAllocList)
  {

  row.RowMod = IceRow.ROWSTATE_UNCHANGED;
  } 

oat = oa.OrderAllocationGetRows(oatl, 0);                                                                                          ///////////////////////////////////////////  Two
  
if(oat != null )
{
  
  //foreach(var ordRel in oat.OrderAlloc.Where(i=>i.Company == Session.CompanyID ))
  //{
  //*  
  Erp.Tablesets.SlimOrderAllocTableset soa = new Erp.Tablesets.SlimOrderAllocTableset();
  Ice.IceRow sR = soa.SlimOrderAlloc.NewRow();
  sR["AssemblySeq"] = 0;
  sR["Company"] = Session.CompanyID.ToString();
  sR["DemandType"] = "Order";
  sR["FulfillmentSeq"] = 1;
  sR["JobNum"] = "";
  sR["MtlSeq"] = 0;
  sR["OrderLine"] = 1;
  sR["OrderNum"] = 2320;
  sR["OrderRelNum"] = 1;
  sR["SelectedForAction"] = true; /////////
  sR["TFOrdLine"] = 0;
  sR["TFOrdNum"] = "";
  //sR["LotNum"] = "515";
  sR["RowMod"] = "A"; /////////
  
  soa.SlimOrderAlloc.Add(sR);
  //Epicor.Customization.Bpm.InfoMessage.Publish("4");
  
  try
    {
    
    foreach(var ORow in oat.OrderAlloc)
    {
       
       ORow.SelectedForAction = true; // Will Get a Demand Error if you don;t set this!!
       ORow.RowMod = "U";
       Epicor.Customization.Bpm.InfoMessage.Publish(Convert.ToString(ORow.OrderLine));
       //}
    }
       
    foreach(var TRow in oat.PartAllocTran)
    {
     TRow.AddHoc = true;
     TRow.ReleaseToPicking = true;
     TRow.RowMod = "U";
     //Epicor.Customization.Bpm.InfoMessage.Publish("Tran" + TRow.Company);
    }
   
    oa.CheckDates(ref soa ,out Message);
    oa.OneDemandType(ref oat ,out Message, out Message);
    
    
    
    
    oa.GetLotBinOnHandByWhseCodeZoneBinType(ref oat, "","","Standard");
    
    decimal Qty = 12;
    
    Erp.Tablesets.PartAllocLotRow PAllocLR = new Erp.Tablesets.PartAllocLotRow();
    PAllocLR["Company"] = "CABP";
    PAllocLR["PartNum"] = "1000522";
    PAllocLR["WarehouseCode"] = "WCAS";
    PAllocLR["BinNum"] = "PUTAWAY";
    PAllocLR["OrderNum"] = 2320;
    PAllocLR["Orderline"] = 1;
    PAllocLR["OrderRelNum"] = 1;
    PAllocLR["LotNum"] = "515";
    PAllocLR["Allocate"] = true;
    PAllocLR["NewAllocatedQty"] = Qty  ;
     PAllocLR["AllocatedQty"] = Qty  ;
    
    PAllocLR["RelatedToSchemaName"] = "Erp"  ;
    PAllocLR["RelatedToTableName"] = "OrderRel"  ;
    
    Guid OrderRel =new Guid("272B6BCE-5863-42DC-AE55-AD73AB0E0088");
    System.Guid.NewGuid().ToString();
    PAllocLR["RelatedToSysRowID"] = OrderRel  ;
    
    PAllocLR["RowMod"] = "A"  ;
           
    oat.PartAllocLot.Add(PAllocLR);
        
    oa.AllocateByLotBin(ref oat,"","All",out Message,out res);
    
    }
    catch (Exception ex)
    {
    Epicor.Customization.Bpm.InfoMessage.Publish(" Reservation Error "+ ex.Message + "\n" + ex.InnerException);
    }
     
}

}