diff --git a/migration/i2.0/oracle/201312051535_IDEMPIERE-337.sql b/migration/i2.0/oracle/201312051535_IDEMPIERE-337.sql new file mode 100644 index 0000000000..dd8d9a52f7 --- /dev/null +++ b/migration/i2.0/oracle/201312051535_IDEMPIERE-337.sql @@ -0,0 +1,18 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-337 zkwebui - Improve Info Product window +UPDATE M_Product_PO po +SET IsCurrentVendor='N' +WHERE po.IsActive='Y' +AND po.IsCurrentVendor='Y' +AND po.C_BPartner_ID NOT IN ( + SELECT MAX(ppo.C_BPartner_ID) + FROM M_Product_PO ppo + WHERE ppo.IsActive='Y' + AND ppo.IsCurrentVendor='Y' + AND ppo.M_Product_ID = po.M_Product_ID +); + +SELECT register_migration_script('201312051535_IDEMPIERE-337') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0/postgresql/201312051535_IDEMPIERE-337.sql b/migration/i2.0/postgresql/201312051535_IDEMPIERE-337.sql new file mode 100644 index 0000000000..fd2829156a --- /dev/null +++ b/migration/i2.0/postgresql/201312051535_IDEMPIERE-337.sql @@ -0,0 +1,15 @@ +-- IDEMPIERE-337 zkwebui - Improve Info Product window +UPDATE M_Product_PO po +SET IsCurrentVendor='N' +WHERE po.IsActive='Y' +AND po.IsCurrentVendor='Y' +AND po.C_BPartner_ID NOT IN ( + SELECT MAX(ppo.C_BPartner_ID) + FROM M_Product_PO ppo + WHERE ppo.IsActive='Y' + AND ppo.IsCurrentVendor='Y' + AND ppo.M_Product_ID = po.M_Product_ID +); + +SELECT register_migration_script('201312051535_IDEMPIERE-337') FROM dual +; \ No newline at end of file diff --git a/org.adempiere.base.callout/src/org/compiere/model/CalloutInvoice.java b/org.adempiere.base.callout/src/org/compiere/model/CalloutInvoice.java index 0adede9787..b3e36dc703 100644 --- a/org.adempiere.base.callout/src/org/compiere/model/CalloutInvoice.java +++ b/org.adempiere.base.callout/src/org/compiere/model/CalloutInvoice.java @@ -510,6 +510,8 @@ public class CalloutInvoice extends CalloutEngine int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); int StdPrecision = MPriceList.getStandardPrecision(ctx, M_PriceList_ID); + MPriceList pl = new MPriceList(ctx, M_PriceList_ID, null); + boolean isEnforcePriceLimit = pl.isEnforcePriceLimit(); BigDecimal QtyEntered, QtyInvoiced, PriceEntered, PriceActual, PriceLimit, Discount, PriceList; // get values QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); @@ -630,7 +632,7 @@ public class CalloutInvoice extends CalloutEngine // Check PriceLimit String epl = Env.getContext(ctx, WindowNo, "EnforcePriceLimit"); - boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && epl.equals("Y"); + boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && !epl.equals("") ? epl.equals("Y") : isEnforcePriceLimit; if (enforce && MRole.getDefault().isOverwritePriceLimit()) enforce = false; // Check Price Limit? diff --git a/org.adempiere.base.callout/src/org/compiere/model/CalloutOrder.java b/org.adempiere.base.callout/src/org/compiere/model/CalloutOrder.java index 8a5c2359e6..09331f172a 100644 --- a/org.adempiere.base.callout/src/org/compiere/model/CalloutOrder.java +++ b/org.adempiere.base.callout/src/org/compiere/model/CalloutOrder.java @@ -1038,6 +1038,8 @@ public class CalloutOrder extends CalloutEngine int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); int StdPrecision = MPriceList.getStandardPrecision(ctx, M_PriceList_ID); + MPriceList pl = new MPriceList(ctx, M_PriceList_ID, null); + boolean isEnforcePriceLimit = pl.isEnforcePriceLimit(); BigDecimal QtyEntered, QtyOrdered, PriceEntered, PriceActual, PriceLimit, Discount, PriceList; // get values QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); @@ -1158,7 +1160,7 @@ public class CalloutOrder extends CalloutEngine // Check PriceLimit String epl = Env.getContext(ctx, WindowNo, "EnforcePriceLimit"); - boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && epl.equals("Y"); + boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && !epl.equals("") ? epl.equals("Y") : isEnforcePriceLimit; if (enforce && MRole.getDefault().isOverwritePriceLimit()) enforce = false; // Check Price Limit? diff --git a/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java b/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java index 66060a4a68..efe60aee52 100644 --- a/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java +++ b/org.adempiere.base.process/src/org/compiere/process/ImportAccount.java @@ -25,6 +25,7 @@ import java.util.logging.Level; import org.compiere.model.MAccount; import org.compiere.model.MAcctSchema; +import org.compiere.model.MColumn; import org.compiere.model.MElementValue; import org.compiere.model.X_I_ElementValue; import org.compiere.util.DB; @@ -656,8 +657,14 @@ public class ImportAccount extends SvrProcess } // replace combination } // need to update } // for all default accounts - else - log.log(Level.SEVERE, "Account not found " + sql); + else { + // check if column is active before logging on SEVERE level + int columnID = MColumn.getColumn_ID(TableName, ColumnName); + if (new MColumn(getCtx(), columnID, get_TrxName()).isActive()) + log.log(Level.SEVERE, "Account not found " + sql); + else + log.log(Level.WARNING, "The account " + ColumnName + " is deprecated, you should consider removing it from your import file"); + } } catch (SQLException e) { diff --git a/org.adempiere.base/src/org/compiere/model/DataStatusEvent.java b/org.adempiere.base/src/org/compiere/model/DataStatusEvent.java index 18251591d4..0327477f1a 100644 --- a/org.adempiere.base/src/org/compiere/model/DataStatusEvent.java +++ b/org.adempiere.base/src/org/compiere/model/DataStatusEvent.java @@ -20,6 +20,8 @@ import java.io.Serializable; import java.sql.Timestamp; import java.util.EventObject; +import org.idempiere.fa.util.Util; + /** * Data Status Event *
@@ -337,4 +339,17 @@ public final class DataStatusEvent extends EventObject implements Serializable
return m_confirmed;
} // isConfirmed
+ public boolean isEqual(DataStatusEvent e) {
+ if (e == null) return false;
+
+ return e.m_changed == m_changed &&
+ e.m_inserting == m_inserting &&
+ e.m_isError == m_isError &&
+ e.m_isWarning == m_isWarning &&
+ Util.equals(e.m_AD_Message, m_AD_Message) &&
+ e.m_changedColumn == m_changedColumn &&
+ Util.equals(e.m_columnName, m_columnName) &&
+ e.m_currentRow == m_currentRow;
+ }
+
} // DataStatusEvent
diff --git a/org.adempiere.base/src/org/compiere/model/GridTab.java b/org.adempiere.base/src/org/compiere/model/GridTab.java
index c0d28b9e3b..18d4331f46 100644
--- a/org.adempiere.base/src/org/compiere/model/GridTab.java
+++ b/org.adempiere.base/src/org/compiere/model/GridTab.java
@@ -2251,7 +2251,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
* @param e event
*/
public void dataStatusChanged (DataStatusEvent e)
- {
+ {
if (log.isLoggable(Level.FINE)) log.fine("#" + m_vo.TabNo + " - " + e.toString());
int oldCurrentRow = e.getCurrentRow();
m_DataStatusEvent = e; // save it
@@ -2262,6 +2262,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
// set current row
m_DataStatusEvent = e; // setCurrentRow clear it, need to save again
m_DataStatusEvent.setCurrentRow(m_currentRow);
+
// Same row - update value
if (oldCurrentRow == m_currentRow)
{
@@ -2272,8 +2273,25 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
field.setValue(value, m_mTable.isInserting());
}
}
- else // Redistribute Info with current row info
- fireDataStatusChanged(m_DataStatusEvent);
+ else
+ {
+ // Redistribute Info with current row info
+ // Avoid firing of duplicate event
+ boolean fire = true;
+ if (m_lastDataStatusEvent != null)
+ {
+ if (System.currentTimeMillis() - m_lastDataStatusEventTime < 200)
+ {
+ if (m_lastDataStatusEvent.isEqual(m_DataStatusEvent))
+ {
+ fire = false;
+ }
+ }
+ }
+
+ if (fire)
+ fireDataStatusChanged(m_DataStatusEvent);
+ }
//reset
m_lastDataStatusEventTime = System.currentTimeMillis();
diff --git a/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java b/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java
index 7951b446cd..c32cbc48c4 100644
--- a/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java
+++ b/org.adempiere.base/src/org/compiere/model/MInvoiceLine.java
@@ -860,6 +860,19 @@ public class MInvoiceLine extends X_C_InvoiceLine
&& Env.ZERO.compareTo(getPriceActual()) == 0
&& Env.ZERO.compareTo(getPriceList()) == 0)
setPrice();
+ // IDEMPIERE-1574 Sales Order Line lets Price under the Price Limit when updating
+ // Check PriceLimit
+ boolean enforce = m_IsSOTrx && m_parent.getM_PriceList().isEnforcePriceLimit();
+ if (enforce && MRole.getDefault().isOverwritePriceLimit())
+ enforce = false;
+ // Check Price Limit?
+ if (enforce && getPriceLimit() != Env.ZERO
+ && getPriceActual().compareTo(getPriceLimit()) < 0)
+ {
+ log.saveError("UnderLimitPrice", "PriceEntered=" + getPriceEntered() + ", PriceLimit=" + getPriceLimit());
+ return false;
+ }
+ //
}
// Set Tax
diff --git a/org.adempiere.base/src/org/compiere/model/MMailText.java b/org.adempiere.base/src/org/compiere/model/MMailText.java
index 8acec867b3..53ac18a862 100644
--- a/org.adempiere.base/src/org/compiere/model/MMailText.java
+++ b/org.adempiere.base/src/org/compiere/model/MMailText.java
@@ -18,12 +18,15 @@ package org.compiere.model;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.text.SimpleDateFormat;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.util.CCache;
import org.compiere.util.DB;
+import org.compiere.util.DisplayType;
import org.compiere.util.Env;
+import org.compiere.util.Msg;
/**
* Request Mail Template Model.
@@ -221,6 +224,14 @@ public class MMailText extends X_R_MailText
Object value = null;
if (col != null && col.isSecure()) {
value = "********";
+ } else if (col.getAD_Reference_ID() == DisplayType.Date || col.getAD_Reference_ID() == DisplayType.DateTime || col.getAD_Reference_ID() == DisplayType.Time) {
+ SimpleDateFormat sdf = DisplayType.getDateFormat(col.getAD_Reference_ID());
+ value = sdf.format (po.get_Value(index));
+ } else if (col.getAD_Reference_ID() == DisplayType.YesNo) {
+ if (po.get_ValueAsBoolean(variable))
+ value = Msg.getMsg(Env.getCtx(), "Yes");
+ else
+ value = Msg.getMsg(Env.getCtx(), "No");
} else {
value = po.get_Value(index);
}
diff --git a/org.adempiere.base/src/org/compiere/model/MOrderLine.java b/org.adempiere.base/src/org/compiere/model/MOrderLine.java
index bc1df9dad5..dae5610880 100644
--- a/org.adempiere.base/src/org/compiere/model/MOrderLine.java
+++ b/org.adempiere.base/src/org/compiere/model/MOrderLine.java
@@ -870,6 +870,19 @@ public class MOrderLine extends X_C_OrderLine
// Check if on Price list
if (m_productPrice == null)
getProductPricing(m_M_PriceList_ID);
+ // IDEMPIERE-1574 Sales Order Line lets Price under the Price Limit when updating
+ // Check PriceLimit
+ boolean enforce = m_IsSOTrx && m_parent.getM_PriceList().isEnforcePriceLimit();
+ if (enforce && MRole.getDefault().isOverwritePriceLimit())
+ enforce = false;
+ // Check Price Limit?
+ if (enforce && getPriceLimit() != Env.ZERO
+ && getPriceActual().compareTo(getPriceLimit()) < 0)
+ {
+ log.saveError("UnderLimitPrice", "PriceEntered=" + getPriceEntered() + ", PriceLimit=" + getPriceLimit());
+ return false;
+ }
+ //
if (!m_productPrice.isCalculated())
{
throw new ProductNotOnPriceListException(m_productPrice, getLine());
diff --git a/org.adempiere.base/src/org/compiere/model/MProductPO.java b/org.adempiere.base/src/org/compiere/model/MProductPO.java
index dde9a5356b..b04471a1c9 100644
--- a/org.adempiere.base/src/org/compiere/model/MProductPO.java
+++ b/org.adempiere.base/src/org/compiere/model/MProductPO.java
@@ -19,6 +19,9 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.List;
import java.util.Properties;
+import java.util.logging.Level;
+
+import org.compiere.util.DB;
/**
* Product PO Model
@@ -31,8 +34,7 @@ public class MProductPO extends X_M_Product_PO
/**
*
*/
- private static final long serialVersionUID = -747761340543484440L;
-
+ private static final long serialVersionUID = -1883198806060209516L;
/**
* Get current PO of Product
@@ -84,4 +86,34 @@ public class MProductPO extends X_M_Product_PO
super(ctx, rs, trxName);
} // MProductPO
+ /**
+ * Before Save
+ * @param newRecord new
+ * @return true
+ */
+ @Override
+ protected boolean beforeSave(boolean newRecord)
+ {
+ if ((newRecord && isActive() && isCurrentVendor()) ||
+ (!newRecord &&
+ (
+ (is_ValueChanged("IsActive") && isActive()) // now active
+ || (is_ValueChanged("IsCurrentVendor") && isCurrentVendor()) // now current vendor
+ || is_ValueChanged("C_BPartner_ID")
+ || is_ValueChanged("M_Product_ID")
+ )
+ )
+ )
+ {
+ if (isActive() && isCurrentVendor())
+ {
+ String sql = "UPDATE M_Product_PO SET IsCurrentVendor='N' WHERE IsActive='Y' AND IsCurrentVendor='Y' AND C_BPartner_ID!=? AND M_Product_ID=?";
+ int no = DB.executeUpdate(sql, new Object[] {getC_BPartner_ID(), getM_Product_ID()}, false, get_TrxName());
+ if (log.isLoggable(Level.FINEST)) log.finest("Updated M_Product_PO.IsCurrentVendor #" + no);
+ }
+ }
+
+ return true;
+ }
+
} // MProductPO
diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java b/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java
index a1530e29c4..ea01ee7c68 100644
--- a/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java
+++ b/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java
@@ -29,6 +29,11 @@ public class PoExporter {
private void addTextElement(String qName, String text, AttributesImpl atts) {
try {
+ //default trim to false for print item label since trailing space is commonly use
+ //for formatting purpose
+ if (qName.equalsIgnoreCase("PrintName")) {
+ atts.addAttribute("", "", "trim", "CDATA", "false");
+ }
transformerHandler.startElement("", "", qName, atts);
append(text);
transformerHandler.endElement("", "", qName);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
index be306888f9..b81cdbfc93 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
@@ -28,6 +28,7 @@ import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.zkoss.zhtml.Text;
+import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@@ -244,7 +245,20 @@ public class Messagebox extends Window implements EventListener
").append(message);
}
return out;
diff --git a/org.adempiere.ui/src/org/compiere/apps/form/Allocation.java b/org.adempiere.ui/src/org/compiere/apps/form/Allocation.java
index 7bb72f5ae4..7ef931b896 100644
--- a/org.adempiere.ui/src/org/compiere/apps/form/Allocation.java
+++ b/org.adempiere.ui/src/org/compiere/apps/form/Allocation.java
@@ -30,6 +30,7 @@ import org.compiere.model.MAllocationLine;
import org.compiere.model.MInvoice;
import org.compiere.model.MPayment;
import org.compiere.model.MRole;
+import org.compiere.model.MSysConfig;
import org.compiere.process.DocAction;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
@@ -422,8 +423,9 @@ public class Allocation
{
if ( applied.signum() == -open.signum() )
applied = applied.negate();
- if ( open.abs().compareTo( applied.abs() ) < 0 )
- applied = open;
+ if (! MSysConfig.getBooleanValue("ALLOW_OVER_APPLIED_PAYMENT", false, Env.getAD_Client_ID(Env.getCtx())))
+ if ( open.abs().compareTo( applied.abs() ) < 0 )
+ applied = open;
}
payment.setValueAt(applied, row, i_payment);