From 9d614b985ecd2f501c6396876b089a75c3eca4d5 Mon Sep 17 00:00:00 2001 From: hengsin Date: Thu, 27 Aug 2020 18:40:44 +0800 Subject: [PATCH] IDEMPIERE-4424 (#222) * IDEMPIERE-4424 Concurrent update not prevented in Grid View Grid View - change click navigation to follow the same flow as toolbar navigation. * IDEMPIERE-4424 Concurrent update not prevented in Grid View GridTable - added Updated and Processed concurrency checked against PO. * IDEMPIERE-4424 Concurrent update not prevented in Grid View Incorporate fix suggested by Carlos --- .../src/org/compiere/model/GridTable.java | 66 +++++++++++++++++-- .../adempiere/webui/adwindow/GridView.java | 13 ++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/GridTable.java b/org.adempiere.base/src/org/compiere/model/GridTable.java index daa2d06c4b..05c343ad22 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTable.java +++ b/org.adempiere.base/src/org/compiere/model/GridTable.java @@ -2168,6 +2168,18 @@ public class GridTable extends AbstractTableModel if (po == null) throw new ClassNotFoundException ("No Persistent Object"); + if (!po.is_new()) + { + if (hasChanged(po)) + { + // return error stating that current record has changed and it cannot be saved + String adMessage = "CurrentRecordModified"; + String msg = Msg.getMsg(Env.getCtx(), adMessage); + fireDataStatusEEvent(adMessage, msg, true); + return SAVE_ERROR; + } + } + int size = m_fields.size(); for (int col = 0; col < size; col++) { @@ -3791,8 +3803,8 @@ public class GridTable extends AbstractTableModel int colUpdated = findColumn("Updated"); int colProcessed = findColumn("Processed"); - boolean hasUpdated = (colUpdated > 0); - boolean hasProcessed = (colProcessed > 0); + boolean hasUpdated = (colUpdated >= 0); + boolean hasProcessed = (colProcessed >= 0); String columns = null; if (hasUpdated && hasProcessed) { @@ -3802,7 +3814,7 @@ public class GridTable extends AbstractTableModel } else if (hasProcessed) { columns = new String("Processed"); } else { - // no columns updated or processed to commpare + // no columns updated or processed to compare return false; } @@ -3873,7 +3885,53 @@ public class GridTable extends AbstractTableModel return false; } - + // verify if the current record has changed + private boolean hasChanged(PO po) { + if (m_rowChanged < 0) + return false; + + // not so aggressive (it can has still concurrency problems) + // compare Updated, IsProcessed + int colUpdated = findColumn("Updated"); + int colProcessed = findColumn("Processed"); + + boolean hasUpdated = colUpdated >= 0; + boolean hasProcessed = colProcessed >= 0; + + if (!hasUpdated && !hasProcessed) { + // no columns updated or processed to compare + return false; + } + + Timestamp dbUpdated = (Timestamp) po.get_Value("Updated"); + if (hasUpdated) { + Timestamp memUpdated = null; + memUpdated = (Timestamp) getOldValue(m_rowChanged, colUpdated); + if (memUpdated == null) + memUpdated = (Timestamp) getValueAt(m_rowChanged, colUpdated); + + if (memUpdated != null && ! memUpdated.equals(dbUpdated)) + return true; + } + + if (hasProcessed) { + Boolean memProcessed = null; + memProcessed = (Boolean) getOldValue(m_rowChanged, colProcessed); + if (memProcessed == null){ + if(getValueAt(m_rowChanged, colProcessed) instanceof Boolean ) + memProcessed = (Boolean) getValueAt(m_rowChanged, colProcessed); + else if (getValueAt(m_rowChanged, colProcessed) instanceof String ) + memProcessed = Boolean.valueOf((String)getValueAt(m_rowChanged, colProcessed)); + } + + Boolean dbProcessed = po.get_ValueAsBoolean("Processed"); + if (memProcessed != null && ! memProcessed.equals(dbProcessed)) + return true; + } + + return false; + } + /** * get Parent Tab No * @return Tab No diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java index 94b4bbed08..c3e087620a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java @@ -1004,6 +1004,19 @@ public class GridView extends Vlayout implements EventListener, IdSpace, } if (gridTab.getCurrentRow() != rowIndex) { + ADWindow adwindow = ADWindow.findADWindow(this); + if (adwindow != null) { + final boolean[] retValue = new boolean[] {false}; + final int index = rowIndex; + adwindow.getADWindowContent().saveAndNavigate(e -> { + if (e) { + gridTab.navigate(index); + retValue[0] = true; + } + }); + return retValue[0]; + } + gridTab.navigate(rowIndex); return true; }