如果有遗漏或错误的地方请大家指正
从Inventory management->journals->Item Counting->Counting可以进入盘点:
新建一条盘点记录后单击lines可以进入盘点:
需要注意到的一点是:当我们修改各相关字段时,盘点数会实时更新。
基本上每个字段其数据源下的对应字段的modified方法都会触发去更新盘点数:
盘点这部分是由类:InventMov_Jour_Loss_SumUp控制的,它是inventmov_journal的子类,而inventmov_journal又是InventMovement的子类。
InventMov_Jour_Loss_SumUp是使用方法:InventQty dateOnHandPhysical(InventDim _inventDim)计算盘点数的,
而该方法又调用了InventSumDatePhysicalDim的静态方法:
server static InventQty onHandQty(
TransDate _transDate,
ItemId _itemId,
InventDim _inventDim,
InventDimParm _inventDimParm
)
来计算的,在这个静态方法里会去调用类:InventSumDatePhysicalDim,这个类继承自InventSumDatePhysical,它负责结合维度来查询物料数量。
类inventmov_journal的声明中会声明一个:
InventJournalTrans inventJournalTrans;
当进入到盘点行时就会操作inventJournalTrans
首先:
当你新建一条盘点记录时就会触发去计算盘点数,这时会用到inventDim,而inventDim是在InventMovement中声明的,会使用InventMovement的:
InventDim inventdim(InventDim _inventDim = inventDim)
{
;
inventDim = _inventDim;
if (!inventDim)
inventDim = InventDim::find(this.inventDimId());
return inventDim;
}
来得到inventDim,如果!inventDim则会调用table:inventDim的find方法:
static public InventDim find(InventDimId inventDimId, boolean _forupdate = false)
{
InventDim inventDim;
;
if (inventDimId)
{
if (_forupdate)
inventDim.selectForUpdate(_forupdate);
select firstonly inventDim
index hint DimIdIdx
where inventDim.InventDimId == inventDimId;
}
return inventDim;
}
这样,你就知道:
InventQty dateOnHandPhysical(InventDim _inventDim)
中的参数是从那里来的了,当你新建时你拿到一个新定义的inventdim,你在图二中的记录中添加记录实际就是在修改这个inventdim。
然后:
InventQty dateOnHandPhysical(InventDim _inventDim)
{
InventDimParm _inventDimParm;
;
//下边这句根据先前的inventDim构造一个_InventDimParm
_inventDimParm.initFromInventDim(_inventDim);
_inventDimParm = InventDimParm::orParms(_inventDimParm,InventJournalTable::journalId2inventDimParm(inventJournalTrans.JournalId));
return InventSumDatePhysicalDim::onHandQty(inventJournalTrans.TransDate,inventJournalTrans.ItemId,_inventDim,_inventDimParm);
}
以上这段代码中的:InventJournalTable::journalId2inventDimParm:
static InventDimParm journalId2inventDimParm(InventJournalId inventJournalId)
{
InventDimParm inventDimParm;
;
InventDimFixedClass::inventDimFixed2InventDimParm(InventJournalTable::find(inventJournalId).InventDimFixed,inventDimParm);
return inventDimParm;
}
会根据inventJournalTable中的字段InventDimFixed来构造一个inventDimParm.
而这个字段是这样得来的:
在新建一条记录时会弹出:
InventDimFixed是一个0~255的整数,上图的八个维度分别对应一个字节的8位,如果该维度选中,则该位为一:
Color |
Size |
Config |
Serial |
Pallet |
Location |
Batch |
warehouse |
128 |
64 |
32 |
16 |
8 |
4 |
2 |
1 |
InventJournalTable会调用InventDimFixedClass类来初始这个字段,最核心的代码是:
InventDimFixed inventDimFixed()
{
InventDimFixed inventDimFixed;
;
#inventDimDevelop
if (inventDimParm.inventLocationIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #INVENTLOCATIONID_IDX);
if (inventDimParm.inventBatchIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #BATCH_IDX);
if (inventDimParm.WMSLocationIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #LOCATION_IDX);
if (inventDimParm.WMSPalletIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #PALLET_IDX);
if (inventDimParm.inventSerialIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #SERIALID_IDX);
if (inventDimParm.configIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #CONFIGID_IDX);
if (inventDimParm.inventSizeIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #INVENTSIZEID_IDX);
if (inventDimParm.inventColorIdFlag) inventDimFixed = InventDimFixedClass::setField(inventDimFixed, #INVENTCOLORID_IDX);
return inventDimFixed;
}
查看该类的声明可以看到:
public class InventDimFixedClass
{
InventDimParm inventDimParm;
#DEFINE.INVENTLOCATIONID_IDX(0)
#DEFINE.BATCH_IDX(1)
#DEFINE.LOCATION_IDX(2)
#DEFINE.PALLET_IDX(3)
#DEFINE.SERIALID_IDX(4)
#DEFINE.CONFIGID_IDX(5)
#DEFINE.INVENTSIZEID_IDX(6)
#DEFINE.INVENTCOLORID_IDX(7)
// Indexes 0..15 reserved for the SYS layer
// Indexes 16..30 reserved for distributors, vars and customers
#INVENTDIMDEVELOP
}
而setField是这样执行的:
static InventDimFixed setField(InventDimFixed inventDimFixed, Integer idx)
{
;
inventDimFixed = inventDimFixed | (1 << idx);
return inventDimFixed;
}
也就是它同1按位或出一个结果.
继续看代码:
InventQty dateOnHandPhysical(InventDim _inventDim)
{
InventDimParm _inventDimParm;
;
//下边这句根据先前的inventDim构造一个_InventDimParm
_inventDimParm.initFromInventDim(_inventDim);
_inventDimParm = InventDimParm::orParms(_inventDimParm,InventJournalTable::journalId2inventDimParm(inventJournalTrans.JournalId));
return InventSumDatePhysicalDim::onHandQty(inventJournalTrans.TransDate,inventJournalTrans.ItemId,_inventDim,_inventDimParm);
}
两个inventDimParm按位或,得到一个inventDimParm,然后使用onHandQty开始计算输入日期的某维度物料的结存量:
server static InventQty onHandQty(
TransDate _transDate,
ItemId _itemId,
InventDim _inventDim,
InventDimParm _inventDimParm
)
{
InventSumDatePhysicalDim inventSumDatePhysicalDim = InventSumDatePhysicalDim::newParameters(_transDate,_itemId,_inventDim,_inventDimParm);
;
return inventSumDatePhysicalDim.postedQty() +
inventSumDatePhysicalDim.receivedQty() -
inventSumDatePhysicalDim.deductedQty() -
inventSumDatePhysicalDim.pickedQty() +
inventSumDatePhysicalDim.registeredQty();
}
会去构造一个类InventSumDatePhysicalDim去计算结存.
最终先会使用InventSumDatePhysicalDim的方法selectInventTransPicked, selectInventTransPostingFinancial, selectInventTransPostingPhysical, selectInventTransRegistered,
这四个方法会结合两个宏语句来查询各种日期大于查询日期的交易记录,从InventSum表中查询到当前结存量,然后将当前日期与查询日期中间的交易数量按实际出入加减,得到查询日期时的结存量.
这两个宏分别为:# InventDimSelect,
# InventDimExistsJoin:
exists join tableId from %2
where (%2.InventDimId == %1) &&
(%2.ConfigId == %3.ConfigId || ! %4.ConfigIdFlag) &&
(%2.InventSizeId == %3.InventSizeId || ! %4.InventSizeIdFlag) &&
(%2.InventColorId == %3.InventColorId || ! %4.InventColorIdFlag) &&
(%2.InventLocationId == %3.InventLocationId || ! %4.InventLocationIdFlag) &&
(%2.InventBatchId == %3.InventBatchId || ! %4.InventBatchIdFlag) &&
(%2.WMSLocationId == %3.WMSLocationId || ! %4.WMSLocationIdFlag) &&
(%2.WMSPalletId == %3.WMSPalletId || ! %4.WMSPalletIdFlag) &&
(%2.InventSerialId == %3.InventSerialId || ! %4.InventSerialIdFlag)
#InventDimDevelop
这个宏实现了:如果你选择了某种维度,那么就必须用你所填写的维度去匹配数据库中的维度表来查找相应数据.如果你没有选择这种维度,则对于这一维度全部匹配.
最后说说我们怎么使用它:
以一个例子来说吧:
如果你要查询物料B-Pack1,维度为: 仓库:GW ,SIZE:5,Color:红色 在4/22/2008的结存量
可以这样:
InventDim inventDim;
InventDimParm _inventDimParm;
Date _date;
ItemId itemId;
;
inventDim.inventColorId = “红色”;
inventDim.inventSizeId = 5;
inventDim.inventLocationId = “gw”;
_inventDimParm.initFromInventDim(_inventDim);
_date = 22/4/2008;
itemId = “b-pack1”;
return InventSumDatePhysicalDim::onHandQty(_date,iItemId,inventDim,_inventDimParm);