moved qtyavailable from storage onhand to storage reservation
This commit is contained in:
parent
5732700f46
commit
4e119984a8
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue