Dynamics Ax does not allow you to change the Inventory UnitId of an item if there is stock or if there are open transactions. We as a food business wanted to change the inventory unit of canola oil from 200L barrels to 1000L Pallecons (or even better to Ltrs, avoiding future changes of the Inventory Stock Item), but as nearly every one of our products use canola oil the will be no point in time without open transactions (production orders) and deleting and reentering all open orders is also a nuisance. Therefore I decided to make a mod which allows us to change to unitId with open transactions and existing stock. The modifications only need to be done in the update method of the InventTableModule table and are marked with //bw.
IMPORTANT: The code here only updates InventTrans and InventSum. There are other tables with Quantities referring to the Inventory Unit such as InventJournalTrans which I do not update. This leads to inconsistencies which we can live with but you might not!
void update(boolean _updatePriceDate = true)
{
InventTrans inventTrans; //bw InventTableModule old = this.orig(); //bw
InventSum inventSum; //bw
boolean updPrice;
FormRun formRun;
FormObjectSet formObjSet;
int i;
{
InventTrans inventTrans; //bw InventTableModule old = this.orig(); //bw
InventSum inventSum; //bw
boolean updPrice;
FormRun formRun;
FormObjectSet formObjSet;
int i;
if (this.orig().Price != this.Price ||
this.orig().Markup != this.Markup ||
this.orig().PriceUnit != this.PriceUnit)
{
updPrice = true;
this.orig().Markup != this.Markup ||
this.orig().PriceUnit != this.PriceUnit)
{
updPrice = true;
if (_updatePriceDate)
this.PriceDate = systemdateget();
}
this.PriceDate = systemdateget();
}
ttsbegin;
//bw start
//Changed on 27 Apr 2007 by TW
/* Description:
allow update of units: modify stock level and inventJournals
//bw start
//Changed on 27 Apr 2007 by TW
/* Description:
allow update of units: modify stock level and inventJournals
Prerequisite: a unit conversion must exist between the old and the new UnitId.
The unit conversion will be used to adjust the quantities.
*/ if (old.UnitId != this.UnitId && this.ModuleType==ModuleInventPurchSales::Invent) //only for inventory type
{
if(UnitConvert::canConvert(old.UnitId,this.UnitId,this.ItemId)//assured by validateField
&& UnitConvert::valueConvert(1,old.UnitId,this.UnitId,this.ItemId)!=1) //only bother if not one-to-one
{
//adjust inventTrans (this updates all transaction history of the item and might take a while)
while select forupdate inventTrans where inventTrans.ItemId == this.ItemId
{
inventTrans.Qty = UnitConvert::valueConvert(inventTrans.Qty,old.UnitId,this.UnitId,this.ItemId);
inventTrans.QtySettled =
UnitConvert::valueConvert(inventTrans.QtySettled,old.UnitId,this.UnitId,this.ItemId);
inventTrans.update();
}
//adjust inventSum select forupdate firstonly inventSum where inventSum.ItemId == this.ItemId;
if (inventSum)
{
inventSum.AvailOrdered
= UnitConvert::valueConvert(inventSum.AvailOrdered,old.UnitId,this.UnitId,this.ItemId);
inventSum.AvailPhysical
= UnitConvert::valueConvert(inventSum.AvailPhysical,old.UnitId,this.UnitId,this.ItemId);
inventSum.OnOrder
= UnitConvert::valueConvert(inventSum.OnOrder,old.UnitId,this.UnitId,this.ItemId);
inventSum.Ordered
= UnitConvert::valueConvert(inventSum.Ordered,old.UnitId,this.UnitId,this.ItemId);
inventSum.ReservOrdered
= UnitConvert::valueConvert(inventSum.ReservOrdered,old.UnitId,this.UnitId,this.ItemId);
inventSum.ReservPhysical
= UnitConvert::valueConvert(inventSum.ReservPhysical,old.UnitId,this.UnitId,this.ItemId);
inventSum.Received
= UnitConvert::valueConvert(inventSum.Received,old.UnitId,this.UnitId,this.ItemId);
inventSum.PostedQty
= UnitConvert::valueConvert(inventSum.PostedQty,old.UnitId,this.UnitId,this.ItemId);
inventSum.Deducted
= UnitConvert::valueConvert(inventSum.Deducted,old.UnitId,this.UnitId,this.ItemId);
inventSum.QuotationIssue
= UnitConvert::valueConvert(inventSum.QuotationIssue,old.UnitId,this.UnitId,this.ItemId);
inventSum.QuotationReceipt
= UnitConvert::valueConvert(inventSum.QuotationReceipt,old.UnitId,this.UnitId,this.ItemId);
inventSum.Registered
= UnitConvert::valueConvert(inventSum.Registered,old.UnitId,this.UnitId,this.ItemId);
inventSum.Picked
= UnitConvert::valueConvert(inventSum.Picked,old.UnitId,this.UnitId,this.ItemId);
inventSum.Arrived
= UnitConvert::valueConvert(inventSum.Arrived,old.UnitId,this.UnitId,this.ItemId);
inventSum.PhysicalInvent
= UnitConvert::valueConvert(inventSum.PhysicalInvent,old.UnitId,this.UnitId,this.ItemId);
inventSum.update();
}
}
}
//bw end super();
if (updPrice)*/ if (old.UnitId != this.UnitId && this.ModuleType==ModuleInventPurchSales::Invent) //only for inventory type
{
if(UnitConvert::canConvert(old.UnitId,this.UnitId,this.ItemId)//assured by validateField
&& UnitConvert::valueConvert(1,old.UnitId,this.UnitId,this.ItemId)!=1) //only bother if not one-to-one
{
//adjust inventTrans (this updates all transaction history of the item and might take a while)
while select forupdate inventTrans where inventTrans.ItemId == this.ItemId
{
inventTrans.Qty = UnitConvert::valueConvert(inventTrans.Qty,old.UnitId,this.UnitId,this.ItemId);
inventTrans.QtySettled =
UnitConvert::valueConvert(inventTrans.QtySettled,old.UnitId,this.UnitId,this.ItemId);
inventTrans.update();
}
//adjust inventSum select forupdate firstonly inventSum where inventSum.ItemId == this.ItemId;
if (inventSum)
{
inventSum.AvailOrdered
= UnitConvert::valueConvert(inventSum.AvailOrdered,old.UnitId,this.UnitId,this.ItemId);
inventSum.AvailPhysical
= UnitConvert::valueConvert(inventSum.AvailPhysical,old.UnitId,this.UnitId,this.ItemId);
inventSum.OnOrder
= UnitConvert::valueConvert(inventSum.OnOrder,old.UnitId,this.UnitId,this.ItemId);
inventSum.Ordered
= UnitConvert::valueConvert(inventSum.Ordered,old.UnitId,this.UnitId,this.ItemId);
inventSum.ReservOrdered
= UnitConvert::valueConvert(inventSum.ReservOrdered,old.UnitId,this.UnitId,this.ItemId);
inventSum.ReservPhysical
= UnitConvert::valueConvert(inventSum.ReservPhysical,old.UnitId,this.UnitId,this.ItemId);
inventSum.Received
= UnitConvert::valueConvert(inventSum.Received,old.UnitId,this.UnitId,this.ItemId);
inventSum.PostedQty
= UnitConvert::valueConvert(inventSum.PostedQty,old.UnitId,this.UnitId,this.ItemId);
inventSum.Deducted
= UnitConvert::valueConvert(inventSum.Deducted,old.UnitId,this.UnitId,this.ItemId);
inventSum.QuotationIssue
= UnitConvert::valueConvert(inventSum.QuotationIssue,old.UnitId,this.UnitId,this.ItemId);
inventSum.QuotationReceipt
= UnitConvert::valueConvert(inventSum.QuotationReceipt,old.UnitId,this.UnitId,this.ItemId);
inventSum.Registered
= UnitConvert::valueConvert(inventSum.Registered,old.UnitId,this.UnitId,this.ItemId);
inventSum.Picked
= UnitConvert::valueConvert(inventSum.Picked,old.UnitId,this.UnitId,this.ItemId);
inventSum.Arrived
= UnitConvert::valueConvert(inventSum.Arrived,old.UnitId,this.UnitId,this.ItemId);
inventSum.PhysicalInvent
= UnitConvert::valueConvert(inventSum.PhysicalInvent,old.UnitId,this.UnitId,this.ItemId);
inventSum.update();
}
}
}
//bw end super();
{ [...] }
ttscommit;
}
}