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
This commit is contained in:
hengsin 2020-08-27 18:40:44 +08:00 committed by GitHub
parent f13313760c
commit 9d614b985e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 4 deletions

View File

@ -2168,6 +2168,18 @@ public class GridTable extends AbstractTableModel
if (po == null) if (po == null)
throw new ClassNotFoundException ("No Persistent Object"); 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(); int size = m_fields.size();
for (int col = 0; col < size; col++) for (int col = 0; col < size; col++)
{ {
@ -3791,8 +3803,8 @@ public class GridTable extends AbstractTableModel
int colUpdated = findColumn("Updated"); int colUpdated = findColumn("Updated");
int colProcessed = findColumn("Processed"); int colProcessed = findColumn("Processed");
boolean hasUpdated = (colUpdated > 0); boolean hasUpdated = (colUpdated >= 0);
boolean hasProcessed = (colProcessed > 0); boolean hasProcessed = (colProcessed >= 0);
String columns = null; String columns = null;
if (hasUpdated && hasProcessed) { if (hasUpdated && hasProcessed) {
@ -3802,7 +3814,7 @@ public class GridTable extends AbstractTableModel
} else if (hasProcessed) { } else if (hasProcessed) {
columns = new String("Processed"); columns = new String("Processed");
} else { } else {
// no columns updated or processed to commpare // no columns updated or processed to compare
return false; return false;
} }
@ -3873,7 +3885,53 @@ public class GridTable extends AbstractTableModel
return false; 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 * get Parent Tab No
* @return Tab No * @return Tab No

View File

@ -1004,6 +1004,19 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
} }
if (gridTab.getCurrentRow() != rowIndex) { 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); gridTab.navigate(rowIndex);
return true; return true;
} }