From 71ee570659c7f411a1de239904a4b4a32669b480 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 9 Feb 2009 11:45:04 +0000 Subject: [PATCH] Merge bug fix from branches/adempiere343 [ 2545020 ] Issuing of stock should ignore storage with onhand <= 0 [ 2566690 ] Create new ASI instead of using 0 when no QtyOnHand [ 2567104 ] Inventory move should allow movement between ASI --- base/src/org/compiere/model/MInOut.java | 70 +++---- base/src/org/compiere/model/MInventory.java | 62 ++++--- base/src/org/compiere/model/MMovement.java | 174 ++++++------------ .../src/org/compiere/model/MMovementLine.java | 25 +-- base/src/org/compiere/model/MStorage.java | 27 ++- .../org/compiere/process/InOutGenerate.java | 7 +- 6 files changed, 166 insertions(+), 199 deletions(-) diff --git a/base/src/org/compiere/model/MInOut.java b/base/src/org/compiere/model/MInOut.java index 4fde7bb972..de6d314acf 100644 --- a/base/src/org/compiere/model/MInOut.java +++ b/base/src/org/compiere/model/MInOut.java @@ -102,9 +102,7 @@ public class MInOut extends X_M_InOut implements DocAction String MMPolicy = product.getMMPolicy(); storages = MStorage.getWarehouse (order.getCtx(), order.getM_Warehouse_ID(), oLines[i].getM_Product_ID(), oLines[i].getM_AttributeSetInstance_ID(), - product.getM_AttributeSet_ID(), - allAttributeInstances, minGuaranteeDate, - MClient.MMPOLICY_FiFo.equals(MMPolicy), trxName); + minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, 0, trxName); } else { continue; } @@ -1256,7 +1254,9 @@ public class MInOut extends X_M_InOut implements DocAction { //Ignore the Material Policy when is Reverse Correction if(!isReversal()) - checkMaterialPolicy(sLine); + { + checkMaterialPolicy(sLine); + } log.fine("Material Transaction"); MTransaction mtrx = null; @@ -1672,33 +1672,37 @@ public class MInOut extends X_M_InOut implements DocAction if (product != null && line.getM_AttributeSetInstance_ID() == 0) { //Validate Transaction - //if (inTrx) if (getMovementType().compareTo(MInOut.MOVEMENTTYPE_CustomerReturns) == 0 || getMovementType().compareTo(MInOut.MOVEMENTTYPE_VendorReceipts) == 0 ) { - MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), 0, get_TrxName()); - asi.setClientOrg(getAD_Client_ID(), 0); - asi.setM_AttributeSet_ID(product.getM_AttributeSet_ID()); - if (!asi.save()) + MAttributeSetInstance asi = null; + //auto balance negative on hand + MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, + null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false, line.getM_Locator_ID(), get_TrxName()); + for (MStorage storage : storages) { - throw new IllegalStateException("Error try create ASI Reservation"); - } - if (asi.save()) - { - line.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); - log.config("New ASI=" + line); - needSave = true; + if (storage.getQtyOnHand().signum() < 0) + { + asi = new MAttributeSetInstance(getCtx(), storage.getM_AttributeSetInstance_ID(), get_TrxName()); + break; + } } + //always create asi so fifo/lifo work. + if (asi == null) + { + asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + } + line.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + log.config("New ASI=" + line); + needSave = true; } // Create consume the Attribute Set Instance using policy FIFO/LIFO else if(getMovementType().compareTo(MInOut.MOVEMENTTYPE_VendorReturns) == 0 || getMovementType().compareTo(MInOut.MOVEMENTTYPE_CustomerShipment) == 0) { String MMPolicy = product.getMMPolicy(); Timestamp minGuaranteeDate = getMovementDate(); - MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), - line.getM_AttributeSetInstance_ID(), + MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName()); BigDecimal qtyToDeliver = line.getMovementQty(); - BigDecimal qtyNegativeOnhand = Env.ZERO; for (MStorage storage: storages) { if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0) @@ -1706,39 +1710,39 @@ public class MInOut extends X_M_InOut implements DocAction MInOutLineMA ma = new MInOutLineMA (line, storage.getM_AttributeSetInstance_ID(), qtyToDeliver); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } + ma.saveEx(); qtyToDeliver = Env.ZERO; - break; } else { MInOutLineMA ma = new MInOutLineMA (line, storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand()); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } + ma.saveEx(); qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand()); log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); } + + if (qtyToDeliver.signum() == 0) + break; } if (qtyToDeliver.signum() != 0) { - MInOutLineMA ma = new MInOutLineMA (line, 0, qtyToDeliver); - if (!ma.save()) - throw new IllegalStateException("Error try create ASI Reservation"); + //deliver using new asi + MAttributeSetInstance asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + int M_AttributeSetInstance_ID = asi.getM_AttributeSetInstance_ID(); + MInOutLineMA ma = new MInOutLineMA (line, M_AttributeSetInstance_ID, qtyToDeliver); + ma.saveEx(); log.fine("##: " + ma); } } // outgoing Trx } // attributeSetInstance - if (needSave && !line.save()) - log.severe("NOT saved " + line); + if (needSave) + { + line.saveEx(); + } } // checkMaterialPolicy diff --git a/base/src/org/compiere/model/MInventory.java b/base/src/org/compiere/model/MInventory.java index 617fa46a4a..36dc92c9fc 100644 --- a/base/src/org/compiere/model/MInventory.java +++ b/base/src/org/compiere/model/MInventory.java @@ -48,6 +48,12 @@ import org.compiere.util.Msg; */ public class MInventory extends X_M_Inventory implements DocAction { + /** + * generated serialVersionUID + */ + private static final long serialVersionUID = 6039577059413522140L; + + /** * Get Inventory from Cache * @param ctx context @@ -577,8 +583,6 @@ public class MInventory extends X_M_Inventory implements DocAction /** * Check Material Policy. - * (NOT USED) - * Sets line ASI */ private void checkMaterialPolicy(MInventoryLine line, BigDecimal qtyDiff) { @@ -586,7 +590,6 @@ public class MInventory extends X_M_Inventory implements DocAction if (no > 0) log.config("Delete old #" + no); - // Check Line boolean needSave = false; // Attribute Set Instance @@ -595,18 +598,24 @@ public class MInventory extends X_M_Inventory implements DocAction MProduct product = MProduct.get(getCtx(), line.getM_Product_ID()); if (qtyDiff.signum() > 0) // Incoming Trx { - MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), 0, get_TrxName()); - asi.setClientOrg(getAD_Client_ID(), 0); - asi.setM_AttributeSet_ID(product.getM_AttributeSet_ID()); - if (!asi.save()) + MAttributeSetInstance asi = null; + //auto balance negative on hand + MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, + null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false, line.getM_Locator_ID(), get_TrxName()); + for (MStorage storage : storages) { - throw new IllegalStateException("Error try create ASI Reservation"); - } - if (asi.save()) - { - line.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); - needSave = true; + if (storage.getQtyOnHand().signum() < 0) + { + asi = new MAttributeSetInstance(getCtx(), storage.getM_AttributeSetInstance_ID(), get_TrxName()); + break; + } } + if (asi == null) + { + asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + } + line.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + needSave = true; } else // Outgoing Trx { @@ -623,41 +632,40 @@ public class MInventory extends X_M_Inventory implements DocAction MInventoryLineMA ma = new MInventoryLineMA (line, storage.getM_AttributeSetInstance_ID(), qtyToDeliver); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } + ma.saveEx(); qtyToDeliver = Env.ZERO; log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); - break; } else { MInventoryLineMA ma = new MInventoryLineMA (line, storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand()); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } + ma.saveEx(); qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand()); log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); } + if (qtyToDeliver.signum() == 0) + break; } // No AttributeSetInstance found for remainder if (qtyToDeliver.signum() != 0) { - MInventoryLineMA ma = new MInventoryLineMA (line, 0 , qtyToDeliver); + //deliver using new asi + MAttributeSetInstance asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + int M_AttributeSetInstance_ID = asi.getM_AttributeSetInstance_ID(); + MInventoryLineMA ma = new MInventoryLineMA (line, M_AttributeSetInstance_ID , qtyToDeliver); - if (!ma.save()) - throw new IllegalStateException("Error try create ASI Reservation"); + ma.saveEx(); log.fine("##: " + ma); } } // outgoing Trx - if (needSave && !line.save()) - log.severe("NOT saved " + line); + if (needSave) + { + line.saveEx(); + } } // for all lines } // checkMaterialPolicy diff --git a/base/src/org/compiere/model/MMovement.java b/base/src/org/compiere/model/MMovement.java index 5ce5f44e1d..d339b876da 100644 --- a/base/src/org/compiere/model/MMovement.java +++ b/base/src/org/compiere/model/MMovement.java @@ -315,10 +315,6 @@ public class MMovement extends X_M_Movement implements DocAction m_processMsg = "@NoLines@"; return DocAction.STATUS_Invalid; } - // Add up Amounts - - - //checkMaterialPolicy(); // Confirmation if (dt.isInTransit()) @@ -429,12 +425,6 @@ public class MMovement extends X_M_Movement implements DocAction { MMovementLineMA ma = mas[j]; // - /*MStorage storageFrom = MStorage.get(getCtx(), line.getM_Locator_ID(), - line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName()); - if (storageFrom == null) - storageFrom = MStorage.getCreate(getCtx(), line.getM_Locator_ID(), - line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName()); - //*/ MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName()); //Update Storage if (!MStorage.add(getCtx(),locator.getM_Warehouse_ID(), @@ -447,39 +437,23 @@ public class MMovement extends X_M_Movement implements DocAction return DocAction.STATUS_Invalid; } - /*MStorage storageTo = MStorage.get(getCtx(), line.getM_LocatorTo_ID(), - line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName()); - if (storageTo == null) - storageTo = MStorage.getCreate(getCtx(), line.getM_LocatorTo_ID(), - line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName()); - //*/ - - // MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName()); + int M_AttributeSetInstanceTo_ID = line.getM_AttributeSetInstanceTo_ID(); + //only can be same asi if locator is different + if (M_AttributeSetInstanceTo_ID == 0 && line.getM_Locator_ID() != line.getM_LocatorTo_ID()) + { + M_AttributeSetInstanceTo_ID = ma.getM_AttributeSetInstance_ID(); + } //Update Storage if (!MStorage.add(getCtx(),locator.getM_Warehouse_ID(), line.getM_LocatorTo_ID(), line.getM_Product_ID(), - ma.getM_AttributeSetInstance_ID(), 0, + M_AttributeSetInstanceTo_ID, 0, ma.getMovementQty(), Env.ZERO , Env.ZERO , get_TrxName())) { m_processMsg = "Cannot correct Inventory (MA)"; return DocAction.STATUS_Invalid; } - /*storageFrom.setQtyOnHand(storageFrom.getQtyOnHand().subtract(ma.getMovementQty())); - if (!storageFrom.save(get_TrxName())) - { - m_processMsg = "Storage From not updated (MA)"; - return DocAction.STATUS_Invalid; - } - // - storageTo.setQtyOnHand(storageTo.getQtyOnHand().add(ma.getMovementQty())); - if (!storageTo.save(get_TrxName())) - { - m_processMsg = "Storage To not updated (MA)"; - return DocAction.STATUS_Invalid; - }*/ - // trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(), MTransaction.MOVEMENTTYPE_MovementFrom, @@ -494,7 +468,7 @@ public class MMovement extends X_M_Movement implements DocAction // MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(), MTransaction.MOVEMENTTYPE_MovementTo, - line.getM_LocatorTo_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), + line.getM_LocatorTo_ID(), line.getM_Product_ID(), M_AttributeSetInstanceTo_ID, ma.getMovementQty(), getMovementDate(), get_TrxName()); trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID()); if (!trxTo.save()) @@ -507,32 +481,6 @@ public class MMovement extends X_M_Movement implements DocAction // Fallback - We have ASI if (trxFrom == null) { - /*MStorage storageFrom = MStorage.get(getCtx(), line.getM_Locator_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName()); - if (storageFrom == null) - storageFrom = MStorage.getCreate(getCtx(), line.getM_Locator_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName()); - // - MStorage storageTo = MStorage.get(getCtx(), line.getM_LocatorTo_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), get_TrxName()); - if (storageTo == null) - storageTo = MStorage.getCreate(getCtx(), line.getM_LocatorTo_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), get_TrxName()); - // - storageFrom.setQtyOnHand(storageFrom.getQtyOnHand().subtract(line.getMovementQty())); - if (!storageFrom.save(get_TrxName())) - { - m_processMsg = "Storage From not updated"; - return DocAction.STATUS_Invalid; - } - // - storageTo.setQtyOnHand(storageTo.getQtyOnHand().add(line.getMovementQty())); - if (!storageTo.save(get_TrxName())) - { - m_processMsg = "Storage To not updated"; - return DocAction.STATUS_Invalid; - }*/ - MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName()); //Update Storage if (!MStorage.add(getCtx(),locator.getM_Warehouse_ID(), @@ -545,12 +493,11 @@ public class MMovement extends X_M_Movement implements DocAction return DocAction.STATUS_Invalid; } - // MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName()); //Update Storage if (!MStorage.add(getCtx(),locator.getM_Warehouse_ID(), line.getM_LocatorTo_ID(), line.getM_Product_ID(), - line.getM_AttributeSetInstance_ID(), 0, + line.getM_AttributeSetInstanceTo_ID(), 0, line.getMovementQty(), Env.ZERO , Env.ZERO , get_TrxName())) { m_processMsg = "Cannot correct Inventory (MA)"; @@ -651,68 +598,59 @@ public class MMovement extends X_M_Movement implements DocAction int no = MMovementLineMA.deleteMovementMA(getM_Movement_ID(), get_TrxName()); if (no > 0) log.config("Delete old #" + no); - //MMovementLine[] lines = getLines(false); - // Check Lines - //for (int i = 0; i < lines.length; i++) - //{ - // MMovementLine line = lines[i]; - boolean needSave = false; + boolean needSave = false; - // Attribute Set Instance - if (line.getM_AttributeSetInstance_ID() == 0) + // Attribute Set Instance + if (line.getM_AttributeSetInstance_ID() == 0) + { + MProduct product = MProduct.get(getCtx(), line.getM_Product_ID()); + String MMPolicy = product.getMMPolicy(); + MStorage[] storages = MStorage.getWarehouse(getCtx(), 0, line.getM_Product_ID(), 0, + null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName()); + + BigDecimal qtyToDeliver = line.getMovementQty(); + + for (MStorage storage: storages) { - MProduct product = MProduct.get(getCtx(), line.getM_Product_ID()); - String MMPolicy = product.getMMPolicy(); - MStorage[] storages = MStorage.getWarehouse(getCtx(), 0, line.getM_Product_ID(), 0, - null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName()); - - BigDecimal qtyToDeliver = line.getMovementQty(); - - for (MStorage storage: storages) + if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0) { - if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0) - { - MMovementLineMA ma = new MMovementLineMA (line, + MMovementLineMA ma = new MMovementLineMA (line, + storage.getM_AttributeSetInstance_ID(), + qtyToDeliver); + ma.saveEx(); + qtyToDeliver = Env.ZERO; + log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); + } + else + { + MMovementLineMA ma = new MMovementLineMA (line, storage.getM_AttributeSetInstance_ID(), - qtyToDeliver); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } - qtyToDeliver = Env.ZERO; - log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); - break; - } - else - { - MMovementLineMA ma = new MMovementLineMA (line, - storage.getM_AttributeSetInstance_ID(), - storage.getQtyOnHand()); - if (!ma.save()) - { - throw new IllegalStateException("Error try create ASI Reservation"); - } - qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand()); - log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); - } + storage.getQtyOnHand()); + ma.saveEx(); + qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand()); + log.fine( ma + ", QtyToDeliver=" + qtyToDeliver); } - - // No AttributeSetInstance found for remainder - if (qtyToDeliver.signum() != 0) - { - MMovementLineMA ma = new MMovementLineMA (line, 0 , qtyToDeliver); - - if (!ma.save()) - throw new IllegalStateException("Error try create ASI Reservation"); - log.fine("##: " + ma); - } - } // attributeSetInstance - - if (needSave && !line.save()) - log.severe("NOT saved " + line); - //} // for all lines - + if (qtyToDeliver.signum() == 0) + break; + } + + // No AttributeSetInstance found for remainder + if (qtyToDeliver.signum() != 0) + { + //deliver using new asi + MAttributeSetInstance asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + int M_AttributeSetInstance_ID = asi.getM_AttributeSetInstance_ID(); + MMovementLineMA ma = new MMovementLineMA (line, M_AttributeSetInstance_ID , qtyToDeliver); + ma.saveEx(); + log.fine("##: " + ma); + } + } // attributeSetInstance + + if (needSave) + { + line.saveEx(); + } } // checkMaterialPolicy /** diff --git a/base/src/org/compiere/model/MMovementLine.java b/base/src/org/compiere/model/MMovementLine.java index 23b35bd894..5d60fc6f60 100644 --- a/base/src/org/compiere/model/MMovementLine.java +++ b/base/src/org/compiere/model/MMovementLine.java @@ -95,7 +95,7 @@ public class MMovementLine extends X_M_MovementLine public int getM_AttributeSetInstanceTo_ID () { int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID(); - if (M_AttributeSetInstanceTo_ID == 0) + if (M_AttributeSetInstanceTo_ID == 0 && (getM_Locator_ID() == getM_LocatorTo_ID())) M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstance_ID(); return M_AttributeSetInstanceTo_ID; } // getM_AttributeSetInstanceTo_ID @@ -174,9 +174,10 @@ public class MMovementLine extends X_M_MovementLine setLine (ii); } - if (getM_Locator_ID() == getM_LocatorTo_ID()) + //either movement between locator or movement between lot + if (getM_Locator_ID() == getM_LocatorTo_ID() && getM_AttributeSetInstance_ID() == getM_AttributeSetInstanceTo_ID()) { - log.saveError("Error", Msg.parseTranslation(getCtx(), "@M_Locator_ID@ == @M_LocatorTo_ID@")); + log.saveError("Error", Msg.parseTranslation(getCtx(), "@M_Locator_ID@ == @M_LocatorTo_ID@ and @M_AttributeSetInstance_ID@ == @M_AttributeSetInstanceTo_ID@")); return false; } @@ -213,15 +214,17 @@ public class MMovementLine extends X_M_MovementLine } if (getM_AttributeSetInstanceTo_ID() == 0) { - if (getM_AttributeSetInstance_ID() != 0) // set to from - setM_AttributeSetInstanceTo_ID(getM_AttributeSetInstance_ID()); - else + //instance id default to same for movement between locator + if (getM_Locator_ID() != getM_LocatorTo_ID()) { - if (product != null && product.isASIMandatory(true)) - { - log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstanceTo_ID)); - return false; - } + if (getM_AttributeSetInstance_ID() != 0) //set to from + setM_AttributeSetInstanceTo_ID(getM_AttributeSetInstance_ID()); + } + + if (product != null && product.isASIMandatory(true) && getM_AttributeSetInstanceTo_ID() == 0) + { + log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstanceTo_ID)); + return false; } } // ASI diff --git a/base/src/org/compiere/model/MStorage.java b/base/src/org/compiere/model/MStorage.java index 193cd1fa01..215d5bbd50 100644 --- a/base/src/org/compiere/model/MStorage.java +++ b/base/src/org/compiere/model/MStorage.java @@ -38,6 +38,11 @@ import org.compiere.util.Env; */ public class MStorage extends X_M_Storage { + /** + * generated serialVersionUID + */ + private static final long serialVersionUID = 9086223702645715061L; + /** * Get Storage Info * @param ctx context @@ -105,6 +110,8 @@ public class MStorage extends X_M_Storage + " AND M_AttributeSetInstance_ID > 0 " + " AND QtyOnHand <> 0 " + "ORDER BY M_AttributeSetInstance_ID"; + if (!FiFo) + sql += " DESC"; PreparedStatement pstmt = null; ResultSet rs = null; try @@ -273,6 +280,10 @@ public class MStorage extends X_M_Storage { sql += " AND s.QtyOnHand > 0 "; } + else + { + sql += " AND s.QtyOnHand <> 0 "; + } sql += "ORDER BY l.PriorityNo DESC, M_AttributeSetInstance_ID"; if (!FiFo) sql += " DESC"; @@ -290,13 +301,17 @@ public class MStorage extends X_M_Storage else sql += "WHERE l.M_Warehouse_ID=?"; sql += " AND s.M_Product_ID=? "; + if (positiveOnly) + { + sql += " AND s.QtyOnHand > 0 "; + } + else + { + sql += " AND s.QtyOnHand <> 0 "; + } if (minGuaranteeDate != null) { sql += "AND (asi.GuaranteeDate IS NULL OR asi.GuaranteeDate>?) "; - if (positiveOnly) - { - sql += " AND s.QtyOnHand > 0 "; - } sql += "ORDER BY l.PriorityNo DESC, " + "asi.GuaranteeDate, M_AttributeSetInstance_ID"; if (!FiFo) @@ -305,10 +320,6 @@ public class MStorage extends X_M_Storage } else { - if (positiveOnly) - { - sql += " AND s.QtyOnHand > 0 "; - } sql += "ORDER BY l.PriorityNo DESC, l.M_Locator_ID, s.M_AttributeSetInstance_ID"; if (!FiFo) sql += " DESC"; diff --git a/base/src/org/compiere/process/InOutGenerate.java b/base/src/org/compiere/process/InOutGenerate.java index 855139ca1d..f7db933032 100644 --- a/base/src/org/compiere/process/InOutGenerate.java +++ b/base/src/org/compiere/process/InOutGenerate.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.logging.Level; -import org.compiere.model.MAttributeSet; import org.compiere.model.MClient; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; @@ -465,6 +464,10 @@ public class InOutGenerate extends SvrProcess { MStorage storage = storages[i]; BigDecimal deliver = toDeliver; + //skip negative storage record + if (storage.getQtyOnHand().signum() < 0) + continue; + // Not enough On Hand if (deliver.compareTo(storage.getQtyOnHand()) > 0 && storage.getQtyOnHand().signum() >= 0) // positive storage @@ -557,7 +560,7 @@ public class InOutGenerate extends SvrProcess { m_lastStorages = MStorage.getWarehouse(getCtx(), M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, - minGuaranteeDate, FiFo,true, 0, get_TrxName()); + minGuaranteeDate, FiFo,false, 0, get_TrxName()); m_map.put(m_lastPP, m_lastStorages); } return m_lastStorages;