Creating Part Lot record with quantity from code

Having a bit of frustration with creating a part lot record from form code. I’m creating Part Lot records on the fly to create user testing data. I’m attempting doing it by following the same methods that fire from a quantity adjustment transaction, but I keep failing at the end when I try to call the SetInventoryQtyAdj method from the Inventory Quantity Adjustment adapter. Here’s what I’ve tried:

string errorLocation = String.Empty;
for(int i = 0; i<recs; i++)
{
try{				
	//try creating part lots for test parts and give them a qty
	//Lot Adapter
	LotSelectUpdateAdapter adapterLSA = new LotSelectUpdateAdapter(oTrans);
	adapterLSA.BOConnect();		
	bool result = adapterLSA.GetNewPartLot(partNum);
	if(result){
	//lotDataSet and part lot row approach. Set plRow to random lot
	LotSelectUpdateDataSet lsaData = adapterLSA.LotSelectUpdateData;
	LotSelectUpdateDataSet.PartLotRow plRow = (LotSelectUpdateDataSet.PartLotRow)lsaData.PartLot[0];
	errorLocation= "245";
	//generate random lot number
	lotNumRand = RandomString(7);
	plRow.LotNum = lotNumRand;
	adapterLSA.GetByID(partNum,lotNum);
	adapterLSA.Update();
	errorLocation = "251";
	//MessageBox.Show(adapterLSA.GetByID(partNum,lotNum).ToString());
	if(adapterLSA.GetByID(partNum,lotNum)){
	//set the inventory quantity
	InventoryQtyAdjAdapter adapterQtyAdj = new InventoryQtyAdjAdapter(oTrans);
	adapterQtyAdj.BOConnect();
	//get by ID?
	InventoryQtyAdjDataSet qtyAdjData = adapterQtyAdj.InventoryQtyAdjData;
	errorLocation = "259";						
	//Neg inv test
	string pcMessage;
	string pcNeqQtyAction;
	adapterQtyAdj.NegativeInventoryTest(partNum, "52", "receipt", lotNumRand,"", "EA", 1, -1, out pcNeqQtyAction, out pcMessage);
	//Pre Set Inv Qty Adj row and method						
	//InventoryQtyAdjDataSet.InventoryQtyAdjRow qaRow = (InventoryQtyAdjDataSet.InventoryQtyAdjRow)qtyAdjData.InventoryQtyAdj[0]; //No Row exists, try creating one
	InventoryQtyAdjDataSet.InventoryQtyAdjRow qaRow = (InventoryQtyAdjDataSet.InventoryQtyAdjRow)qtyAdjData.InventoryQtyAdj.NewInventoryQtyAdjRow();		
	errorLocation = "267";		
	qaRow.BinNum = "receipt";	
	qaRow.AdjustQuantity = 1;
	qaRow.ReasonCode = "DJ002";
	qaRow.LotNum = lotNumRand;
	qaRow.ReasonCodeDescription = "Accounting Adjust Disposition";
	qaRow.WhseBinDescription = "Receipt Denver";
	adapterQtyAdj.Update();
	errorLocation = "275";
	bool requiresUserInput;
	adapterQtyAdj.PreSetInventoryQtyAdj(out requiresUserInput);
	//Set Inv Qty Adj, no attributes called
	string partTranPKs;
	qaRow.RowMod = "U";
	adapterQtyAdj.SetInventoryQtyAdj(qtyAdjData,out partTranPKs);
	//cleanup adapter
	adapterQtyAdj.Dispose();
	}    

Specifically the error I get is at my fancy location marker “275” and the error message is “ttInventoryQtyAdj record not found”, which seems to tell me that I haven’t provided a valid data set for that method to consume.

Probably a long shot, but if anyone has done something similar, I’d appreciate any help. Thanks

If anyone has had a thought on this, I would really appreciate it!

You are missing some calls you need to get a NewDataSet or a GetData or something to populate that DataSet

1 Like

If you look at a Trace you are missing the following calls, those get you an inventory InventoryQtyAdjDataSet which you can then update to change the quantity

<tracePacket>
  <businessObject>Erp.Proxy.BO.InventoryQtyAdjImpl</businessObject>
  <methodName>GetInventoryQtyAdj</methodName>
  <appServerUri>net.tcp://epicor10/Epicor10.1Coding/</appServerUri>
  <returnType>Erp.Tablesets.InventoryQtyAdjTableset</returnType>
  <localTime>1/3/2017 13:05:36:8946155 PM</localTime>
  <executionTime total="237" roundTrip="235" channel="0" bpm="0" other="2" />
  <retries>0</retries>
  <parameters>
    <parameter name="partnumber" type="System.String"><![CDATA[MRWH811]]></parameter>
    <parameter name="uomCode" type="System.String"><![CDATA[]]></parameter>
  </parameters>
</tracePacket>

<tracePacket>
  <businessObject>Erp.Proxy.BO.InventoryQtyAdjImpl</businessObject>
  <methodName>GetInventoryQtyAdjBrw</methodName>
  <appServerUri>net.tcp://epicor10/Epicor10.1Coding/</appServerUri>
  <returnType>Erp.Tablesets.InventoryQtyAdjBrwTableset</returnType>
  <localTime>1/3/2017 13:05:37:3365861 PM</localTime>
  <executionTime total="1260" roundTrip="1256" channel="0" bpm="0" other="4" />
  <retries>0</retries>
  <parameters>
    <parameter name="partNum" type="System.String"><![CDATA[MRWH811]]></parameter>
    <parameter name="wareHouseCode" type="System.String"><![CDATA[Main]]></parameter>
    <parameter name="primaryBin" type="System.String"><![CDATA[]]></parameter>
  </parameters>
</tracePacket>
1 Like

Thanks Jose,
I was basically following the trace from an inventory qty adjustment transaction, but I did not see those methods until much later in the transaction. I will try calling those methods, thank you for your help!

After calling those methods to get a data set, I still get no row at position 0. Do I need to create the row myself?

not but you need to make sure you re using that dataset… share your code

if(adapterLSA.GetByID(partNum,lotNum)){
//set the inventory quantity
	InventoryQtyAdjAdapter adapterQtyAdj = new InventoryQtyAdjAdapter(oTrans);
	adapterQtyAdj.BOConnect();
	
	//call Get Inv Qty Adj
	adapterQtyAdj.GetInventoryQtyAdj(partNum, "");
	InventoryQtyAdjDataSet qtyAdjData = adapterQtyAdj.InventoryQtyAdjData;

	//call GetInvQtyAdjBrw
	string primaryBin;
	adapterQtyAdj.GetInventoryQtyAdjBrw(partNum, "52", out primaryBin);
	InventoryQtyAdjBrwDataSet qtyAdjDataBrw = adapterQtyAdj.InventoryQtyAdjBrw;
	errorLocation = "259";	
				
	//Neg inv test
	string pcMessage;
	string pcNeqQtyAction;
	adapterQtyAdj.NegativeInventoryTest(partNum, "52", "receipt", lotNumRand,"", "EA", 1, -1, out pcNeqQtyAction, out pcMessage);

	//Pre Set Inv Qty Adj row and method						
	InventoryQtyAdjDataSet.InventoryQtyAdjRow qaRow = (InventoryQtyAdjDataSet.InventoryQtyAdjRow)qtyAdjData.InventoryQtyAdj[0]; //this row doesn't exist	
	//InventoryQtyAdjDataSet.InventoryQtyAdjRow qaRow = (InventoryQtyAdjDataSet.InventoryQtyAdjRow)qtyAdjData.InventoryQtyAdj.NewInventoryQtyAdjRow();		
	
	errorLocation = "267";		
	qaRow.BinNum = "receipt";	
	qaRow.AdjustQuantity = 1;
	qaRow.ReasonCode = "DJ002";
	qaRow.LotNum = lotNumRand;
	qaRow.ReasonCodeDescription = "Accounting Adjust Disposition";
	qaRow.WhseBinDescription = "Receipt Denver";
	qaRow.RowMod = "U";
	adapterQtyAdj.Update();
	errorLocation = "275";		
			
	//preset inv qty adj method
	bool requiresUserInput;
	adapterQtyAdj.PreSetInventoryQtyAdj(out requiresUserInput);

	//CheckForNeedLotAttrs
	bool needsLotAttrs;
	adapterLSA.ChkForNeedsLotAttrs(partNum, lotNumRand, out needsLotAttrs);	
				
	//Set Inv Qty Adj, no attributes called.
	errorLocation = "280";
	string partTranPKs;						
	adapterQtyAdj.SetInventoryQtyAdj(qtyAdjData,out partTranPKs);

	//cleanup adapter
	adapterQtyAdj.Dispose();
}

Are you actually getting a Row when you run your Get?

Good call, I am not. I just tested this

 //call Get Inv Qty Adj
    	adapterQtyAdj.GetInventoryQtyAdj(partNum, "");
    	InventoryQtyAdjDataSet qtyAdjData = adapterQtyAdj.InventoryQtyAdjData;
    	MessageBox.Show(qtyAdjData.Tables[0].Rows.Count.ToString());

I get a count of 0…

Hmm dumb question is there inventory already in the system?

It does not. Before I call this code block, I am (I think) creating the lot shell.
I intended to create the actual inventory with this quantity adjustment transaction though, just as I would if interacting through the quantity adjustment form.

for(int i = 0; i<recs; i++)
{
	try{				
	//try creating part lots for test parts and give them a qty
	//Lot Adapter
	LotSelectUpdateAdapter adapterLSA = new LotSelectUpdateAdapter(oTrans);
	adapterLSA.BOConnect();		
	bool result = adapterLSA.GetNewPartLot(partNum);
	if(result){
	//lotDataSet and part lot row approach. Set plRow to random lot
	LotSelectUpdateDataSet lsaData = adapterLSA.LotSelectUpdateData;
	LotSelectUpdateDataSet.PartLotRow plRow = (LotSelectUpdateDataSet.PartLotRow)lsaData.PartLot[0];
	errorLocation= "245";
	//generate random lot number
	lotNumRand = RandomString(7);
	MessageBox.Show(lotNumRand);
	plRow.LotNum = lotNumRand;
	adapterLSA.GetByID(partNum,lotNum);
        adapterLSA.Update();
	errorLocation = "251";
if(adapterLSA.GetByID(partNum,lotNum)){ //this is where the above code then starts.

Edit: Yes there is inventory in the system, but I am attempting to create more from this code. I don’t think I answered your question properly.

This will do it

InventoryQtyAdjAdapter iq = new InventoryQtyAdjAdapter(oTrans);
iq.BOConnect();
iq.GetInventoryQtyAdjustmentData("MYPART",string.Empty);
iq.InventoryQtyAdjData.InventoryQtyAdj[0].AdjustQuantity = 100;
iq.InventoryQtyAdjData.InventoryQtyAdj[0].BinNum = "100";
iq.InventoryQtyAdjData.InventoryQtyAdj[0].ReasonCode = "DEF";
iq.InventoryQtyAdjData.InventoryQtyAdj[0].LotNum = "MyLot";
iq.InventoryQtyAdjData.InventoryQtyAdj[0].RowMod = "U";
string pks;
iq.SetInventoryQtyAdj(iq.InventoryQtyAdjData, out pks);
2 Likes

This is fantastic, thank you Jose! I am curious as to why this solution works though. From what I can see, in my code, I referenced the row, which apparently doesn’t exist in the way I think it does. In your above code, what index are you going after?


I’d really like to make sure I understand why my approach wasn’t working and why yours does for this scenario. Thanks!!

I think the function you were using GetInventoryQtyAdj returns a dataset vs the one I used GetInventoryQtyAdjustmentData merges the dataset into the adapter. That’s likely the issue

Always something new to learn, isn’t there! :slight_smile: thanks!

Same Exact error in Service Connect. Same exact methods called as Aaron did. Unfortunately, GetInventoryQtyAdjustmentData is not an available method to use in the InventoryQtyAdj adapter.

If you guys have any ideas, i’d greatly appreciate it.

Just an idea, but is there a way for you to hydrate a dataset without calling the GetInventoryQtyAdjusmentData method?
Once that’s filled out, there might be a way to call the code above (or a variation of) to accomplish the task.

1 Like

Just figured it out. Thanks for the input. A silly mistake by me really. If anyone else runs into this while Building a Service Connect solution, you need to hardcode an A for the RowMod on the conversion going to the InventoryQtyAdj.PreSetInventoryQtyAdj Request.