IDEMPIERE-5121 MStorageOnHand API enhancements (#1079)
This commit is contained in:
parent
a3872deb23
commit
93ebe43cbd
|
@ -191,7 +191,6 @@ public class CalloutInOut extends CalloutEngine
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
{
|
{
|
||||||
// Set Movement Type
|
// Set Movement Type
|
||||||
String DocBaseType = rs.getString("DocBaseType");
|
|
||||||
// BF [2708789] Read IsSOTrx from C_DocType
|
// BF [2708789] Read IsSOTrx from C_DocType
|
||||||
String trxFlag = rs.getString("IsSOTrx");
|
String trxFlag = rs.getString("IsSOTrx");
|
||||||
Object isSOTrxValue = mTab.getValue("IsSOTrx");
|
Object isSOTrxValue = mTab.getValue("IsSOTrx");
|
||||||
|
|
|
@ -1456,7 +1456,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Storage - see also VMatch.createMatchRecord
|
// Update Storage - see also VMatch.createMatchRecord
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
sLine.getM_Locator_ID(),
|
sLine.getM_Locator_ID(),
|
||||||
sLine.getM_Product_ID(),
|
sLine.getM_Product_ID(),
|
||||||
ma.getM_AttributeSetInstance_ID(),
|
ma.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -1545,7 +1545,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
} else if (storage.getQtyOnHand().signum() > 0) {
|
} else if (storage.getQtyOnHand().signum() > 0) {
|
||||||
BigDecimal onHand = storage.getQtyOnHand();
|
BigDecimal onHand = storage.getQtyOnHand();
|
||||||
// this locator has less qty than required, ship all qtyonhand and iterate to next locator
|
// this locator has less qty than required, ship all qtyonhand and iterate to next locator
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
sLine.getM_Locator_ID(),
|
sLine.getM_Locator_ID(),
|
||||||
sLine.getM_Product_ID(),
|
sLine.getM_Product_ID(),
|
||||||
sLine.getM_AttributeSetInstance_ID(),
|
sLine.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -1578,7 +1578,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
|
|
||||||
// Fallback: Update Storage - see also VMatch.createMatchRecord
|
// Fallback: Update Storage - see also VMatch.createMatchRecord
|
||||||
if (pendingQty.signum() != 0 &&
|
if (pendingQty.signum() != 0 &&
|
||||||
!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
!MStorageOnHand.add(getCtx(),
|
||||||
sLine.getM_Locator_ID(),
|
sLine.getM_Locator_ID(),
|
||||||
sLine.getM_Product_ID(),
|
sLine.getM_Product_ID(),
|
||||||
sLine.getM_AttributeSetInstance_ID(),
|
sLine.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -2671,7 +2671,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (reversal) {
|
if (reversal) {
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), 0, qty.negate(), dateMaterialPolicy, trxName)) {
|
if (!MStorageOnHand.add(getCtx(), M_Locator_ID, product.getM_Product_ID(), 0, qty.negate(), dateMaterialPolicy, trxName)) {
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
String lastError = CLogger.retrieveErrorString("");
|
||||||
m_processMsg = "Cannot move Inventory OnHand to Non ASI [" + product.getValue() + "] - " + lastError;
|
m_processMsg = "Cannot move Inventory OnHand to Non ASI [" + product.getValue() + "] - " + lastError;
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
|
@ -2683,7 +2683,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
m_processMsg = "Transaction From not inserted (MA) [" + product.getValue() + "] - ";
|
m_processMsg = "Transaction From not inserted (MA) [" + product.getValue() + "] - ";
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty, dateMaterialPolicy, trxName)) {
|
if (!MStorageOnHand.add(getCtx(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty, dateMaterialPolicy, trxName)) {
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
String lastError = CLogger.retrieveErrorString("");
|
||||||
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
|
@ -2741,7 +2741,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
if (!reversal && toMove.compareTo(onhand.getQtyOnHand()) >= 0) {
|
if (!reversal && toMove.compareTo(onhand.getQtyOnHand()) >= 0) {
|
||||||
toMove = onhand.getQtyOnHand();
|
toMove = onhand.getQtyOnHand();
|
||||||
}
|
}
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), 0, toMove.negate(), onhand.getDateMaterialPolicy(), trxName)) {
|
if (!MStorageOnHand.add(getCtx(), M_Locator_ID, product.getM_Product_ID(), 0, toMove.negate(), onhand.getDateMaterialPolicy(), trxName)) {
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
String lastError = CLogger.retrieveErrorString("");
|
||||||
m_processMsg = "Cannot move Inventory OnHand to Non ASI [" + product.getValue() + "] - " + lastError;
|
m_processMsg = "Cannot move Inventory OnHand to Non ASI [" + product.getValue() + "] - " + lastError;
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
|
@ -2758,7 +2758,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
if ((!reversal && totalToMove.signum() <= 0) || (reversal && totalToMove.signum() >= 0))
|
if ((!reversal && totalToMove.signum() <= 0) || (reversal && totalToMove.signum() >= 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty,
|
if (!MStorageOnHand.add(getCtx(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty,
|
||||||
(dateMaterialPolicy != null ? dateMaterialPolicy : onHandDateMaterialPolicy), trxName)) {
|
(dateMaterialPolicy != null ? dateMaterialPolicy : onHandDateMaterialPolicy), trxName)) {
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
String lastError = CLogger.retrieveErrorString("");
|
||||||
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||||
|
|
|
@ -559,7 +559,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("Diff=" + qtyDiff
|
if (log.isLoggable(Level.FINE)) log.fine("Diff=" + qtyDiff
|
||||||
+ " - Instance OnHand=" + QtyMA + "->" + QtyNew);
|
+ " - Instance OnHand=" + QtyMA + "->" + QtyNew);
|
||||||
|
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
line.getM_Locator_ID(),
|
line.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
ma.getM_AttributeSetInstance_ID(),
|
ma.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -617,7 +617,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fallback: Update Storage - see also VMatch.createMatchRecord
|
//Fallback: Update Storage - see also VMatch.createMatchRecord
|
||||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
line.getM_Locator_ID(),
|
line.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
line.getM_AttributeSetInstance_ID(),
|
line.getM_AttributeSetInstance_ID(),
|
||||||
|
|
|
@ -444,9 +444,8 @@ public class MMovement extends X_M_Movement implements DocAction
|
||||||
{
|
{
|
||||||
MMovementLineMA ma = mas[j];
|
MMovementLineMA ma = mas[j];
|
||||||
//
|
//
|
||||||
MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName());
|
|
||||||
//Update Storage
|
//Update Storage
|
||||||
if (!MStorageOnHand.add(getCtx(),locator.getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
line.getM_Locator_ID(),
|
line.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
ma.getM_AttributeSetInstance_ID(),
|
ma.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -464,8 +463,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
||||||
M_AttributeSetInstanceTo_ID = ma.getM_AttributeSetInstance_ID();
|
M_AttributeSetInstanceTo_ID = ma.getM_AttributeSetInstance_ID();
|
||||||
}
|
}
|
||||||
//Update Storage
|
//Update Storage
|
||||||
MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName());
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
if (!MStorageOnHand.add(getCtx(),locatorTo.getM_Warehouse_ID(),
|
|
||||||
line.getM_LocatorTo_ID(),
|
line.getM_LocatorTo_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
M_AttributeSetInstanceTo_ID,
|
M_AttributeSetInstanceTo_ID,
|
||||||
|
@ -528,12 +526,11 @@ public class MMovement extends X_M_Movement implements DocAction
|
||||||
if (dateMPolicy == null && storages.length > 0)
|
if (dateMPolicy == null && storages.length > 0)
|
||||||
dateMPolicy = storages[0].getDateMaterialPolicy();
|
dateMPolicy = storages[0].getDateMaterialPolicy();
|
||||||
|
|
||||||
MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName());
|
|
||||||
//Update Storage
|
//Update Storage
|
||||||
Timestamp effDateMPolicy = dateMPolicy;
|
Timestamp effDateMPolicy = dateMPolicy;
|
||||||
if (dateMPolicy == null && line.getMovementQty().negate().signum() > 0)
|
if (dateMPolicy == null && line.getMovementQty().negate().signum() > 0)
|
||||||
effDateMPolicy = getMovementDate();
|
effDateMPolicy = getMovementDate();
|
||||||
if (!MStorageOnHand.add(getCtx(),locator.getM_Warehouse_ID(),
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
line.getM_Locator_ID(),
|
line.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
line.getM_AttributeSetInstance_ID(),
|
line.getM_AttributeSetInstance_ID(),
|
||||||
|
@ -548,8 +545,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
||||||
effDateMPolicy = dateMPolicy;
|
effDateMPolicy = dateMPolicy;
|
||||||
if (dateMPolicy == null && line.getMovementQty().signum() > 0)
|
if (dateMPolicy == null && line.getMovementQty().signum() > 0)
|
||||||
effDateMPolicy = getMovementDate();
|
effDateMPolicy = getMovementDate();
|
||||||
MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName());
|
if (!MStorageOnHand.add(getCtx(),
|
||||||
if (!MStorageOnHand.add(getCtx(),locatorTo.getM_Warehouse_ID(),
|
|
||||||
line.getM_LocatorTo_ID(),
|
line.getM_LocatorTo_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
line.getM_AttributeSetInstanceTo_ID(),
|
line.getM_AttributeSetInstanceTo_ID(),
|
||||||
|
|
|
@ -178,8 +178,6 @@ public class MProjectIssue extends X_C_ProjectIssue implements DocAction, DocOpt
|
||||||
getMovementQty().negate(), getMovementDate(), get_TrxName());
|
getMovementQty().negate(), getMovementDate(), get_TrxName());
|
||||||
mTrx.setC_ProjectIssue_ID(getC_ProjectIssue_ID());
|
mTrx.setC_ProjectIssue_ID(getC_ProjectIssue_ID());
|
||||||
//
|
//
|
||||||
MLocator loc = MLocator.get(getCtx(), getM_Locator_ID());
|
|
||||||
|
|
||||||
Timestamp dateMPolicy = getMovementDate();
|
Timestamp dateMPolicy = getMovementDate();
|
||||||
|
|
||||||
if(getM_AttributeSetInstance_ID()>0){
|
if(getM_AttributeSetInstance_ID()>0){
|
||||||
|
@ -217,14 +215,14 @@ public class MProjectIssue extends X_C_ProjectIssue implements DocAction, DocOpt
|
||||||
}
|
}
|
||||||
if (qtyToIssue.signum() > 0)
|
if (qtyToIssue.signum() > 0)
|
||||||
{
|
{
|
||||||
ok = MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
|
ok = MStorageOnHand.add(getCtx(), getM_Locator_ID(),
|
||||||
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
||||||
qtyToIssue.negate(),dateMPolicy, get_TrxName());
|
qtyToIssue.negate(),dateMPolicy, get_TrxName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ok = MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
|
ok = MStorageOnHand.add(getCtx(), getM_Locator_ID(),
|
||||||
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
||||||
getMovementQty().negate(),dateMPolicy, get_TrxName());
|
getMovementQty().negate(),dateMPolicy, get_TrxName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
* Get all Storages for Product where QtyOnHand <> 0
|
* Get all Storages for Product where QtyOnHand <> 0
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
* @param M_Product_ID product
|
* @param M_Product_ID product
|
||||||
* @param M_Locator_ID locator
|
* @param M_Locator_ID locator, 0 to match all locator
|
||||||
* @param trxName transaction
|
* @param trxName transaction
|
||||||
* @return existing or null
|
* @return existing or null
|
||||||
*/
|
*/
|
||||||
|
@ -163,25 +163,68 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
* Get all Storages for Product where QtyOnHand <> 0
|
* Get all Storages for Product where QtyOnHand <> 0
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
* @param M_Product_ID product
|
* @param M_Product_ID product
|
||||||
* @param M_Locator_ID locator
|
* @param M_Locator_ID locator, 0 to match all locator
|
||||||
* @param trxName transaction
|
* @param trxName transaction
|
||||||
* @return existing or null
|
* @return existing or null
|
||||||
*/
|
*/
|
||||||
public static MStorageOnHand[] getAll (Properties ctx,
|
public static MStorageOnHand[] getAll (Properties ctx,
|
||||||
int M_Product_ID, int M_Locator_ID, String trxName, boolean forUpdate, int timeout)
|
int M_Product_ID, int M_Locator_ID, String trxName, boolean forUpdate, int timeout)
|
||||||
{
|
{
|
||||||
String sqlWhere = "M_Product_ID=? AND M_Locator_ID=? AND QtyOnHand <> 0";
|
return getAll(ctx, M_Product_ID, M_Locator_ID, false, true, trxName, forUpdate, timeout);
|
||||||
Query query = new Query(ctx, MStorageOnHand.Table_Name, sqlWhere, trxName)
|
}
|
||||||
.setParameters(M_Product_ID, M_Locator_ID);
|
|
||||||
|
/**
|
||||||
|
* Get all Storages for Product where QtyOnHand <> 0
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_Locator_ID locator, 0 to match all locator
|
||||||
|
* @param locatorPriority If true, sort descending by locator Priority No
|
||||||
|
* @param fifo Sort ascending(fifo) or descending(lifo) by date material policy, m_attributesetinstance_id
|
||||||
|
* @param trxName transaction
|
||||||
|
* @param forUpdate If true, acquire db lock for update
|
||||||
|
* @param timeout timeout for the acquisition of db update lock
|
||||||
|
* @return existing or null
|
||||||
|
*/
|
||||||
|
public static MStorageOnHand[] getAll (Properties ctx,
|
||||||
|
int M_Product_ID, int M_Locator_ID, boolean locatorPriority, boolean fifo, String trxName, boolean forUpdate, int timeout)
|
||||||
|
{
|
||||||
|
String sqlWhere = "M_Product_ID=? AND QtyOnHand <> 0";
|
||||||
|
if (M_Locator_ID > 0)
|
||||||
|
sqlWhere = sqlWhere + " AND M_Locator_ID=? ";
|
||||||
|
Query query = new Query(ctx, MStorageOnHand.Table_Name, sqlWhere, trxName);
|
||||||
|
if (M_Locator_ID > 0)
|
||||||
|
query.setParameters(M_Product_ID, M_Locator_ID);
|
||||||
|
else
|
||||||
|
query.setParameters(M_Product_ID);
|
||||||
MProduct product = MProduct.get(ctx, M_Product_ID);
|
MProduct product = MProduct.get(ctx, M_Product_ID);
|
||||||
|
StringBuilder orderBy = new StringBuilder();
|
||||||
|
if (locatorPriority)
|
||||||
|
{
|
||||||
|
query.addJoinClause("JOIN M_Locator locator ON (M_StorageOnHand.M_Locator_ID=locator.M_Locator_ID) ");
|
||||||
|
orderBy.append("locator.PriorityNo DESC, ");
|
||||||
|
}
|
||||||
if (product.isUseGuaranteeDateForMPolicy())
|
if (product.isUseGuaranteeDateForMPolicy())
|
||||||
{
|
{
|
||||||
query.addJoinClause(" LEFT OUTER JOIN M_AttributeSetInstance asi ON (M_StorageOnHand.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) ")
|
query.addJoinClause(" LEFT OUTER JOIN M_AttributeSetInstance asi ON (M_StorageOnHand.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) ");
|
||||||
.setOrderBy("asi."+I_M_AttributeSetInstance.COLUMNNAME_GuaranteeDate);
|
orderBy.append("asi.").append(I_M_AttributeSetInstance.COLUMNNAME_GuaranteeDate);
|
||||||
|
if (!fifo)
|
||||||
|
orderBy.append(" DESC");
|
||||||
|
orderBy.append(", ");
|
||||||
|
orderBy.append(MStorageOnHand.Table_Name).append(".").append(MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID);
|
||||||
|
if (!fifo)
|
||||||
|
orderBy.append(" DESC");
|
||||||
|
query.setOrderBy(orderBy.toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query.setOrderBy(MStorageOnHand.COLUMNNAME_DateMaterialPolicy+","+ MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID);
|
orderBy.append(MStorageOnHand.Table_Name).append(".").append(MStorageOnHand.COLUMNNAME_DateMaterialPolicy);
|
||||||
|
if (!fifo)
|
||||||
|
orderBy.append(" DESC");
|
||||||
|
orderBy.append(", ");
|
||||||
|
orderBy.append(MStorageOnHand.Table_Name).append(".").append(MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID);
|
||||||
|
if (!fifo)
|
||||||
|
orderBy.append(" DESC");
|
||||||
|
query.setOrderBy(orderBy.toString());
|
||||||
}
|
}
|
||||||
if (forUpdate)
|
if (forUpdate)
|
||||||
{
|
{
|
||||||
|
@ -680,7 +723,28 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
* Update Storage Info add.
|
* Update Storage Info add.
|
||||||
* Called from MProjectIssue
|
* Called from MProjectIssue
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
* @param M_Warehouse_ID warehouse
|
* @param M_Warehouse_ID warehouse, not use
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID AS Instance
|
||||||
|
* @param reservationAttributeSetInstance_ID reservation AS Instance
|
||||||
|
* @param diffQtyOnHand add on hand
|
||||||
|
* @param dateMPolicy
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return true if updated
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID,
|
||||||
|
BigDecimal diffQtyOnHand,Timestamp dateMPolicy, String trxName)
|
||||||
|
{
|
||||||
|
return add(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, diffQtyOnHand, dateMPolicy, trxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Storage Info add.
|
||||||
|
* Called from MProjectIssue
|
||||||
|
* @param ctx context
|
||||||
* @param M_Locator_ID locator
|
* @param M_Locator_ID locator
|
||||||
* @param M_Product_ID product
|
* @param M_Product_ID product
|
||||||
* @param M_AttributeSetInstance_ID AS Instance
|
* @param M_AttributeSetInstance_ID AS Instance
|
||||||
|
@ -690,7 +754,7 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
* @param trxName transaction
|
* @param trxName transaction
|
||||||
* @return true if updated
|
* @return true if updated
|
||||||
*/
|
*/
|
||||||
public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID,
|
public static boolean add (Properties ctx, int M_Locator_ID,
|
||||||
int M_Product_ID, int M_AttributeSetInstance_ID,
|
int M_Product_ID, int M_AttributeSetInstance_ID,
|
||||||
BigDecimal diffQtyOnHand,Timestamp dateMPolicy, String trxName)
|
BigDecimal diffQtyOnHand,Timestamp dateMPolicy, String trxName)
|
||||||
{
|
{
|
||||||
|
@ -744,10 +808,10 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
* Get Location with highest Locator Priority and a sufficient OnHand Qty
|
* Get Location with highest Locator Priority and a sufficient OnHand Qty
|
||||||
* @param M_Warehouse_ID warehouse
|
* @param M_Warehouse_ID warehouse
|
||||||
* @param M_Product_ID product
|
* @param M_Product_ID product
|
||||||
* @param M_AttributeSetInstance_ID asi
|
* @param M_AttributeSetInstance_ID asi id, use negative value (for e.g -1) to match all asi including 0
|
||||||
* @param Qty qty
|
* @param Qty qty
|
||||||
* @param trxName transaction
|
* @param trxName transaction
|
||||||
* @return id
|
* @return locator id (0 if no match found)
|
||||||
*/
|
*/
|
||||||
public static int getM_Locator_ID (int M_Warehouse_ID,
|
public static int getM_Locator_ID (int M_Warehouse_ID,
|
||||||
int M_Product_ID, int M_AttributeSetInstance_ID, BigDecimal Qty,
|
int M_Product_ID, int M_AttributeSetInstance_ID, BigDecimal Qty,
|
||||||
|
@ -758,12 +822,14 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
String sql = "SELECT s.M_Locator_ID, s.QtyOnHand "
|
String sql = "SELECT s.M_Locator_ID, s.QtyOnHand "
|
||||||
+ "FROM M_StorageOnHand s"
|
+ "FROM M_StorageOnHand s"
|
||||||
+ " INNER JOIN M_Locator l ON (s.M_Locator_ID=l.M_Locator_ID)"
|
+ " INNER JOIN M_Locator l ON (s.M_Locator_ID=l.M_Locator_ID)"
|
||||||
+ " INNER JOIN M_Product p ON (s.M_Product_ID=p.M_Product_ID)"
|
+ " INNER JOIN M_Product p ON (s.M_Product_ID=p.M_Product_ID) ";
|
||||||
+ " LEFT OUTER JOIN M_AttributeSet mas ON (p.M_AttributeSet_ID=mas.M_AttributeSet_ID) "
|
if (M_AttributeSetInstance_ID >= 0)
|
||||||
+ "WHERE l.M_Warehouse_ID=?"
|
sql = sql + " LEFT OUTER JOIN M_AttributeSet mas ON (p.M_AttributeSet_ID=mas.M_AttributeSet_ID) ";
|
||||||
+ " AND s.M_Product_ID=?"
|
sql = sql + "WHERE l.M_Warehouse_ID=? "
|
||||||
+ " AND (mas.IsInstanceAttribute IS NULL OR mas.IsInstanceAttribute='N' OR s.M_AttributeSetInstance_ID=?)"
|
+ " AND s.M_Product_ID=? ";
|
||||||
+ " AND l.IsActive='Y' "
|
if (M_AttributeSetInstance_ID >= 0)
|
||||||
|
sql = sql + " AND (mas.IsInstanceAttribute IS NULL OR mas.IsInstanceAttribute='N' OR s.M_AttributeSetInstance_ID=?) ";
|
||||||
|
sql = sql + " AND l.IsActive='Y' "
|
||||||
+ "ORDER BY l.PriorityNo DESC, s.QtyOnHand DESC";
|
+ "ORDER BY l.PriorityNo DESC, s.QtyOnHand DESC";
|
||||||
|
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
|
@ -773,6 +839,7 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
||||||
pstmt = DB.prepareStatement(sql, trxName);
|
pstmt = DB.prepareStatement(sql, trxName);
|
||||||
pstmt.setInt(1, M_Warehouse_ID);
|
pstmt.setInt(1, M_Warehouse_ID);
|
||||||
pstmt.setInt(2, M_Product_ID);
|
pstmt.setInt(2, M_Product_ID);
|
||||||
|
if (M_AttributeSetInstance_ID >= 0)
|
||||||
pstmt.setInt(3, M_AttributeSetInstance_ID);
|
pstmt.setInt(3, M_AttributeSetInstance_ID);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
while (rs.next())
|
while (rs.next())
|
||||||
|
|
|
@ -881,7 +881,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
||||||
if (product.isStocked())
|
if (product.isStocked())
|
||||||
{
|
{
|
||||||
// Update Storage
|
// Update Storage
|
||||||
if (!MStorageOnHand.add(getCtx(), locator_to.getM_Warehouse_ID(), locator_to.getM_Locator_ID(),
|
if (!MStorageOnHand.add(getCtx(), locator_to.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
line.getM_AttributeSetInstance_ID(),
|
line.getM_AttributeSetInstance_ID(),
|
||||||
Env.ZERO,null, get_TrxName()))
|
Env.ZERO,null, get_TrxName()))
|
||||||
|
@ -889,7 +889,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
||||||
throw new AdempiereException();
|
throw new AdempiereException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MStorageOnHand.add(getCtx(), locator_from.getM_Warehouse_ID(), locator_from.getM_Locator_ID(),
|
if (!MStorageOnHand.add(getCtx(), locator_from.getM_Locator_ID(),
|
||||||
line.getM_Product_ID(),
|
line.getM_Product_ID(),
|
||||||
line.getM_AttributeSetInstanceTo_ID(),
|
line.getM_AttributeSetInstanceTo_ID(),
|
||||||
Env.ZERO,null, get_TrxName()))
|
Env.ZERO,null, get_TrxName()))
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.test.model;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
import org.compiere.model.MAttributeSet;
|
||||||
|
import org.compiere.model.MAttributeSetInstance;
|
||||||
|
import org.compiere.model.MLocator;
|
||||||
|
import org.compiere.model.MProduct;
|
||||||
|
import org.compiere.model.MStorageOnHand;
|
||||||
|
import org.compiere.util.CacheMgt;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.TimeUtil;
|
||||||
|
import org.idempiere.test.AbstractTestCase;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MStorageOnHandTest extends AbstractTestCase {
|
||||||
|
|
||||||
|
private final static int FERTILIZER_LOT_ATTRIBUTESET_ID = 101;
|
||||||
|
private final static int HQ_LOCATOR_ID = 101;
|
||||||
|
private final static int STORE_LOCATOR_ID = 102;
|
||||||
|
private static final int TAX_CATEGORY_STANDARD_ID = 107;
|
||||||
|
private static final int CHEMICALS_CATEGORY_ID = 109;
|
||||||
|
private static final int UOM_EACH_ID = 100;
|
||||||
|
|
||||||
|
public MStorageOnHandTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAll() {
|
||||||
|
//storageonhand api doesn't use trx to retrieve product
|
||||||
|
MProduct product = new MProduct(Env.getCtx(), 0, null);
|
||||||
|
product.setName("testGetAll");
|
||||||
|
product.setM_AttributeSet_ID(FERTILIZER_LOT_ATTRIBUTESET_ID);
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||||
|
product.setC_UOM_ID(UOM_EACH_ID);
|
||||||
|
product.setM_Product_Category_ID(CHEMICALS_CATEGORY_ID);
|
||||||
|
product.setC_TaxCategory_ID(TAX_CATEGORY_STANDARD_ID);
|
||||||
|
product.saveEx();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Timestamp today = TimeUtil.getDay(null);
|
||||||
|
Timestamp tomorrow = TimeUtil.addDays(today, 1);
|
||||||
|
MStorageOnHand.add(Env.getCtx(), HQ_LOCATOR_ID, product.get_ID(), 0, new BigDecimal("1"), today, getTrxName());
|
||||||
|
MStorageOnHand.add(Env.getCtx(), STORE_LOCATOR_ID, product.get_ID(), 0, new BigDecimal("2"), tomorrow, getTrxName());
|
||||||
|
|
||||||
|
MStorageOnHand[] onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), HQ_LOCATOR_ID, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(1, onhands.length);
|
||||||
|
assertEquals(HQ_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(1, onhands[0].getQtyOnHand().intValue());
|
||||||
|
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), STORE_LOCATOR_ID, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(1, onhands.length);
|
||||||
|
assertEquals(STORE_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(2, onhands[0].getQtyOnHand().intValue());
|
||||||
|
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(2, onhands.length);
|
||||||
|
|
||||||
|
//test locator priority
|
||||||
|
MLocator locator = new MLocator(Env.getCtx(), STORE_LOCATOR_ID, getTrxName());
|
||||||
|
locator.setPriorityNo(Integer.MAX_VALUE);
|
||||||
|
locator.saveEx();
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, true, true, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(2, onhands.length);
|
||||||
|
assertEquals(STORE_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(2, onhands[0].getQtyOnHand().intValue());
|
||||||
|
|
||||||
|
//test fifo
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, false, true, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(2, onhands.length);
|
||||||
|
assertEquals(HQ_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(1, onhands[0].getQtyOnHand().intValue());
|
||||||
|
|
||||||
|
//test lifo
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, false, false, getTrxName(), false, 0);
|
||||||
|
assertNotNull(onhands);
|
||||||
|
assertEquals(2, onhands.length);
|
||||||
|
assertEquals(STORE_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(2, onhands[0].getQtyOnHand().intValue());
|
||||||
|
|
||||||
|
//test UseGuaranteeDateForMPolicy
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, false, true, getTrxName(), false, 0);
|
||||||
|
assertEquals(HQ_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(1, onhands[0].getQtyOnHand().intValue());
|
||||||
|
MAttributeSet as = new MAttributeSet(Env.getCtx(), FERTILIZER_LOT_ATTRIBUTESET_ID, null);
|
||||||
|
try {
|
||||||
|
as.setUseGuaranteeDateForMPolicy(true);
|
||||||
|
as.saveEx();
|
||||||
|
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||||
|
asi1.setM_AttributeSet_ID(FERTILIZER_LOT_ATTRIBUTESET_ID);
|
||||||
|
asi1.setGuaranteeDate(tomorrow);
|
||||||
|
asi1.saveEx();
|
||||||
|
DB.executeUpdateEx("UPDATE M_StorageOnHand SET M_AttributeSetInstance_ID=? WHERE M_StorageOnHand_UU=?", new Object[] {asi1.get_ID(), onhands[0].getM_StorageOnHand_UU()}, getTrxName());
|
||||||
|
MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||||
|
asi2.setM_AttributeSet_ID(FERTILIZER_LOT_ATTRIBUTESET_ID);
|
||||||
|
asi2.setGuaranteeDate(today);
|
||||||
|
asi2.saveEx();
|
||||||
|
DB.executeUpdateEx("UPDATE M_StorageOnHand SET M_AttributeSetInstance_ID=? WHERE M_StorageOnHand_UU=?", new Object[] {asi2.get_ID(), onhands[1].getM_StorageOnHand_UU()}, getTrxName());
|
||||||
|
CacheMgt.get().reset(MProduct.Table_Name, product.get_ID());
|
||||||
|
onhands = MStorageOnHand.getAll(Env.getCtx(), product.get_ID(), 0, false, true, getTrxName(), false, 0);
|
||||||
|
assertEquals(asi2.get_ID(), onhands[0].getM_AttributeSetInstance_ID());
|
||||||
|
assertEquals(STORE_LOCATOR_ID, onhands[0].getM_Locator_ID());
|
||||||
|
assertEquals(2, onhands[0].getQtyOnHand().intValue());
|
||||||
|
} finally {
|
||||||
|
as.setUseGuaranteeDateForMPolicy(false);
|
||||||
|
as.saveEx();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
product.deleteEx(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetM_Locator_ID() {
|
||||||
|
MLocator hqLocator = new MLocator(Env.getCtx(), HQ_LOCATOR_ID, getTrxName());
|
||||||
|
MLocator hqLocator1 = new MLocator(Env.getCtx(), 0, getTrxName());
|
||||||
|
hqLocator1.setM_Warehouse_ID(hqLocator.getM_Warehouse_ID());
|
||||||
|
hqLocator1.setValue("HQ Locator 1");
|
||||||
|
hqLocator1.setPriorityNo(hqLocator.getPriorityNo());
|
||||||
|
hqLocator1.setX("x");
|
||||||
|
hqLocator1.setY("y");
|
||||||
|
hqLocator1.setZ("z");
|
||||||
|
hqLocator1.saveEx();
|
||||||
|
|
||||||
|
MProduct product = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||||
|
product.setName("testGetM_Locator_ID");
|
||||||
|
product.setM_AttributeSet_ID(FERTILIZER_LOT_ATTRIBUTESET_ID);
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||||
|
product.setC_UOM_ID(UOM_EACH_ID);
|
||||||
|
product.setM_Product_Category_ID(CHEMICALS_CATEGORY_ID);
|
||||||
|
product.setC_TaxCategory_ID(TAX_CATEGORY_STANDARD_ID);
|
||||||
|
product.saveEx();
|
||||||
|
|
||||||
|
Timestamp today = TimeUtil.getDay(null);
|
||||||
|
MStorageOnHand.add(Env.getCtx(), HQ_LOCATOR_ID, product.get_ID(), 0, new BigDecimal("2"), today, getTrxName());
|
||||||
|
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||||
|
asi1.setM_AttributeSet_ID(FERTILIZER_LOT_ATTRIBUTESET_ID);
|
||||||
|
asi1.setLot("Lot1");
|
||||||
|
asi1.saveEx();
|
||||||
|
MStorageOnHand.add(Env.getCtx(), hqLocator1.get_ID(), product.get_ID(), asi1.get_ID(), new BigDecimal("1"), today, getTrxName());
|
||||||
|
|
||||||
|
//get asi=0
|
||||||
|
int M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), 0, new BigDecimal("1"), getTrxName());
|
||||||
|
assertEquals(HQ_LOCATOR_ID, M_Locator_ID);
|
||||||
|
//get asi>0
|
||||||
|
M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), asi1.get_ID(), new BigDecimal("1"), getTrxName());
|
||||||
|
assertEquals(hqLocator1.get_ID(), M_Locator_ID);
|
||||||
|
//check all asi and get locator with highest onhand
|
||||||
|
M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), -1, new BigDecimal("1"), getTrxName());
|
||||||
|
assertEquals(HQ_LOCATOR_ID, M_Locator_ID);
|
||||||
|
MStorageOnHand.add(Env.getCtx(), hqLocator1.get_ID(), product.get_ID(), asi1.get_ID(), new BigDecimal("2"), today, getTrxName());
|
||||||
|
M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), -1, new BigDecimal("1"), getTrxName());
|
||||||
|
assertEquals(hqLocator1.get_ID(), M_Locator_ID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -698,8 +698,8 @@ public class SalesOrderTest extends AbstractTestCase {
|
||||||
asi.setLot("1010");
|
asi.setLot("1010");
|
||||||
asi.saveEx();
|
asi.saveEx();
|
||||||
|
|
||||||
MStorageOnHand.add(ctx, WAREHOUSE_FERTILIZER, LOCATOR_FERTILIZER, PRODUCT_FERT50, asi.getM_AttributeSetInstance_ID(), Env.ONE, past_month, trxName);
|
MStorageOnHand.add(ctx, LOCATOR_FERTILIZER, PRODUCT_FERT50, asi.getM_AttributeSetInstance_ID(), Env.ONE, past_month, trxName);
|
||||||
MStorageOnHand.add(ctx, WAREHOUSE_FERTILIZER, LOCATOR_FERTILIZER, PRODUCT_FERT50, asi.getM_AttributeSetInstance_ID(), Env.ONE, today, trxName);
|
MStorageOnHand.add(ctx, LOCATOR_FERTILIZER, PRODUCT_FERT50, asi.getM_AttributeSetInstance_ID(), Env.ONE, today, trxName);
|
||||||
|
|
||||||
// Expected to create two entries in storage because of the different dates
|
// Expected to create two entries in storage because of the different dates
|
||||||
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(ctx, WAREHOUSE_FERTILIZER,
|
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(ctx, WAREHOUSE_FERTILIZER,
|
||||||
|
|
Loading…
Reference in New Issue