diff --git a/base/src/org/adempiere/exceptions/ProductNotOnPriceListException.java b/base/src/org/adempiere/exceptions/ProductNotOnPriceListException.java
new file mode 100644
index 0000000000..18bece0516
--- /dev/null
+++ b/base/src/org/adempiere/exceptions/ProductNotOnPriceListException.java
@@ -0,0 +1,68 @@
+/**
+ *
+ */
+package org.adempiere.exceptions;
+
+import java.text.DateFormat;
+
+import org.compiere.model.MPriceList;
+import org.compiere.model.MProduct;
+import org.compiere.model.MProductPricing;
+import org.compiere.util.DisplayType;
+import org.compiere.util.Env;
+
+/**
+ * Throw when product price is not found in price list
+ * @author teo.sarca@gmail.com
+ *
FR [ 2872255 ] Introduce ProductNotOnPriceListException
+ * https://sourceforge.net/tracker/?func=detail&aid=2872255&group_id=176962&atid=879335
+ */
+public class ProductNotOnPriceListException extends AdempiereException
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3505579126676698444L;
+
+ public static final String AD_Message = "ProductNotOnPriceList";
+
+ public ProductNotOnPriceListException(MProductPricing productPricing, int documentLineNo)
+ {
+ super(buildMessage(productPricing, documentLineNo));
+ }
+
+ private static final String buildMessage (MProductPricing pp, int documentLineNo)
+ {
+ StringBuffer sb = new StringBuffer();
+ if (documentLineNo > 0)
+ {
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append("@Line@:").append(documentLineNo);
+ }
+ if (pp.getM_Product_ID() > 0)
+ {
+ MProduct p = MProduct.get(Env.getCtx(), pp.getM_Product_ID());
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append("@M_Product_ID@:").append(p == null ? "?" : p.get_Translation(MProduct.COLUMNNAME_Name));
+ }
+ if (pp.getM_PriceList_ID() > 0)
+ {
+ MPriceList pl = MPriceList.get(Env.getCtx(), pp.getM_PriceList_ID(), null);
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append("@M_PriceList_ID@:").append(pl == null ? "?" : pl.get_Translation(MPriceList.COLUMNNAME_Name));
+ }
+ if (pp.getPriceDate() != null)
+ {
+ DateFormat df = DisplayType.getDateFormat(DisplayType.Date);
+ if (sb.length() > 0)
+ sb.append(", ");
+ sb.append("@Date@:").append(df.format(pp.getPriceDate()));
+ }
+ //
+ sb.insert(0, "@"+AD_Message+"@ - ");
+ return sb.toString();
+ }
+}
diff --git a/base/src/org/compiere/model/MOrderLine.java b/base/src/org/compiere/model/MOrderLine.java
index 9e6c857ecc..38179ee506 100644
--- a/base/src/org/compiere/model/MOrderLine.java
+++ b/base/src/org/compiere/model/MOrderLine.java
@@ -22,7 +22,7 @@ import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
-import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.exceptions.ProductNotOnPriceListException;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
@@ -833,7 +833,7 @@ public class MOrderLine extends X_C_OrderLine
getProductPricing(m_M_PriceList_ID);
if (!m_productPrice.isCalculated())
{
- throw new AdempiereException("@ProductNotOnPriceList@ @Line@: "+getLine());
+ throw new ProductNotOnPriceListException(m_productPrice, getLine());
}
}