moved qtyavailable from storage onhand to storage reservation

This commit is contained in:
uthadehikaru 2012-10-17 09:19:14 +07:00
parent 5732700f46
commit 4e119984a8
8 changed files with 86 additions and 67 deletions

View File

@ -121,7 +121,7 @@ public class CalloutMovement extends CalloutEngine
if (M_Locator_ID <= 0) if (M_Locator_ID <= 0)
return; return;
int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
BigDecimal available = MStorageOnHand.getQtyAvailable(0, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null); BigDecimal available = MStorageReservation.getQtyAvailable(0, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null);
if (available == null) if (available == null)
available = Env.ZERO; available = Env.ZERO;
if (available.signum() == 0) if (available.signum() == 0)

View File

@ -821,7 +821,7 @@ public class CalloutOrder extends CalloutEngine
BigDecimal QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); BigDecimal QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered");
int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID");
int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
BigDecimal available = MStorageOnHand.getQtyAvailable BigDecimal available = MStorageReservation.getQtyAvailable
(M_Warehouse_ID, 0, M_Product_ID.intValue(), M_AttributeSetInstance_ID, null); (M_Warehouse_ID, 0, M_Product_ID.intValue(), M_AttributeSetInstance_ID, null);
if (available == null) if (available == null)
available = Env.ZERO; available = Env.ZERO;
@ -1296,7 +1296,7 @@ public class CalloutOrder extends CalloutEngine
{ {
int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID");
int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
BigDecimal available = MStorageOnHand.getQtyAvailable BigDecimal available = MStorageReservation.getQtyAvailable
(M_Warehouse_ID, 0, M_Product_ID, M_AttributeSetInstance_ID, null); (M_Warehouse_ID, 0, M_Product_ID, M_AttributeSetInstance_ID, null);
if (available == null) if (available == null)
available = Env.ZERO; available = Env.ZERO;

View File

@ -25,6 +25,7 @@ import org.compiere.model.MClient;
import org.compiere.model.MLocator; import org.compiere.model.MLocator;
import org.compiere.model.MProduct; import org.compiere.model.MProduct;
import org.compiere.model.MStorageOnHand; import org.compiere.model.MStorageOnHand;
import org.compiere.model.MStorageReservation;
import org.compiere.model.MTransaction; import org.compiere.model.MTransaction;
import org.compiere.model.Query; import org.compiere.model.Query;
import org.compiere.model.X_M_Production; import org.compiere.model.X_M_Production;
@ -140,7 +141,7 @@ public class M_Production_Run extends SvrProcess {
continue ; continue ;
else if(MovementQty.signum() < 0) else if(MovementQty.signum() < 0)
{ {
BigDecimal QtyAvailable = MStorageOnHand.getQtyAvailable( BigDecimal QtyAvailable = MStorageReservation.getQtyAvailable(
locator.getM_Warehouse_ID(), locator.getM_Warehouse_ID(),
locator.getM_Locator_ID(), locator.getM_Locator_ID(),
pline.getM_Product_ID(), pline.getM_Product_ID(),

View File

@ -510,65 +510,6 @@ public class MStorageOnHand extends X_M_StorageOnHand
return M_Locator_ID; return M_Locator_ID;
return firstM_Locator_ID; return firstM_Locator_ID;
} // getM_Locator_ID } // getM_Locator_ID
/**
* Get Available Qty.
* The call is accurate only if there is a storage record
* and assumes that the product is stocked
* @param M_Warehouse_ID wh
* @param M_Product_ID product
* @param M_AttributeSetInstance_ID masi
* @param trxName transaction
* @return qty available (QtyOnHand-QtyReserved) or null
* @deprecated Since 331b. Please use {@link #getQtyAvailable(int, int, int, int, String)}.
*/
public static BigDecimal getQtyAvailable (int M_Warehouse_ID,
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
{
return getQtyAvailable(M_Warehouse_ID, 0, M_Product_ID, M_AttributeSetInstance_ID, trxName);
}
/**
* Get Warehouse/Locator Available Qty.
* The call is accurate only if there is a storage record
* and assumes that the product is stocked
* @param M_Warehouse_ID wh (if the M_Locator_ID!=0 then M_Warehouse_ID is ignored)
* @param M_Locator_ID locator (if 0, the whole warehouse will be evaluated)
* @param M_Product_ID product
* @param M_AttributeSetInstance_ID masi
* @param trxName transaction
* @return qty available (QtyOnHand-QtyReserved) or null if error
*/
public static BigDecimal getQtyAvailable (int M_Warehouse_ID, int M_Locator_ID,
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
{
ArrayList<Object> params = new ArrayList<Object>();
StringBuffer sql = new StringBuffer("SELECT COALESCE(SUM(s.QtyOnHand-s.QtyReserved),0)")
.append(" FROM M_StorageOnHand s")
.append(" WHERE s.M_Product_ID=?");
params.add(M_Product_ID);
// Warehouse level
if (M_Locator_ID == 0) {
sql.append(" AND EXISTS (SELECT 1 FROM M_Locator l WHERE s.M_Locator_ID=l.M_Locator_ID AND l.M_Warehouse_ID=?)");
params.add(M_Warehouse_ID);
}
// Locator level
else {
sql.append(" AND s.M_Locator_ID=?");
params.add(M_Locator_ID);
}
// With ASI
if (M_AttributeSetInstance_ID != 0) {
sql.append(" AND s.M_AttributeSetInstance_ID=?");
params.add(M_AttributeSetInstance_ID);
}
//
BigDecimal retValue = DB.getSQLValueBD(trxName, sql.toString(), params);
if (CLogMgt.isLevelFine())
s_log.fine("M_Warehouse_ID=" + M_Warehouse_ID + ", M_Locator_ID=" + M_Locator_ID
+ ",M_Product_ID=" + M_Product_ID + " = " + retValue);
return retValue;
} // getQtyAvailable
/************************************************************************** /**************************************************************************
* Persistency Constructor * Persistency Constructor

View File

@ -1,10 +1,22 @@
package org.compiere.model; package org.compiere.model;
import java.math.BigDecimal;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
public class MStorageReservation extends X_M_StorageReservation { public class MStorageReservation extends X_M_StorageReservation {
/**
*
*/
private static final long serialVersionUID = 8114446879871270122L;
private static CLogger s_log = CLogger.getCLogger(MStorageReservation.class);
public MStorageReservation(Properties ctx, int M_StorageReservation_ID, public MStorageReservation(Properties ctx, int M_StorageReservation_ID,
String trxName) { String trxName) {
super(ctx, M_StorageReservation_ID, trxName); super(ctx, M_StorageReservation_ID, trxName);
@ -16,5 +28,67 @@ public class MStorageReservation extends X_M_StorageReservation {
super(ctx, rs, trxName); super(ctx, rs, trxName);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
/**
* Get Available Qty.
* The call is accurate only if there is a storage record
* and assumes that the product is stocked
* @param M_Warehouse_ID wh
* @param M_Product_ID product
* @param M_AttributeSetInstance_ID masi
* @param trxName transaction
* @return qty available (QtyOnHand-QtyReserved) or null
* @deprecated Since 331b. Please use {@link #getQtyAvailable(int, int, int, int, String)}.
*/
public static BigDecimal getQtyAvailable (int M_Warehouse_ID,
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
{
return getQtyAvailable(M_Warehouse_ID, 0, M_Product_ID, M_AttributeSetInstance_ID, trxName);
}
/**
* Get Warehouse/Locator Available Qty.
* The call is accurate only if there is a storage record
* and assumes that the product is stocked
* @param M_Warehouse_ID wh (if the M_Locator_ID!=0 then M_Warehouse_ID is ignored)
* @param M_Locator_ID locator (if 0, the whole warehouse will be evaluated)
* @param M_Product_ID product
* @param M_AttributeSetInstance_ID masi
* @param trxName transaction
* @return qty available (QtyOnHand-QtyReserved) or null if error
*/
public static BigDecimal getQtyAvailable (int M_Warehouse_ID, int M_Locator_ID,
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
{
ArrayList<Object> params = new ArrayList<Object>();
StringBuffer sql = new StringBuffer("SELECT COALESCE(SUM(COALESCE(SUM(s.QtyOnHand),0)-COALESCE(SUM(r.Qty),0),0)")
.append(" FROM M_StorageOnHand s")
.append(" JOIN M_StorageReservation r ON s.M_Product_ID=r.M_Product_ID")
.append(" WHERE s.M_Product_ID=?")
.append(" AND EXISTS (SELECT 1 FROM M_Locator l WHERE s.M_Locator_ID=l.M_Locator_ID AND l.M_Warehouse_ID=r.M_Warehouse_ID");
params.add(M_Product_ID, M_Product_ID);
// Warehouse level
if (M_Locator_ID == 0) {
sql.append(" AND l.M_Warehouse_ID=?)");
params.add(M_Warehouse_ID);
}
// Locator level
else {
sql.append(" AND s.M_Locator_ID=?)");
params.add(M_Locator_ID);
}
// With ASI
if (M_AttributeSetInstance_ID != 0) {
sql.append(" AND s.M_AttributeSetInstance_ID=? AND r.M_AttributeSetInstance_ID=?");
params.add(M_AttributeSetInstance_ID, M_AttributeSetInstance_ID);
}
//
BigDecimal retValue = DB.getSQLValueBD(trxName, sql.toString(), params);
if (CLogMgt.isLevelFine())
s_log.fine("M_Warehouse_ID=" + M_Warehouse_ID + ", M_Locator_ID=" + M_Locator_ID
+ ",M_Product_ID=" + M_Product_ID + " = " + retValue);
return retValue;
} // getQtyAvailable
} }

View File

@ -17,6 +17,7 @@ import java.math.BigDecimal;
import org.compiere.model.MLocator; import org.compiere.model.MLocator;
import org.compiere.model.MStorageOnHand; import org.compiere.model.MStorageOnHand;
import org.compiere.model.MStorageReservation;
import org.compiere.model.MWarehouse; import org.compiere.model.MWarehouse;
import org.compiere.util.Env; import org.compiere.util.Env;
@ -48,14 +49,14 @@ public class MStorageTest extends AdempiereTestCase
s1.setQtyOnHand(targetQty); s1.setQtyOnHand(targetQty);
s1.saveEx(); s1.saveEx();
// //
BigDecimal qty = MStorageOnHand.getQtyAvailable(wh.get_ID(), loc.get_ID(), product_id, 0, getTrxName()).setScale(12, BigDecimal.ROUND_HALF_UP); BigDecimal qty = MStorageReservation.getQtyAvailable(wh.get_ID(), loc.get_ID(), product_id, 0, getTrxName()).setScale(12, BigDecimal.ROUND_HALF_UP);
assertEquals("Error on locator "+locatorValue, targetQty, qty); assertEquals("Error on locator "+locatorValue, targetQty, qty);
// //
return loc; return loc;
} }
private void assertWarehouseQty(MWarehouse wh, BigDecimal targetQty) private void assertWarehouseQty(MWarehouse wh, BigDecimal targetQty)
{ {
BigDecimal qty = MStorageOnHand.getQtyAvailable(wh.get_ID(), 0, product_id, 0, getTrxName()); BigDecimal qty = MStorageReservation.getQtyAvailable(wh.get_ID(), 0, product_id, 0, getTrxName());
qty = qty.setScale(12, BigDecimal.ROUND_HALF_UP); qty = qty.setScale(12, BigDecimal.ROUND_HALF_UP);
targetQty = targetQty.setScale(12, BigDecimal.ROUND_HALF_UP); targetQty = targetQty.setScale(12, BigDecimal.ROUND_HALF_UP);
assertEquals(targetQty, qty); assertEquals(targetQty, qty);

View File

@ -51,6 +51,7 @@ import org.compiere.model.MProduct;
import org.compiere.model.MProductPrice; import org.compiere.model.MProductPrice;
import org.compiere.model.MRole; import org.compiere.model.MRole;
import org.compiere.model.MStorageOnHand; import org.compiere.model.MStorageOnHand;
import org.compiere.model.MStorageReservation;
import org.compiere.swing.CComboBox; import org.compiere.swing.CComboBox;
import org.compiere.swing.CLabel; import org.compiere.swing.CLabel;
import org.compiere.swing.CPanel; import org.compiere.swing.CPanel;
@ -518,7 +519,7 @@ public class VAttributeGrid extends CPanel
formatted = ""; formatted = "";
if (m_M_Warehouse_ID != 0) if (m_M_Warehouse_ID != 0)
{ {
BigDecimal qty = MStorageOnHand.getQtyAvailable(m_M_Warehouse_ID, M_Product_ID, 0, null); BigDecimal qty = MStorageReservation.getQtyAvailable(m_M_Warehouse_ID, 0, M_Product_ID, 0, null);
if (qty == null) if (qty == null)
formatted = "-"; formatted = "-";
else else

View File

@ -44,6 +44,7 @@ import org.compiere.model.MProduct;
import org.compiere.model.MProductPrice; import org.compiere.model.MProductPrice;
import org.compiere.model.MRole; import org.compiere.model.MRole;
import org.compiere.model.MStorageOnHand; import org.compiere.model.MStorageOnHand;
import org.compiere.model.MStorageReservation;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
@ -607,7 +608,7 @@ public class WAttributeGrid extends ADForm implements EventListener
formatted = ""; formatted = "";
if (m_M_Warehouse_ID != 0) if (m_M_Warehouse_ID != 0)
{ {
BigDecimal qty = MStorageOnHand.getQtyAvailable(m_M_Warehouse_ID, M_Product_ID, 0, null); BigDecimal qty = MStorageReservation.getQtyAvailable(m_M_Warehouse_ID, M_Product_ID, 0, null);
if (qty == null) if (qty == null)
formatted = "-"; formatted = "-";
else else