From 39247bf2f0edb979ce952a8b7372777de1584e92 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Thu, 31 Oct 2013 18:09:41 +0800 Subject: [PATCH] IDEMPIERE-386 Redesign ASI usage for FIFO. Improve backward compatibility. Ensure dateMPolicy is without time in the MStorageOnHand.* method that will create or update storage record. --- .../org/compiere/model/CalloutMovement.java | 12 +- .../src/org/compiere/model/MInventory.java | 3 +- .../org/compiere/model/MStorageOnHand.java | 108 ++++++++++++++++-- 3 files changed, 102 insertions(+), 21 deletions(-) diff --git a/org.adempiere.base.callout/src/org/compiere/model/CalloutMovement.java b/org.adempiere.base.callout/src/org/compiere/model/CalloutMovement.java index 9e9c0e8d21..a0bec96ca6 100644 --- a/org.adempiere.base.callout/src/org/compiere/model/CalloutMovement.java +++ b/org.adempiere.base.callout/src/org/compiere/model/CalloutMovement.java @@ -121,17 +121,7 @@ public class CalloutMovement extends CalloutEngine if (M_Locator_ID <= 0) return; int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); - BigDecimal available = Env.ZERO; - if (M_AttributeSetInstance_ID > 0) { - MStorageOnHand oh = MStorageOnHand.get(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null,null); - if (oh != null) - available = oh.getQtyOnHand(); - } else { - MStorageOnHand[] ohs = MStorageOnHand.getAll(ctx, M_Product_ID, M_Locator_ID, null); - for (MStorageOnHand oh : ohs) { - available = available.add(oh.getQtyOnHand()); - } - } + BigDecimal available = MStorageOnHand.getQtyOnHandForLocator(M_Product_ID, M_Locator_ID, M_AttributeSetInstance_ID, null); if (available == null) available = Env.ZERO; diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 8ec82bc95e..9125c6d5a4 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -509,7 +509,8 @@ public class MInventory extends X_M_Inventory implements DocAction { Timestamp dateMPolicy= getMovementDate(); I_M_AttributeSetInstance asi = line.getM_AttributeSetInstance(); - dateMPolicy =asi.getCreated(); + if (asi != null) + dateMPolicy =asi.getCreated(); //Fallback: Update Storage - see also VMatch.createMatchRecord if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), diff --git a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java index 6c7a6b41fb..a9f21f850b 100644 --- a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java +++ b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java @@ -46,6 +46,16 @@ public class MStorageOnHand extends X_M_StorageOnHand */ private static final long serialVersionUID = -9202148574984537051L; + /** + * + * @param ctx + * @param M_Locator_ID + * @param M_Product_ID + * @param M_AttributeSetInstance_ID + * @param trxName + * @deprecated + * @return MStorageOnHand + */ public static MStorageOnHand get (Properties ctx, int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID, String trxName) { return get (ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null, trxName); @@ -71,13 +81,23 @@ public class MStorageOnHand extends X_M_StorageOnHand sqlWhere += "M_AttributeSetInstance_ID=?"; if (dateMPolicy == null) - dateMPolicy = new Timestamp(new Date().getTime()); + { + if (M_AttributeSetInstance_ID > 0) + { + MAttributeSetInstance asi = new MAttributeSetInstance(ctx, M_AttributeSetInstance_ID, trxName); + dateMPolicy = asi.getCreated(); + } + } + + if (dateMPolicy != null) + sqlWhere += " AND DateMaterialPolicy=trunc(cast(? as date))"; - sqlWhere += " AND DateMaterialPolicy=trunc(cast(? as date))"; - - MStorageOnHand retValue = new Query(ctx, MStorageOnHand.Table_Name, sqlWhere, trxName) - .setParameters(M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, dateMPolicy) - .first(); + Query query = new Query(ctx, MStorageOnHand.Table_Name, sqlWhere, trxName); + if (dateMPolicy != null) + query.setParameters(M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, dateMPolicy); + else + query.setParameters(M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID); + MStorageOnHand retValue = query.first(); if (retValue == null) { if (s_log.isLoggable(Level.FINE)) s_log.fine("Not Found - M_Locator_ID=" + M_Locator_ID @@ -625,6 +645,8 @@ public class MStorageOnHand extends X_M_StorageOnHand if (dateMPolicy == null) dateMPolicy = new Timestamp(new Date().getTime()); + dateMPolicy = Util.removeTime(dateMPolicy); + MStorageOnHand retValue = get(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID,dateMPolicy, trxName); if (retValue != null) { @@ -644,7 +666,6 @@ public class MStorageOnHand extends X_M_StorageOnHand return retValue; } // getCreate - /** * Update Storage Info add. * Called from MProjectIssue @@ -656,6 +677,28 @@ public class MStorageOnHand extends X_M_StorageOnHand * @param reservationAttributeSetInstance_ID reservation AS Instance * @param diffQtyOnHand add on hand * @param trxName transaction + * @deprecated + * @return true if updated + */ + public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID, + int M_Product_ID, int M_AttributeSetInstance_ID, + BigDecimal diffQtyOnHand, String trxName) + { + return add(ctx, M_Warehouse_ID, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, diffQtyOnHand, null, trxName); + } + + /** + * Update Storage Info add. + * Called from MProjectIssue + * @param ctx context + * @param M_Warehouse_ID warehouse + * @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 */ public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID, @@ -665,8 +708,23 @@ public class MStorageOnHand extends X_M_StorageOnHand if (diffQtyOnHand == null || diffQtyOnHand.signum() == 0) return true; + if (dateMPolicy == null) + { + if (M_AttributeSetInstance_ID > 0) + { + MAttributeSetInstance asi = new MAttributeSetInstance(ctx, M_AttributeSetInstance_ID, trxName); + dateMPolicy = asi.getCreated(); + } + else + { + dateMPolicy = new Timestamp(System.currentTimeMillis()); + } + } + + dateMPolicy = Util.removeTime(dateMPolicy); + // Get Storage - MStorageOnHand storage = getCreate (ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID,dateMPolicy, trxName, true, 120); + MStorageOnHand storage = getCreate (ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, dateMPolicy, trxName, true, 120); // Verify if (storage.getM_Locator_ID() != M_Locator_ID && storage.getM_Product_ID() != M_Product_ID @@ -787,6 +845,7 @@ public class MStorageOnHand extends X_M_StorageOnHand setM_Locator_ID (locator.getM_Locator_ID()); setM_Product_ID (M_Product_ID); setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID); + dateMPolicy = Util.removeTime(dateMPolicy); setDateMaterialPolicy(dateMPolicy); } // MStorageOnHand @@ -874,7 +933,7 @@ public class MStorageOnHand extends X_M_StorageOnHand * @param M_Warehouse_ID * @param M_AttributeSetInstance_ID * @param trxName - * @return + * @return QtyOnHand */ public static BigDecimal getQtyOnHand(int M_Product_ID, int M_Warehouse_ID, int M_AttributeSetInstance_ID, String trxName) { StringBuilder sql = new StringBuilder(); @@ -899,6 +958,37 @@ public class MStorageOnHand extends X_M_StorageOnHand return qty; } + /** + * Get Quantity On Hand of Locator + * @param M_Product_ID + * @param M_Locator_ID + * @param M_AttributeSetInstance_ID + * @param trxName + * @return QtyOnHand + */ + public static BigDecimal getQtyOnHandForLocator(int M_Product_ID, int M_Locator_ID, int M_AttributeSetInstance_ID, String trxName) { + StringBuilder sql = new StringBuilder(); + sql.append(" SELECT SUM(oh.QtyOnHand) FROM M_StorageOnHand oh") + .append(" WHERE oh.M_Product_ID=?") + .append(" AND oh.M_Locator_ID=?"); + + ArrayList params = new ArrayList(); + params.add(M_Product_ID); + params.add(M_Locator_ID); + + // With ASI + if (M_AttributeSetInstance_ID != 0) { + sql.append(" AND oh.M_AttributeSetInstance_ID=?"); + params.add(M_AttributeSetInstance_ID); + } + + BigDecimal qty = DB.getSQLValueBD(trxName, sql.toString(), params); + if (qty == null) + qty = Env.ZERO; + + return qty; + } + /** * String Representation * @return info