IDEMPIERE-3488 Improvement to Error Message for Negative Inventory Disallow exception
This commit is contained in:
parent
8f0c185141
commit
e3961c7d61
|
@ -0,0 +1,11 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- IDEMPIERE-3488 Improvement to Error Message for Negative Inventory Disallow exception
|
||||
-- Sep 14, 2017 6:28:55 PM GMT+08:00
|
||||
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','The {0} warehouse does not allow negative inventory for Product = {1}, ASI = {2}, Locator = {3} (Shortage of {4})',0,0,'Y',TO_DATE('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,200431,'NegativeInventoryDisallowedInfo','D','1a686715-09f5-4437-9885-882719423bd1')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201709151000_IDEMPIERE-3488.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- IDEMPIERE-3488 Improvement to Error Message for Negative Inventory Disallow exception
|
||||
-- Sep 14, 2017 6:28:55 PM GMT+08:00
|
||||
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','The {0} warehouse does not allow negative inventory for Product = {1}, ASI = {2}, Locator = {3} (Shortage of {4})',0,0,'Y',TO_TIMESTAMP('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,200431,'NegativeInventoryDisallowedInfo','D','1a686715-09f5-4437-9885-882719423bd1')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201709151000_IDEMPIERE-3488.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2017 Trek Global Inc. *
|
||||
* Copyright (C) 2017 Low Heng Sin *
|
||||
* 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. *
|
||||
*******************************************************************************/
|
||||
package org.adempiere.exceptions;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MLocator;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class NegativeInventoryDisallowedException extends AdempiereException
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 253224414462489886L;
|
||||
|
||||
private int M_Warehouse_ID;
|
||||
private int M_Product_ID;
|
||||
private int M_AttributeSetInstance_ID;
|
||||
private int M_Locator_ID;
|
||||
private BigDecimal QtyOnHand;
|
||||
private BigDecimal MovementQty;
|
||||
|
||||
public NegativeInventoryDisallowedException(Properties ctx, int M_Warehouse_ID, int M_Product_ID, int M_AttributeSetInstance_ID, int M_Locator_ID,
|
||||
BigDecimal QtyOnHand, BigDecimal MovementQty)
|
||||
{
|
||||
super(Msg.getMsg(ctx, "NegativeInventoryDisallowedInfo", new Object[] {
|
||||
MWarehouse.get(ctx, M_Warehouse_ID).getName(),
|
||||
MProduct.get(ctx, M_Product_ID).getValue() + MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(ctx)) + MProduct.get(ctx, M_Product_ID).getName(),
|
||||
M_AttributeSetInstance_ID > 0 ? MAttributeSetInstance.get(ctx, M_AttributeSetInstance_ID, M_Product_ID).getDescription() : "0",
|
||||
M_Locator_ID > 0 ? MLocator.get(ctx, M_Locator_ID).getValue() : "0", MovementQty.subtract(QtyOnHand)
|
||||
|
||||
}));
|
||||
|
||||
this.M_Warehouse_ID = M_Warehouse_ID;
|
||||
this.M_Product_ID = M_Product_ID;
|
||||
this.M_AttributeSetInstance_ID = M_AttributeSetInstance_ID;
|
||||
this.M_Locator_ID = M_Locator_ID;
|
||||
this.QtyOnHand = QtyOnHand;
|
||||
this.MovementQty = MovementQty;
|
||||
}
|
||||
|
||||
public int getM_Warehouse_ID() {
|
||||
return M_Warehouse_ID;
|
||||
}
|
||||
|
||||
public int getM_Product_ID() {
|
||||
return M_Product_ID;
|
||||
}
|
||||
|
||||
public int getM_AttributeSetInstance_ID() {
|
||||
return M_AttributeSetInstance_ID;
|
||||
}
|
||||
|
||||
public int getM_Locator_ID() {
|
||||
return M_Locator_ID;
|
||||
}
|
||||
|
||||
public BigDecimal getQtyOnHand() {
|
||||
return QtyOnHand;
|
||||
}
|
||||
|
||||
public BigDecimal getMovementQty() {
|
||||
return MovementQty;
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import java.util.Properties;
|
|||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.adempiere.exceptions.PeriodClosedException;
|
||||
import org.compiere.print.MPrintFormat;
|
||||
import org.compiere.print.ReportEngine;
|
||||
|
@ -1286,6 +1287,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
if (log.isLoggable(Level.INFO)) log.info(toString());
|
||||
StringBuilder info = new StringBuilder();
|
||||
|
||||
StringBuilder errors = new StringBuilder();
|
||||
// For all lines
|
||||
MInOutLine[] lines = getLines(false);
|
||||
for (int lineIndex = 0; lineIndex < lines.length; lineIndex++)
|
||||
|
@ -1293,6 +1295,8 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
MInOutLine sLine = lines[lineIndex];
|
||||
MProduct product = sLine.getProduct();
|
||||
|
||||
try
|
||||
{
|
||||
// Qty & Type
|
||||
String MovementType = getMovementType();
|
||||
BigDecimal Qty = sLine.getMovementQty();
|
||||
|
@ -1649,9 +1653,21 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
}
|
||||
} // No Order
|
||||
} // PO Matching
|
||||
|
||||
}
|
||||
catch (NegativeInventoryDisallowedException e)
|
||||
{
|
||||
log.severe(e.getMessage());
|
||||
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(sLine.getLine()).append(": ");
|
||||
errors.append(e.getMessage()).append("\n");
|
||||
}
|
||||
} // for all lines
|
||||
|
||||
if (errors.toString().length() > 0)
|
||||
{
|
||||
m_processMsg = errors.toString();
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
// Counter Documents
|
||||
MInOut counter = createCounterDoc();
|
||||
if (counter != null)
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.adempiere.exceptions.PeriodClosedException;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
|
@ -435,6 +436,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
approveIt();
|
||||
if (log.isLoggable(Level.INFO)) log.info(toString());
|
||||
|
||||
StringBuilder errors = new StringBuilder();
|
||||
MInventoryLine[] lines = getLines(false);
|
||||
for (MInventoryLine line : lines)
|
||||
{
|
||||
|
@ -442,7 +444,8 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
continue;
|
||||
|
||||
MProduct product = line.getProduct();
|
||||
|
||||
try
|
||||
{
|
||||
BigDecimal qtyDiff = Env.ZERO;
|
||||
if (MDocType.DOCSUBTYPEINV_InternalUseInventory.equals(docSubTypeInv))
|
||||
qtyDiff = line.getQtyInternalUse().negate();
|
||||
|
@ -619,9 +622,22 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
}
|
||||
} // Fallback
|
||||
} // stock movement
|
||||
}
|
||||
catch (NegativeInventoryDisallowedException e)
|
||||
{
|
||||
log.severe(e.getMessage());
|
||||
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
|
||||
errors.append(e.getMessage()).append("\n");
|
||||
}
|
||||
|
||||
} // for all lines
|
||||
|
||||
if (errors.toString().length() > 0)
|
||||
{
|
||||
m_processMsg = errors.toString();
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
// User Validation
|
||||
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||
if (valid != null)
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.adempiere.exceptions.PeriodClosedException;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
|
@ -416,6 +417,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
approveIt();
|
||||
if (log.isLoggable(Level.INFO)) log.info(toString());
|
||||
|
||||
StringBuilder errors = new StringBuilder();
|
||||
//
|
||||
MMovementLine[] lines = getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
|
@ -425,6 +427,8 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
|
||||
//Stock Movement - Counterpart MOrder.reserveStock
|
||||
MProduct product = line.getProduct();
|
||||
try
|
||||
{
|
||||
if (product != null
|
||||
&& product.isStocked() )
|
||||
{
|
||||
|
@ -592,7 +596,21 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
}
|
||||
} // Fallback
|
||||
} // product stock
|
||||
}
|
||||
catch (NegativeInventoryDisallowedException e)
|
||||
{
|
||||
log.severe(e.getMessage());
|
||||
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
|
||||
errors.append(e.getMessage()).append("\n");
|
||||
}
|
||||
} // for all lines
|
||||
|
||||
if (errors.toString().length() > 0)
|
||||
{
|
||||
m_processMsg = errors.toString();
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
// User Validation
|
||||
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||
if (valid != null)
|
||||
|
|
|
@ -22,8 +22,11 @@ import java.sql.Timestamp;
|
|||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
|
||||
/**
|
||||
* Project Issue Model
|
||||
|
@ -172,6 +175,8 @@ public class MProjectIssue extends X_C_ProjectIssue
|
|||
dateMPolicy = t;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
|
||||
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
||||
getMovementQty().negate(),dateMPolicy, get_TrxName()))
|
||||
|
@ -189,6 +194,16 @@ public class MProjectIssue extends X_C_ProjectIssue
|
|||
}
|
||||
else
|
||||
log.log(Level.SEVERE, "Storage not updated"); // OK
|
||||
}
|
||||
catch (NegativeInventoryDisallowedException e)
|
||||
{
|
||||
log.severe(e.getMessage());
|
||||
StringBuilder error = new StringBuilder();
|
||||
error.append(Msg.getElement(getCtx(), "Line")).append(" ").append(getLine()).append(": ");
|
||||
error.append(e.getMessage()).append("\n");
|
||||
throw new AdempiereException(error.toString());
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
} // process
|
||||
|
|
|
@ -27,11 +27,10 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
|
||||
/**
|
||||
|
@ -735,7 +734,8 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
if (getQtyOnHand().signum() == -1) {
|
||||
MWarehouse wh = MWarehouse.get(Env.getCtx(), getM_Warehouse_ID());
|
||||
if (wh.isDisallowNegativeInv()) {
|
||||
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "NegativeInventoryDisallowed"));
|
||||
throw new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), getM_Locator_ID(),
|
||||
getQtyOnHand().subtract(addition), addition.negate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -899,13 +899,15 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
if (getQtyOnHand().compareTo(BigDecimal.ZERO) < 0 ||
|
||||
QtyOnHand.compareTo(Env.ZERO) < 0)
|
||||
{
|
||||
log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed"));
|
||||
log.saveError("Error", new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(),
|
||||
getM_AttributeSetInstance_ID(), getM_Locator_ID(), QtyOnHand.subtract(getQtyOnHand()), getQtyOnHand().negate()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getM_AttributeSetInstance_ID() > 0 && getQtyOnHand().signum() < 0)
|
||||
{
|
||||
log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed"));
|
||||
log.saveError("Error", new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(),
|
||||
getM_AttributeSetInstance_ID(), getM_Locator_ID(), QtyOnHand.subtract(getQtyOnHand()), getQtyOnHand().negate()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Properties;
|
|||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MBPartnerLocation;
|
||||
import org.compiere.model.MDocType;
|
||||
|
@ -847,6 +848,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
BigDecimal Volume = Env.ZERO;
|
||||
BigDecimal Weight = Env.ZERO;
|
||||
|
||||
StringBuilder errors = new StringBuilder();
|
||||
// Always check and (un) Reserve Inventory
|
||||
for (MDDOrderLine line : lines)
|
||||
{
|
||||
|
@ -873,6 +875,8 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
// Check Product - Stocked and Item
|
||||
MProduct product = line.getProduct();
|
||||
if (product != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (product.isStocked())
|
||||
{
|
||||
|
@ -900,9 +904,19 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
//
|
||||
Volume = Volume.add(product.getVolume().multiply(line.getQtyOrdered()));
|
||||
Weight = Weight.add(product.getWeight().multiply(line.getQtyOrdered()));
|
||||
}
|
||||
catch (NegativeInventoryDisallowedException e)
|
||||
{
|
||||
log.severe(e.getMessage());
|
||||
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
|
||||
errors.append(e.getMessage()).append("\n");
|
||||
}
|
||||
} // product
|
||||
} // reverse inventory
|
||||
|
||||
if (errors.toString().length() > 0)
|
||||
throw new AdempiereException(errors.toString());
|
||||
|
||||
setVolume(Volume);
|
||||
setWeight(Weight);
|
||||
} // reserveStock
|
||||
|
|
Loading…
Reference in New Issue