- http://axforum.info/forums/showthread.php?t=21707
- https://daxbeginners.wordpress.com/2013/12/23/how-to-explode-bom-trough-x/
Il primo è interessante perchè mostra come usare la classe BOMSearch, però non è utilizzabile in quanto in AX 2012 l'enumerato InventTable.ItemType == ItemType::BOM è deprecato, il secondo è a mio avviso incompleto perchè espande la BOM più del necessario. Il fatto che un articolo abbia una BOM valida è condizione necessaria ma NON sufficiente per poterlo esplodere, occorre che siano vere queste condizioni:
1) InventTable.PmfProductType = BOM
2) In default order settings e anche in copertura articoli, abbiamo il default order type che ci dice se è Production o Purchase. Il campo è InventItemSetupSupplyType.DefaultOrderType
Il metodo BOMDesignerCtrl::itemCanHaveBOM(), usato nel "BOM designer" standard effettua questi due controlli.
Ecco la classe che effettua l'esplosione:
class LIL_BomExplosionBOMSearch
{
BOMVersion bomVersion;
}
public static LIL_BomExplosionBOMSearch construct(BOMVersion _bomVersion)
{
LIL_BomExplosionBOMSearch instance = new LIL_BomExplosionBOMSearch();
instance.parmBomVersion(_bomVersion);
return instance;
}
public void run()
{
BOMSearch search = BOMSearch::newBOMTree(this.parmBomVersion().BOMId,
today(),
this.parmBomVersion().ItemId,
this.parmBomVersion().inventDim().configId);
this.BomExplode(search,0);
}
private boolean hasValidBomVersion(ItemId _itemId)
{
BOMVersion bomVersionLocal;
;
select firstonly RecId from bomVersionLocal
where bomVersionLocal.ItemId == _itemid
&& bomVersionLocal.Active
&& bomVersionLocal.Approved
&& bomVersionLocal.FromDate <= systemdateget ()
&& (!bomVersionLocal.ToDate || bomVersionLocal.ToDate >= systemdateget ());
if (bomVersionLocal.RecId)
{
return true;
}
return false;
}
void BomExplode(BOMSearch _search, BOMLevel _level = 0)
{
BOM bom;
BOMSearch BomSearchLocal;
InventTable inventTable;
BOMId bomId;
;
//max tree deep level reached, trow error
if(_level > BOMParameters::find().BOMMaxLevel)
{
throw error("@SYS26729");
}
//root Item
if (_level == 0)
{
info(strFmt("%1 - %2",_level,this.parmBomVersion().ItemId));
}
while (_search.next())
{
bom = _search.BOM();
inventTable = bom.inventTable();
info(strFmt("%1 - %2",_level,bom.ItemId));
//verify if item can be exploded
if (BOMDesignerCtrl::itemCanHaveBOM(bom.inventTable()) &&
this.hasValidBomVersion(bom.ItemId))
{
//find active bom
bomId = inventTable.bomId(today(),bom.BOMQty,bom.inventDim());
BomSearchLocal = BOMSearch::newBOMTree(bomId,
today(),
bom.ItemId,
bom.inventDim().configId);
this.BomExplode(BomSearchLocal, _level+1);
}
}
}
La chiamata alla classe:
LIL_BomExplosionBOMSearch LIL_BomExplosionBOMSearch = LIL_BomExplosionBOMSearch::construct(bomVersion);
LIL_BomExplosionBOMSearch.run();
Come nota tecnico / teorico, secondo la teoria degli alberi, questa ricerca sull'albero BOM è una ricerca di tipo DFS (Depth-first search) perchè non appena trova un nodo a livello (n) passa subito al suo primo figlio a livello (n+1):
nel periodo di Covid mi sarei aspettato qualche articolo in più......
RispondiElimina