Sunday, July 4, 2010

Dynamics Axapta: Inventory Transfer Orders & Business Connector

I'm going to talk about using the business connector to Ship inventory transfer orders. When doing this, as with many MS Dynamics Axapta development cases, trial and error was my approach, if you are an MS Dynamics Axapta developer you probably already know there's not that much information out there for you to use.
My first requirement was to completely Ship an inventory transfer order. The class I needed to use was: "InventTransferUpdShip". I initialized that class using table "InventTransferParmTable".
Without further ado, let me present to you a snippet of code that does the trick:
try
{
ax.TTSBegin();

AxaptaRecord rcInventTransferParmTable = ax.CreateAxaptaRecord("InventTransferParmTable");
AxaptaObject oInventTransferUpdShip = ax.CreateAxaptaObject("InventTransferUpdShip");

rcInventTransferParmTable.Call("Clear");
rcInventTransferParmTable.Call("initParmDefault");

string sParmId = Convert.ToString(ax.CallStaticClassMethod("RunBaseMultiParm", "getSysParmId"));
rcInventTransferParmTable.set_Field("ParmId", sParmId.Trim());
rcInventTransferParmTable.set_Field("TransferId", "TOID-00001");
rcInventTransferParmTable.set_Field("UpdateType", 0); //InventTransferUpdateType::Shipment
rcInventTransferParmTable.set_Field("PrintTransferShipment", 0); //NO, we don't want to print anything
rcInventTransferParmTable.set_Field("ShipUpdateQty", 1); //InventTransferShipUpdateQty::All
rcInventTransferParmTable.set_Field("EditLines", 1); //YES
rcInventTransferParmTable.set_Field("ExplodeLines", 1); //YES
oInventTransferUpdShip = (AxaptaObject)ax.CallStaticClassMethod("InventTransferUpdShip", "newParmBuffer", rcInventTransferParmTable);

oInventTransferUpdShip.Call("Run");

//no problems, then commit the transaction
ax.TTSCommit();
ax.Logoff();
}
catch(Exception ex)
{
//Do something with this!! At least a rollback!
}

Now that we have our order successfully shipped, we might want to partially ship it, this could be a bit of a problem. I first started trying the same approach, trying to use the same class since it has a very tempting method called updateInventTransferLine. But after trying several things I kept getting an error saying: "Ledger class not initialized when calling InventUpd_Financial.initUpdate". What to do here then? Well, let's initialize the missing object by calling "InventTransferUpdShip" base class method "beginLedger" and initializing the lines. Here's a bit of code to do this:

try
{
ax.TTSBegin();

AxaptaRecord rcInventTransferParmTable = ax.CreateAxaptaRecord("InventTransferParmTable");
AxaptaObject oInventTransferUpdShip = ax.CreateAxaptaObject("InventTransferUpdShip");

rcInventTransferParmTable.Call("Clear");
rcInventTransferParmTable.Call("initParmDefault");

string sParmId = Convert.ToString(ax.CallStaticClassMethod("RunBaseMultiParm", "getSysParmId"));
rcInventTransferParmTable.set_Field("ParmId", sParmId.Trim());
rcInventTransferParmTable.set_Field("TransferId", "TOID-00001"); /*Assign the transfer order id*/
rcInventTransferParmTable.set_Field("UpdateType", 0); //InventTransferUpdateType::Shipment
rcInventTransferParmTable.set_Field("PrintTransferShipment", 0); //NO, we don't want to print anything
rcInventTransferParmTable.set_Field("ShipUpdateQty", 1); //InventTransferShipUpdateQty::All
rcInventTransferParmTable.set_Field("EditLines", 1); //YES
rcInventTransferParmTable.set_Field("ExplodeLines", 1); //YES
oInventTransferUpdShip = (AxaptaObject)ax.CallStaticClassMethod("InventTransferUpdShip", "newParmBuffer", rcInventTransferParmTable);

oInventTransferUpdShip.Call("beginLedger"); //load the ledger to use in the transaction
oInventTransferUpdShip.Call("initJournalLinesList"); //initialize the lines, we will then modify them depending on the quantities we want to ship

//Initialize one line and partialy ship it
//you could do this for lots of lines, just iterate through them and add them to the object
AxaptaRecord rcInventTransferParmLine = ax.CreateAxaptaRecord("InventTransferParmLine");
AxaptaRecord rcInventTransferLine = ax.CreateAxaptaRecord("InventTransferLine");
rcInventTransferLine = ax.CallStaticRecordMethod("InventTransferLine", "find",
"TOID-00001" /*this is my transfer order id*/, 1.00 /*this is the line number, I only want the first one for this code snippet*/, 1) as AxaptaRecord;
if (rcInventTransferLine.Found)
{
rcInventTransferParmLine.Call("initFromInventTransferLine", rcInventTransferLine);
rcInventTransferParmLine.set_Field("QtyShipNow", 12); //only ship the QTY that was selected and close the line
rcInventTransferParmLine.set_Field("QtyReceiveNow", 0M);
rcInventTransferParmLine.set_Field("QtyScrapNow", 0M);
rcInventTransferParmLine.set_Field("InventTransId", rcInventTransferLine.get_Field("InventTransId").ToString().Trim());
rcInventTransferParmLine.set_Field("InventTransIdTransit", rcInventTransferLine.get_Field("InventTransIdTransitTo").ToString().Trim());
rcInventTransferParmLine.set_Field("InventDimId", rcInventTransferLine.get_Field("InventDimId").ToString().Trim());
rcInventTransferParmLine.set_Field("CloseLine", 1); //YES

oInventTransferUpdShip.Call("updateInventTransferLine", rcInventTransferParmLine);
}
else
throw new Exception("Not found! What's that all about, I just checked and it was in the database!");


//no problems, then commit the transaction
ax.TTSCommit();
ax.Logoff();
}
catch(Exception ex)
{
//Do something with this!! At least a rollback!
}

Well, hope somebody finds this post useful.
Cheers.

No comments:

Post a Comment