diff --git a/base/src/org/compiere/model/MInOut.java b/base/src/org/compiere/model/MInOut.java
index 958aac9692..74f936aaae 100644
--- a/base/src/org/compiere/model/MInOut.java
+++ b/base/src/org/compiere/model/MInOut.java
@@ -1096,21 +1096,11 @@ public class MInOut extends X_M_InOut implements DocAction
//
if (line.getM_AttributeSetInstance_ID() != 0)
continue;
- if (product != null)
+ if (product != null && product.isASIMandatory(isSOTrx()))
{
- int M_AttributeSet_ID = product.getM_AttributeSet_ID();
- if (M_AttributeSet_ID != 0)
- {
- MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID);
- if (mas != null
- && ((isSOTrx() && mas.isMandatory())
- || (!isSOTrx() && mas.isMandatoryAlways())) )
- {
- m_processMsg = "@M_AttributeSet_ID@ @IsMandatory@ (@Line@ #" + lines[i].getLine() +
- ", @M_Product_ID@=" + product.getValue() + ")";
- return DocAction.STATUS_Invalid;
- }
- }
+ m_processMsg = "@M_AttributeSet_ID@ @IsMandatory@ (@Line@ #" + lines[i].getLine() +
+ ", @M_Product_ID@=" + product.getValue() + ")";
+ return DocAction.STATUS_Invalid;
}
}
setVolume(Volume);
diff --git a/base/src/org/compiere/model/MInventoryLine.java b/base/src/org/compiere/model/MInventoryLine.java
index 05058ce582..583e059af9 100644
--- a/base/src/org/compiere/model/MInventoryLine.java
+++ b/base/src/org/compiere/model/MInventoryLine.java
@@ -3,263 +3,263 @@
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
- * by the Free Software Foundation. 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., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
- * For the text or an alternative of this public license, you may reach us *
- * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
- * or via info@compiere.org or http://www.compiere.org/license.html *
- *****************************************************************************/
-package org.compiere.model;
-
-import java.math.*;
-import java.sql.*;
-import java.util.*;
-import java.util.logging.*;
-
-import org.compiere.util.*;
-
-/**
- * Physical Inventory Line Model
- *
- * @author Jorg Janke
- * @version $Id: MInventoryLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+package org.compiere.model;
+
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import java.util.logging.*;
+
+import org.compiere.util.*;
+
+/**
+ * Physical Inventory Line Model
+ *
+ * @author Jorg Janke
+ * @version $Id: MInventoryLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $
*
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
*
BF [ 1817757 ] Error on saving MInventoryLine in a custom environment
- */
-public class MInventoryLine extends X_M_InventoryLine
-{
- /**
- * Get Inventory Line with parameters
- * @param inventory inventory
- * @param M_Locator_ID locator
- * @param M_Product_ID product
- * @param M_AttributeSetInstance_ID asi
- * @return line or null
- */
- public static MInventoryLine get (MInventory inventory,
- int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID)
- {
- MInventoryLine retValue = null;
- String sql = "SELECT * FROM M_InventoryLine "
- + "WHERE M_Inventory_ID=? AND M_Locator_ID=?"
- + " AND M_Product_ID=? AND M_AttributeSetInstance_ID=?";
- PreparedStatement pstmt = null;
- try
- {
- pstmt = DB.prepareStatement (sql, inventory.get_TrxName());
- pstmt.setInt (1, inventory.getM_Inventory_ID());
- pstmt.setInt(2, M_Locator_ID);
- pstmt.setInt(3, M_Product_ID);
- pstmt.setInt(4, M_AttributeSetInstance_ID);
- ResultSet rs = pstmt.executeQuery ();
- if (rs.next ())
- retValue = new MInventoryLine (inventory.getCtx(), rs, inventory.get_TrxName());
- rs.close ();
- pstmt.close ();
- pstmt = null;
- }
- catch (Exception e)
- {
- s_log.log (Level.SEVERE, sql, e);
- }
- try
- {
- if (pstmt != null)
- pstmt.close ();
- pstmt = null;
- }
- catch (Exception e)
- {
- pstmt = null;
- }
-
- return retValue;
- } // get
-
-
- /** Logger */
- private static CLogger s_log = CLogger.getCLogger (MInventoryLine.class);
-
-
- /**************************************************************************
- * Default Constructor
- * @param ctx context
- * @param M_InventoryLine_ID line
- * @param trxName transaction
- */
- public MInventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName)
- {
- super (ctx, M_InventoryLine_ID, trxName);
- if (M_InventoryLine_ID == 0)
- {
- // setM_Inventory_ID (0); // Parent
- // setM_InventoryLine_ID (0); // PK
- // setM_Locator_ID (0); // FK
- setLine(0);
- // setM_Product_ID (0); // FK
- setM_AttributeSetInstance_ID(0); // FK
- setInventoryType (INVENTORYTYPE_InventoryDifference);
- setQtyBook (Env.ZERO);
- setQtyCount (Env.ZERO);
- setProcessed(false);
- }
- } // MInventoryLine
-
- /**
- * Load Constructor
- * @param ctx context
- * @param rs result set
- * @param trxName transaction
- */
- public MInventoryLine (Properties ctx, ResultSet rs, String trxName)
- {
- super(ctx, rs, trxName);
- } // MInventoryLine
-
- /**
- * Detail Constructor.
- * Locator/Product/AttributeSetInstance must be unique
- * @param inventory parent
- * @param M_Locator_ID locator
- * @param M_Product_ID product
- * @param M_AttributeSetInstance_ID instance
- * @param QtyBook book value
- * @param QtyCount count value
- */
- public MInventoryLine (MInventory inventory,
- int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID,
- BigDecimal QtyBook, BigDecimal QtyCount)
- {
- this (inventory.getCtx(), 0, inventory.get_TrxName());
- if (inventory.get_ID() == 0)
- throw new IllegalArgumentException("Header not saved");
- m_parent = inventory;
- setM_Inventory_ID (inventory.getM_Inventory_ID()); // Parent
- setClientOrg (inventory.getAD_Client_ID(), inventory.getAD_Org_ID());
- setM_Locator_ID (M_Locator_ID); // FK
- setM_Product_ID (M_Product_ID); // FK
- setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID);
- //
- if (QtyBook != null)
- setQtyBook (QtyBook);
- if (QtyCount != null && QtyCount.signum() != 0)
- setQtyCount (QtyCount);
- m_isManualEntry = false;
- } // MInventoryLine
-
- /** Manually created */
- private boolean m_isManualEntry = true;
- /** Parent */
- private MInventory m_parent = null;
- /** Product */
- private MProduct m_product = null;
-
- /**
- * Get Qty Book
- * @return Qty Book
- */
- public BigDecimal getQtyBook ()
- {
- BigDecimal bd = super.getQtyBook ();
- if (bd == null)
- bd = Env.ZERO;
- return bd;
- } // getQtyBook
-
- /**
- * Get Qty Count
- * @return Qty Count
- */
- public BigDecimal getQtyCount ()
- {
- BigDecimal bd = super.getQtyCount();
- if (bd == null)
- bd = Env.ZERO;
- return bd;
- } // getQtyBook
-
- /**
- * Get Product
- * @return product or null if not defined
- */
- public MProduct getProduct()
- {
- int M_Product_ID = getM_Product_ID();
- if (M_Product_ID == 0)
- return null;
- if (m_product != null && m_product.getM_Product_ID() != M_Product_ID)
- m_product = null; // reset
- if (m_product == null)
- m_product = MProduct.get(getCtx(), M_Product_ID);
- return m_product;
- } // getProduct
-
- /**
- * Set Count Qty - enforce UOM
- * @param QtyCount qty
- */
- public void setQtyCount (BigDecimal QtyCount)
- {
- if (QtyCount != null)
- {
- MProduct product = getProduct();
- if (product != null)
- {
- int precision = product.getUOMPrecision();
- QtyCount = QtyCount.setScale(precision, BigDecimal.ROUND_HALF_UP);
- }
- }
- super.setQtyCount(QtyCount);
- } // setQtyCount
-
- /**
- * Set Internal Use Qty - enforce UOM
- * @param QtyInternalUse qty
- */
- public void setQtyInternalUse (BigDecimal QtyInternalUse)
- {
- if (QtyInternalUse != null)
- {
- MProduct product = getProduct();
- if (product != null)
- {
- int precision = product.getUOMPrecision();
- QtyInternalUse = QtyInternalUse.setScale(precision, BigDecimal.ROUND_HALF_UP);
- }
- }
- super.setQtyInternalUse(QtyInternalUse);
- } // setQtyInternalUse
-
-
- /**
- * Add to Description
- * @param description text
- */
- public void addDescription (String description)
- {
- String desc = getDescription();
- if (desc == null)
- setDescription(description);
- else
- setDescription(desc + " | " + description);
- } // addDescription
-
- /**
- * Get Parent
- * @param parent parent
- */
- protected void setParent(MInventory parent)
- {
- m_parent = parent;
- } // setParent
-
- /**
+ */
+public class MInventoryLine extends X_M_InventoryLine
+{
+ /**
+ * Get Inventory Line with parameters
+ * @param inventory inventory
+ * @param M_Locator_ID locator
+ * @param M_Product_ID product
+ * @param M_AttributeSetInstance_ID asi
+ * @return line or null
+ */
+ public static MInventoryLine get (MInventory inventory,
+ int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID)
+ {
+ MInventoryLine retValue = null;
+ String sql = "SELECT * FROM M_InventoryLine "
+ + "WHERE M_Inventory_ID=? AND M_Locator_ID=?"
+ + " AND M_Product_ID=? AND M_AttributeSetInstance_ID=?";
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = DB.prepareStatement (sql, inventory.get_TrxName());
+ pstmt.setInt (1, inventory.getM_Inventory_ID());
+ pstmt.setInt(2, M_Locator_ID);
+ pstmt.setInt(3, M_Product_ID);
+ pstmt.setInt(4, M_AttributeSetInstance_ID);
+ ResultSet rs = pstmt.executeQuery ();
+ if (rs.next ())
+ retValue = new MInventoryLine (inventory.getCtx(), rs, inventory.get_TrxName());
+ rs.close ();
+ pstmt.close ();
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ s_log.log (Level.SEVERE, sql, e);
+ }
+ try
+ {
+ if (pstmt != null)
+ pstmt.close ();
+ pstmt = null;
+ }
+ catch (Exception e)
+ {
+ pstmt = null;
+ }
+
+ return retValue;
+ } // get
+
+
+ /** Logger */
+ private static CLogger s_log = CLogger.getCLogger (MInventoryLine.class);
+
+
+ /**************************************************************************
+ * Default Constructor
+ * @param ctx context
+ * @param M_InventoryLine_ID line
+ * @param trxName transaction
+ */
+ public MInventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName)
+ {
+ super (ctx, M_InventoryLine_ID, trxName);
+ if (M_InventoryLine_ID == 0)
+ {
+ // setM_Inventory_ID (0); // Parent
+ // setM_InventoryLine_ID (0); // PK
+ // setM_Locator_ID (0); // FK
+ setLine(0);
+ // setM_Product_ID (0); // FK
+ setM_AttributeSetInstance_ID(0); // FK
+ setInventoryType (INVENTORYTYPE_InventoryDifference);
+ setQtyBook (Env.ZERO);
+ setQtyCount (Env.ZERO);
+ setProcessed(false);
+ }
+ } // MInventoryLine
+
+ /**
+ * Load Constructor
+ * @param ctx context
+ * @param rs result set
+ * @param trxName transaction
+ */
+ public MInventoryLine (Properties ctx, ResultSet rs, String trxName)
+ {
+ super(ctx, rs, trxName);
+ } // MInventoryLine
+
+ /**
+ * Detail Constructor.
+ * Locator/Product/AttributeSetInstance must be unique
+ * @param inventory parent
+ * @param M_Locator_ID locator
+ * @param M_Product_ID product
+ * @param M_AttributeSetInstance_ID instance
+ * @param QtyBook book value
+ * @param QtyCount count value
+ */
+ public MInventoryLine (MInventory inventory,
+ int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID,
+ BigDecimal QtyBook, BigDecimal QtyCount)
+ {
+ this (inventory.getCtx(), 0, inventory.get_TrxName());
+ if (inventory.get_ID() == 0)
+ throw new IllegalArgumentException("Header not saved");
+ m_parent = inventory;
+ setM_Inventory_ID (inventory.getM_Inventory_ID()); // Parent
+ setClientOrg (inventory.getAD_Client_ID(), inventory.getAD_Org_ID());
+ setM_Locator_ID (M_Locator_ID); // FK
+ setM_Product_ID (M_Product_ID); // FK
+ setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID);
+ //
+ if (QtyBook != null)
+ setQtyBook (QtyBook);
+ if (QtyCount != null && QtyCount.signum() != 0)
+ setQtyCount (QtyCount);
+ m_isManualEntry = false;
+ } // MInventoryLine
+
+ /** Manually created */
+ private boolean m_isManualEntry = true;
+ /** Parent */
+ private MInventory m_parent = null;
+ /** Product */
+ private MProduct m_product = null;
+
+ /**
+ * Get Qty Book
+ * @return Qty Book
+ */
+ public BigDecimal getQtyBook ()
+ {
+ BigDecimal bd = super.getQtyBook ();
+ if (bd == null)
+ bd = Env.ZERO;
+ return bd;
+ } // getQtyBook
+
+ /**
+ * Get Qty Count
+ * @return Qty Count
+ */
+ public BigDecimal getQtyCount ()
+ {
+ BigDecimal bd = super.getQtyCount();
+ if (bd == null)
+ bd = Env.ZERO;
+ return bd;
+ } // getQtyBook
+
+ /**
+ * Get Product
+ * @return product or null if not defined
+ */
+ public MProduct getProduct()
+ {
+ int M_Product_ID = getM_Product_ID();
+ if (M_Product_ID == 0)
+ return null;
+ if (m_product != null && m_product.getM_Product_ID() != M_Product_ID)
+ m_product = null; // reset
+ if (m_product == null)
+ m_product = MProduct.get(getCtx(), M_Product_ID);
+ return m_product;
+ } // getProduct
+
+ /**
+ * Set Count Qty - enforce UOM
+ * @param QtyCount qty
+ */
+ public void setQtyCount (BigDecimal QtyCount)
+ {
+ if (QtyCount != null)
+ {
+ MProduct product = getProduct();
+ if (product != null)
+ {
+ int precision = product.getUOMPrecision();
+ QtyCount = QtyCount.setScale(precision, BigDecimal.ROUND_HALF_UP);
+ }
+ }
+ super.setQtyCount(QtyCount);
+ } // setQtyCount
+
+ /**
+ * Set Internal Use Qty - enforce UOM
+ * @param QtyInternalUse qty
+ */
+ public void setQtyInternalUse (BigDecimal QtyInternalUse)
+ {
+ if (QtyInternalUse != null)
+ {
+ MProduct product = getProduct();
+ if (product != null)
+ {
+ int precision = product.getUOMPrecision();
+ QtyInternalUse = QtyInternalUse.setScale(precision, BigDecimal.ROUND_HALF_UP);
+ }
+ }
+ super.setQtyInternalUse(QtyInternalUse);
+ } // setQtyInternalUse
+
+
+ /**
+ * Add to Description
+ * @param description text
+ */
+ public void addDescription (String description)
+ {
+ String desc = getDescription();
+ if (desc == null)
+ setDescription(description);
+ else
+ setDescription(desc + " | " + description);
+ } // addDescription
+
+ /**
+ * Get Parent
+ * @param parent parent
+ */
+ protected void setParent(MInventory parent)
+ {
+ m_parent = parent;
+ } // setParent
+
+ /**
* Get Parent
* @return parent
*/
@@ -267,155 +267,184 @@ public class MInventoryLine extends X_M_InventoryLine
{
if (m_parent == null)
m_parent = new MInventory (getCtx(), getM_Inventory_ID(), get_TrxName());
- return m_parent;
- } // getParent
-
- /**
- * String Representation
- * @return info
- */
- public String toString ()
- {
- StringBuffer sb = new StringBuffer ("MInventoryLine[");
- sb.append (get_ID())
- .append("-M_Product_ID=").append (getM_Product_ID())
- .append(",QtyCount=").append(getQtyCount())
- .append(",QtyInternalUse=").append(getQtyInternalUse())
- .append(",QtyBook=").append(getQtyBook())
- .append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID())
- .append("]");
- return sb.toString ();
- } // toString
-
- /**
- * Before Save
- * @param newRecord new
- * @return true if can be saved
- */
- protected boolean beforeSave (boolean newRecord)
- {
- if (newRecord && m_isManualEntry)
- {
- // Product requires ASI
- if (getM_AttributeSetInstance_ID() == 0)
- {
- MProduct product = MProduct.get(getCtx(), getM_Product_ID());
- if (product.getM_AttributeSet_ID() != 0)
- {
- MAttributeSet mas = MAttributeSet.get(getCtx(), product.getM_AttributeSet_ID());
- if (mas.isInstanceAttribute()
- && (mas.isMandatory() || mas.isMandatoryAlways()))
- {
- log.saveError("FillMandatory", Msg.getElement(getCtx(), "M_AttributeSetInstance_ID"));
- return false;
- }
- }
- } // No ASI
- } // new or manual
-
- // Set Line No
- if (getLine() == 0)
- {
- String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_InventoryLine WHERE M_Inventory_ID=?";
- int ii = DB.getSQLValue (get_TrxName(), sql, getM_Inventory_ID());
- setLine (ii);
- }
-
- // Enforce Qty UOM
- if (newRecord || is_ValueChanged("QtyCount"))
- setQtyCount(getQtyCount());
- if (newRecord || is_ValueChanged("QtyInternalUse"))
- setQtyInternalUse(getQtyInternalUse());
-
- // InternalUse Inventory
- if (getQtyInternalUse().signum() != 0)
- {
- if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
- setInventoryType(INVENTORYTYPE_ChargeAccount);
- //
- if (getC_Charge_ID() == 0)
- {
- log.saveError("InternalUseNeedsCharge", "");
- return false;
- }
- }
- else if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
- {
- if (getC_Charge_ID() == 0)
- {
- log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID"));
- return false;
- }
- }
- else if (getC_Charge_ID() != 0)
- setC_Charge_ID(0);
-
- // Set AD_Org to parent if not charge
- if (getC_Charge_ID() == 0)
- setAD_Org_ID(getParent().getAD_Org_ID());
-
- return true;
- } // beforeSave
-
- /**
- * After Save
- * @param newRecord new
- * @param success success
- * @return true
- */
- protected boolean afterSave (boolean newRecord, boolean success)
- {
+ return m_parent;
+ } // getParent
+
+ /**
+ * String Representation
+ * @return info
+ */
+ public String toString ()
+ {
+ StringBuffer sb = new StringBuffer ("MInventoryLine[");
+ sb.append (get_ID())
+ .append("-M_Product_ID=").append (getM_Product_ID())
+ .append(",QtyCount=").append(getQtyCount())
+ .append(",QtyInternalUse=").append(getQtyInternalUse())
+ .append(",QtyBook=").append(getQtyBook())
+ .append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID())
+ .append("]");
+ return sb.toString ();
+ } // toString
+
+ /**
+ * Before Save
+ * @param newRecord new
+ * @return true if can be saved
+ */
+ protected boolean beforeSave (boolean newRecord)
+ {
+ if (newRecord && m_isManualEntry)
+ {
+ // Product requires ASI
+ if (getM_AttributeSetInstance_ID() == 0)
+ {
+ MProduct product = MProduct.get(getCtx(), getM_Product_ID());
+ if (product != null && product.isASIMandatory(isSOTrx()))
+ {
+ log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstance_ID));
+ return false;
+ }
+ } // No ASI
+ } // new or manual
+
+ // Set Line No
+ if (getLine() == 0)
+ {
+ String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_InventoryLine WHERE M_Inventory_ID=?";
+ int ii = DB.getSQLValue (get_TrxName(), sql, getM_Inventory_ID());
+ setLine (ii);
+ }
+
+ // Enforce Qty UOM
+ if (newRecord || is_ValueChanged("QtyCount"))
+ setQtyCount(getQtyCount());
+ if (newRecord || is_ValueChanged("QtyInternalUse"))
+ setQtyInternalUse(getQtyInternalUse());
+
+ // InternalUse Inventory
+ if (getQtyInternalUse().signum() != 0)
+ {
+ if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
+ setInventoryType(INVENTORYTYPE_ChargeAccount);
+ //
+ if (getC_Charge_ID() == 0)
+ {
+ log.saveError("InternalUseNeedsCharge", "");
+ return false;
+ }
+ }
+ else if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
+ {
+ if (getC_Charge_ID() == 0)
+ {
+ log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID"));
+ return false;
+ }
+ }
+ else if (getC_Charge_ID() != 0)
+ setC_Charge_ID(0);
+
+ // Set AD_Org to parent if not charge
+ if (getC_Charge_ID() == 0)
+ setAD_Org_ID(getParent().getAD_Org_ID());
+
+ return true;
+ } // beforeSave
+
+ /**
+ * After Save
+ * @param newRecord new
+ * @param success success
+ * @return true
+ */
+ protected boolean afterSave (boolean newRecord, boolean success)
+ {
if (!success)
return false;
- // Create MA
- if (newRecord && success
- && m_isManualEntry && getM_AttributeSetInstance_ID() == 0)
- createMA();
- return true;
- } // afterSave
-
- /**
- * Create Material Allocations for new Instances
- */
- private void createMA()
- {
- MStorage[] storages = MStorage.getAll(getCtx(), getM_Product_ID(),
- getM_Locator_ID(), get_TrxName());
- boolean allZeroASI = true;
- for (int i = 0; i < storages.length; i++)
- {
- if (storages[i].getM_AttributeSetInstance_ID() != 0)
- {
- allZeroASI = false;
- break;
- }
- }
- if (allZeroASI)
- return;
-
- MInventoryLineMA ma = null;
- BigDecimal sum = Env.ZERO;
- for (int i = 0; i < storages.length; i++)
- {
- MStorage storage = storages[i];
- if (storage.getQtyOnHand().signum() == 0)
- continue;
- if (ma != null
- && ma.getM_AttributeSetInstance_ID() == storage.getM_AttributeSetInstance_ID())
- ma.setMovementQty(ma.getMovementQty().add(storage.getQtyOnHand()));
- else
- ma = new MInventoryLineMA (this,
- storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand());
- if (!ma.save())
- ;
- sum = sum.add(storage.getQtyOnHand());
- }
- if (sum.compareTo(getQtyBook()) != 0)
- {
- log.warning("QtyBook=" + getQtyBook() + " corrected to Sum of MA=" + sum);
- setQtyBook(sum);
- }
- } // createMA
-
-} // MInventoryLine
+ // Create MA
+ if (newRecord && success
+ && m_isManualEntry && getM_AttributeSetInstance_ID() == 0)
+ createMA();
+ return true;
+ } // afterSave
+
+ /**
+ * Create Material Allocations for new Instances
+ */
+ private void createMA()
+ {
+ MStorage[] storages = MStorage.getAll(getCtx(), getM_Product_ID(),
+ getM_Locator_ID(), get_TrxName());
+ boolean allZeroASI = true;
+ for (int i = 0; i < storages.length; i++)
+ {
+ if (storages[i].getM_AttributeSetInstance_ID() != 0)
+ {
+ allZeroASI = false;
+ break;
+ }
+ }
+ if (allZeroASI)
+ return;
+
+ MInventoryLineMA ma = null;
+ BigDecimal sum = Env.ZERO;
+ for (int i = 0; i < storages.length; i++)
+ {
+ MStorage storage = storages[i];
+ if (storage.getQtyOnHand().signum() == 0)
+ continue;
+ if (ma != null
+ && ma.getM_AttributeSetInstance_ID() == storage.getM_AttributeSetInstance_ID())
+ ma.setMovementQty(ma.getMovementQty().add(storage.getQtyOnHand()));
+ else
+ ma = new MInventoryLineMA (this,
+ storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand());
+ if (!ma.save())
+ ;
+ sum = sum.add(storage.getQtyOnHand());
+ }
+ if (sum.compareTo(getQtyBook()) != 0)
+ {
+ log.warning("QtyBook=" + getQtyBook() + " corrected to Sum of MA=" + sum);
+ setQtyBook(sum);
+ }
+ } // createMA
+
+ /**
+ * Is Internal Use Inventory
+ * @return true if is internal use inventory
+ */
+ public boolean isInternalUseInventory() {
+ /* TODO: need to add M_Inventory.IsInternalUseInventory flag
+ see FR [ 1879029 ] Added IsInternalUseInventory flag to M_Inventory table
+ MInventory parent = getParent();
+ return parent != null && parent.isInternalUseInventory();
+ */
+ return getQtyInternalUse().signum() != 0;
+ }
+
+ /**
+ * Get Movement Qty (absolute value)
+ * negative value means outgoing trx
+ * positive value means incoming trx
+ * @return movement qty
+ */
+ public BigDecimal getMovementQty() {
+ if(isInternalUseInventory()) {
+ return getQtyInternalUse().negate();
+ }
+ else {
+ return getQtyCount().subtract(getQtyBook());
+ }
+ }
+
+ /**
+ * @return true if is an outgoing transaction
+ */
+ public boolean isSOTrx() {
+ return getMovementQty().signum() < 0;
+ }
+} // MInventoryLine
diff --git a/base/src/org/compiere/model/MMovementLine.java b/base/src/org/compiere/model/MMovementLine.java
index e253a4d0d3..b290f19d5b 100644
--- a/base/src/org/compiere/model/MMovementLine.java
+++ b/base/src/org/compiere/model/MMovementLine.java
@@ -3,23 +3,23 @@
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
- * by the Free Software Foundation. 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., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
- * For the text or an alternative of this public license, you may reach us *
- * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
- * or via info@compiere.org or http://www.compiere.org/license.html *
- *****************************************************************************/
-package org.compiere.model;
-
-import java.math.*;
-import java.sql.*;
-import java.util.*;
-import org.compiere.util.*;
+ * by the Free Software Foundation. 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., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * For the text or an alternative of this public license, you may reach us *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
+ * or via info@compiere.org or http://www.compiere.org/license.html *
+ *****************************************************************************/
+package org.compiere.model;
+
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import org.compiere.util.*;
/**
* Inventory Move Line Model
@@ -27,18 +27,18 @@ import org.compiere.util.*;
* @author Jorg Janke
* @version $Id: MMovementLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
*/
-public class MMovementLine extends X_M_MovementLine
-{
- /**
- * Standard Cosntructor
- * @param ctx context
- * @param M_MovementLine_ID id
- * @param trxName transaction
- */
- public MMovementLine (Properties ctx, int M_MovementLine_ID, String trxName)
- {
- super (ctx, M_MovementLine_ID, trxName);
- if (M_MovementLine_ID == 0)
+public class MMovementLine extends X_M_MovementLine
+{
+ /**
+ * Standard Cosntructor
+ * @param ctx context
+ * @param M_MovementLine_ID id
+ * @param trxName transaction
+ */
+ public MMovementLine (Properties ctx, int M_MovementLine_ID, String trxName)
+ {
+ super (ctx, M_MovementLine_ID, trxName);
+ if (M_MovementLine_ID == 0)
{
// setM_LocatorTo_ID (0); // @M_LocatorTo_ID@
// setM_Locator_ID (0); // @M_Locator_ID@
@@ -47,7 +47,7 @@ public class MMovementLine extends X_M_MovementLine
// setM_Product_ID (0);
setM_AttributeSetInstance_ID(0); // ID
setMovementQty (Env.ZERO); // 1
- setTargetQty (Env.ZERO); // 0
+ setTargetQty (Env.ZERO); // 0
setScrappedQty(Env.ZERO);
setConfirmedQty(Env.ZERO);
setProcessed (false);
@@ -55,23 +55,23 @@ public class MMovementLine extends X_M_MovementLine
} // MMovementLine
/**
- * Load Constructor
- * @param ctx context
- * @param rs result set
- * @param trxName transaction
- */
- public MMovementLine (Properties ctx, ResultSet rs, String trxName)
- {
- super(ctx, rs, trxName);
- } // MMovementLine
-
- /**
- * Parent constructor
- * @param parent parent
- */
- public MMovementLine (MMovement parent)
- {
- this (parent.getCtx(), 0, parent.get_TrxName());
+ * Load Constructor
+ * @param ctx context
+ * @param rs result set
+ * @param trxName transaction
+ */
+ public MMovementLine (Properties ctx, ResultSet rs, String trxName)
+ {
+ super(ctx, rs, trxName);
+ } // MMovementLine
+
+ /**
+ * Parent constructor
+ * @param parent parent
+ */
+ public MMovementLine (MMovement parent)
+ {
+ this (parent.getCtx(), 0, parent.get_TrxName());
setClientOrg(parent);
setM_Movement_ID(parent.getM_Movement_ID());
} // MMovementLine
@@ -79,11 +79,11 @@ public class MMovementLine extends X_M_MovementLine
/**
* Get AttributeSetInstance To
* @return ASI
- */
- public int getM_AttributeSetInstanceTo_ID ()
- {
- int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID();
- if (M_AttributeSetInstanceTo_ID == 0)
+ */
+ public int getM_AttributeSetInstanceTo_ID ()
+ {
+ int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID();
+ if (M_AttributeSetInstanceTo_ID == 0)
M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstance_ID();
return M_AttributeSetInstanceTo_ID;
} // getM_AttributeSetInstanceTo_ID
@@ -91,23 +91,23 @@ public class MMovementLine extends X_M_MovementLine
/**
* Add to Description
* @param description text
- */
- public void addDescription (String description)
- {
- String desc = getDescription();
- if (desc == null)
- setDescription(description);
- else
- setDescription(desc + " | " + description);
- } // addDescription
-
- /**
- * Get Product
- * @return product or null if not defined
- */
- public MProduct getProduct()
- {
- if (getM_Product_ID() != 0)
+ */
+ public void addDescription (String description)
+ {
+ String desc = getDescription();
+ if (desc == null)
+ setDescription(description);
+ else
+ setDescription(desc + " | " + description);
+ } // addDescription
+
+ /**
+ * Get Product
+ * @return product or null if not defined
+ */
+ public MProduct getProduct()
+ {
+ if (getM_Product_ID() != 0)
return MProduct.get(getCtx(), getM_Product_ID());
return null;
} // getProduct
@@ -117,9 +117,9 @@ public class MMovementLine extends X_M_MovementLine
* @param MovementQty qty
*/
public void setMovementQty (BigDecimal MovementQty)
- {
- if (MovementQty != null)
- {
+ {
+ if (MovementQty != null)
+ {
MProduct product = getProduct();
if (product != null)
{
@@ -148,10 +148,10 @@ public class MMovementLine extends X_M_MovementLine
/**
* Before Save
* @param newRecord new
- * @return true
- */
- protected boolean beforeSave (boolean newRecord)
- {
+ * @return true
+ */
+ protected boolean beforeSave (boolean newRecord)
+ {
// Set Line No
if (getLine() == 0)
{
@@ -163,41 +163,41 @@ public class MMovementLine extends X_M_MovementLine
if (getM_Locator_ID() == getM_LocatorTo_ID())
{
log.saveError("Error", Msg.parseTranslation(getCtx(), "@M_Locator_ID@ == @M_LocatorTo_ID@"));
- return false;
- }
-
- if (getMovementQty().signum() == 0)
- {
- log.saveError("FillMandatory", Msg.getElement(getCtx(), "MovementQty"));
- return false;
- }
-
- // Qty Precision
- if (newRecord || is_ValueChanged(COLUMNNAME_MovementQty))
+ return false;
+ }
+
+ if (getMovementQty().signum() == 0)
+ {
+ log.saveError("FillMandatory", Msg.getElement(getCtx(), "MovementQty"));
+ return false;
+ }
+
+ // Qty Precision
+ if (newRecord || is_ValueChanged(COLUMNNAME_MovementQty))
setMovementQty(getMovementQty());
// Mandatory Instance
+ MProduct product = getProduct();
+ if (getM_AttributeSetInstance_ID() == 0) {
+ if (product != null && product.isASIMandatory(false)) {
+ log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstance_ID));
+ return false;
+ }
+ }
if (getM_AttributeSetInstanceTo_ID() == 0)
{
if (getM_AttributeSetInstance_ID() != 0) // set to from
setM_AttributeSetInstanceTo_ID(getM_AttributeSetInstance_ID());
else
{
- MProduct product = getProduct();
- if (product != null
- && product.getM_AttributeSet_ID() != 0)
+ if (product != null && product.isASIMandatory(true))
{
- MAttributeSet mas = MAttributeSet.get(getCtx(), product.getM_AttributeSet_ID());
- if (mas.isInstanceAttribute()
- && (mas.isMandatory() || mas.isMandatoryAlways()))
- {
- log.saveError("FillMandatory", Msg.getElement(getCtx(), "M_AttributeSetInstanceTo_ID"));
- return false;
- }
+ log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstanceTo_ID));
+ return false;
}
}
} // ASI
-
+
return true;
} // beforeSave
diff --git a/base/src/org/compiere/model/MProduct.java b/base/src/org/compiere/model/MProduct.java
index 54c4abf32b..bd6e15e719 100644
--- a/base/src/org/compiere/model/MProduct.java
+++ b/base/src/org/compiere/model/MProduct.java
@@ -30,6 +30,7 @@ import org.compiere.util.*;
*
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
* FR [ 1885153 ] Refactor: getMMPolicy code
+ * BF [ 1885414 ] ASI should be always mandatory if CostingLevel is Batch/Lot
*/
public class MProduct extends X_M_Product
{
@@ -748,4 +749,41 @@ public class MProduct extends X_M_Product
return MMPolicy;
}
+ /**
+ * Check if ASI is mandatory
+ * @param isSOTrx is outgoing trx?
+ * @return true if ASI is mandatory, false otherwise
+ */
+ public boolean isASIMandatory(boolean isSOTrx) {
+ //
+ // If CostingLevel is BatchLot ASI is always mandatory - check all client acct schemas
+ MAcctSchema[] mass = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID(), get_TrxName());
+ for (MAcctSchema as : mass) {
+ MProductCategoryAcct pca = MProductCategoryAcct.get(getCtx(), getM_Product_Category_ID(), as.getC_AcctSchema_ID(), get_TrxName());
+ String cl = pca.getCostingLevel();
+ if (cl == null)
+ cl = as.getCostingLevel();
+ if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(cl)) {
+ return true;
+ }
+ }
+ //
+ // Check Attribute Set settings
+ int M_AttributeSet_ID = getM_AttributeSet_ID();
+ if (M_AttributeSet_ID != 0)
+ {
+ MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID);
+ if (mas == null || !mas.isInstanceAttribute())
+ return false;
+ // Outgoing transaction
+ else if (isSOTrx)
+ return mas.isMandatory();
+ // Incoming transaction
+ else // isSOTrx == false
+ return mas.isMandatoryAlways();
+ }
+ //
+ // Default not mandatory
+ return false;
+ }
} // MProduct