IDEMPIERE-5567 Support of UUID as Key (FHCA-4195) - Recent Items (#1856)
* IDEMPIERE-5567 Support of UUID as Key (FHCA-4195) - Recent Items - Implement support for recent items for UUID based tables - Refactor MRecentItem for better performance * - fixes
This commit is contained in:
parent
281333e8b9
commit
430823153f
|
@ -0,0 +1,88 @@
|
|||
-- IDEMPIERE-5567 Support of UUID as Key (FHCA-4195)
|
||||
SELECT register_migration_script('202305231609_IDEMPIERE-5567.sql') FROM dual;
|
||||
|
||||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- May 23, 2023, 4:09:37 PM CEST
|
||||
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215841,0,'Record UUID',200000,'Record_UU',36,'N','N','N','N','N',0,'N',200240,0,0,'Y',TO_TIMESTAMP('2023-05-23 16:09:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-05-23 16:09:37','YYYY-MM-DD HH24:MI:SS'),100,203804,'N','N','D','N','N','N','N','e4000430-78d0-42f3-bb99-d4cf8d32df5f','N','N','N','M','N')
|
||||
;
|
||||
|
||||
-- May 23, 2023, 4:09:45 PM CEST
|
||||
ALTER TABLE AD_RecentItem ADD Record_UU VARCHAR2(36 CHAR) DEFAULT NULL
|
||||
;
|
||||
|
||||
|
||||
SET SERVEROUTPUT on;
|
||||
|
||||
-- Set Record_UU for existing records
|
||||
DECLARE
|
||||
cmd varchar2(2000);
|
||||
v_cnt numeric;
|
||||
BEGIN
|
||||
FOR r IN (
|
||||
SELECT DISTINCT t.TableName, ri.AD_Table_ID
|
||||
FROM AD_RecentItem ri
|
||||
JOIN AD_Table t ON (ri.AD_Table_ID=t.AD_Table_ID)
|
||||
WHERE ri.Record_UU IS NULL
|
||||
AND ri.Record_ID IS NOT NULL
|
||||
) LOOP
|
||||
cmd := 'UPDATE AD_RecentItem SET Record_UU=(SELECT '
|
||||
|| r.TableName
|
||||
|| '_UU FROM '
|
||||
|| r.TableName
|
||||
|| ' WHERE '
|
||||
|| r.TableName
|
||||
|| '_ID=AD_RecentItem.Record_ID) WHERE AD_Table_ID='
|
||||
|| r.AD_Table_ID
|
||||
|| ' AND Record_ID IS NOT NULL AND Record_UU IS NULL';
|
||||
EXECUTE IMMEDIATE cmd;
|
||||
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' AD_RecentItem.Record_UU set in ' || r.TableName);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
-- May 23, 2023, 7:17:27 PM CEST
|
||||
DROP INDEX AD_RecentItem_Record_ID_AD_Table_ID
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:34 PM CEST
|
||||
UPDATE AD_TableIndex SET Name='AD_RecentItem_Record_UU_AD_Table_ID',Updated=TO_TIMESTAMP('2023-05-23 19:17:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_TableIndex_ID=201116
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:39 PM CEST
|
||||
UPDATE AD_IndexColumn SET AD_Column_ID=215841,Updated=TO_TIMESTAMP('2023-05-23 19:17:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=201489
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:44 PM CEST
|
||||
CREATE INDEX AD_RecentItem_Record_UU_AD_Table_ID ON AD_RecentItem (Record_UU,AD_Table_ID)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:09 PM CEST
|
||||
INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201248,'3247c587-b7fb-4b66-93a5-ad05d386e0c5',TO_TIMESTAMP('2023-05-23 19:18:08','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','AD_RecentItem_AD_User_ID',TO_TIMESTAMP('2023-05-23 19:18:08','YYYY-MM-DD HH24:MI:SS'),100,200000,'N','N','N','N','N')
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:19 PM CEST
|
||||
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201687,'a10d5fdb-351f-4798-a4d8-4e5f3de4995b',TO_TIMESTAMP('2023-05-23 19:18:17','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2023-05-23 19:18:17','YYYY-MM-DD HH24:MI:SS'),100,200006,201248,10)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:27 PM CEST
|
||||
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201688,'a06c4a1d-b923-479c-9415-e2d049e2ac90',TO_TIMESTAMP('2023-05-23 19:18:27','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2023-05-23 19:18:27','YYYY-MM-DD HH24:MI:SS'),100,200000,201248,20)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:32 PM CEST
|
||||
CREATE INDEX AD_RecentItem_AD_User_ID ON AD_RecentItem (AD_User_ID,AD_Client_ID)
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:07 PM CEST
|
||||
UPDATE AD_Column SET IsMandatory='N', IsToolbarButton='N',Updated=TO_TIMESTAMP('2023-05-26 19:30:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=200011
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:10 PM CEST
|
||||
ALTER TABLE AD_RecentItem MODIFY Record_ID NUMBER(10) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:10 PM CEST
|
||||
ALTER TABLE AD_RecentItem MODIFY Record_ID NULL
|
||||
;
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
-- IDEMPIERE-5567 Support of UUID as Key (FHCA-4195)
|
||||
SELECT register_migration_script('202305231609_IDEMPIERE-5567.sql') FROM dual;
|
||||
|
||||
-- May 23, 2023, 4:09:37 PM CEST
|
||||
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (215841,0,'Record UUID',200000,'Record_UU',36,'N','N','N','N','N',0,'N',200240,0,0,'Y',TO_TIMESTAMP('2023-05-23 16:09:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-05-23 16:09:37','YYYY-MM-DD HH24:MI:SS'),100,203804,'N','N','D','N','N','N','N','e4000430-78d0-42f3-bb99-d4cf8d32df5f','N','N','N','M','N')
|
||||
;
|
||||
|
||||
-- May 23, 2023, 4:09:45 PM CEST
|
||||
ALTER TABLE AD_RecentItem ADD COLUMN Record_UU VARCHAR(36) DEFAULT NULL
|
||||
;
|
||||
|
||||
|
||||
-- Set Record_UU for existing records
|
||||
DO $$
|
||||
DECLARE
|
||||
cmd varchar(2000);
|
||||
r record;
|
||||
v_cnt numeric;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT DISTINCT t.TableName, ri.AD_Table_ID
|
||||
FROM AD_RecentItem ri
|
||||
JOIN AD_Table t ON (ri.AD_Table_ID=t.AD_Table_ID)
|
||||
WHERE ri.Record_UU IS NULL
|
||||
AND ri.Record_ID IS NOT NULL
|
||||
LOOP
|
||||
cmd := 'UPDATE AD_RecentItem SET Record_UU=(SELECT '
|
||||
|| r.TableName
|
||||
|| '_UU FROM '
|
||||
|| r.TableName
|
||||
|| ' WHERE '
|
||||
|| r.TableName
|
||||
|| '_ID=AD_RecentItem.Record_ID) WHERE AD_Table_ID='
|
||||
|| r.AD_Table_ID
|
||||
|| ' AND Record_ID IS NOT NULL AND Record_UU IS NULL';
|
||||
EXECUTE cmd;
|
||||
GET DIAGNOSTICS v_cnt = ROW_COUNT;
|
||||
RAISE NOTICE '% AD_RecentItem.Record_UU set in %', v_cnt, r.TableName;
|
||||
END LOOP;
|
||||
END;
|
||||
$$
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:27 PM CEST
|
||||
DROP INDEX AD_RecentItem_Record_ID_AD_Table_ID
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:34 PM CEST
|
||||
UPDATE AD_TableIndex SET Name='AD_RecentItem_Record_UU_AD_Table_ID',Updated=TO_TIMESTAMP('2023-05-23 19:17:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_TableIndex_ID=201116
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:39 PM CEST
|
||||
UPDATE AD_IndexColumn SET AD_Column_ID=215841,Updated=TO_TIMESTAMP('2023-05-23 19:17:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=201489
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:17:44 PM CEST
|
||||
CREATE INDEX AD_RecentItem_Record_UU_AD_Table_ID ON AD_RecentItem (Record_UU,AD_Table_ID)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:09 PM CEST
|
||||
INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201248,'3247c587-b7fb-4b66-93a5-ad05d386e0c5',TO_TIMESTAMP('2023-05-23 19:18:08','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','AD_RecentItem_AD_User_ID',TO_TIMESTAMP('2023-05-23 19:18:08','YYYY-MM-DD HH24:MI:SS'),100,200000,'N','N','N','N','N')
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:19 PM CEST
|
||||
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201687,'a10d5fdb-351f-4798-a4d8-4e5f3de4995b',TO_TIMESTAMP('2023-05-23 19:18:17','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2023-05-23 19:18:17','YYYY-MM-DD HH24:MI:SS'),100,200006,201248,10)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:27 PM CEST
|
||||
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201688,'a06c4a1d-b923-479c-9415-e2d049e2ac90',TO_TIMESTAMP('2023-05-23 19:18:27','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2023-05-23 19:18:27','YYYY-MM-DD HH24:MI:SS'),100,200000,201248,20)
|
||||
;
|
||||
|
||||
-- May 23, 2023, 7:18:32 PM CEST
|
||||
CREATE INDEX AD_RecentItem_AD_User_ID ON AD_RecentItem (AD_User_ID,AD_Client_ID)
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:07 PM CEST
|
||||
UPDATE AD_Column SET IsMandatory='N', IsToolbarButton='N',Updated=TO_TIMESTAMP('2023-05-26 19:30:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=200011
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:10 PM CEST
|
||||
INSERT INTO t_alter_column values('ad_recentitem','Record_ID','NUMERIC(10)',null,'NULL')
|
||||
;
|
||||
|
||||
-- May 26, 2023, 7:30:10 PM CEST
|
||||
INSERT INTO t_alter_column values('ad_recentitem','Record_ID',null,'NULL',null)
|
||||
;
|
||||
|
|
@ -197,6 +197,15 @@ public interface I_AD_RecentItem
|
|||
*/
|
||||
public int getRecord_ID();
|
||||
|
||||
/** Column name Record_UU */
|
||||
public static final String COLUMNNAME_Record_UU = "Record_UU";
|
||||
|
||||
/** Set Record UUID */
|
||||
public void setRecord_UU (String Record_UU);
|
||||
|
||||
/** Get Record UUID */
|
||||
public String getRecord_UU();
|
||||
|
||||
/** Column name Updated */
|
||||
public static final String COLUMNNAME_Updated = "Updated";
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.model;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -26,13 +24,12 @@ import java.util.logging.Level;
|
|||
|
||||
import org.adempiere.base.Core;
|
||||
import org.adempiere.base.event.EventManager;
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.cache.ImmutablePOCache;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.distributed.IMessageService;
|
||||
import org.idempiere.distributed.ITopic;
|
||||
import org.osgi.service.event.Event;
|
||||
|
@ -47,7 +44,7 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6564296810614189111L;
|
||||
private static final long serialVersionUID = 4298877865937943663L;
|
||||
|
||||
public static final String ON_RECENT_ITEM_CHANGED_TOPIC = "onRecentItemChanged";
|
||||
|
||||
|
@ -80,6 +77,12 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
super (ctx, AD_RecentItem_ID, trxName);
|
||||
} // MRecentItem
|
||||
|
||||
/**
|
||||
* Get the cache key AD_RecentItem_ID|Language
|
||||
* @param AD_RecentItem_ID
|
||||
* @param ctx
|
||||
* @return
|
||||
*/
|
||||
private static String getCacheKey(int AD_RecentItem_ID, Properties ctx) {
|
||||
return AD_RecentItem_ID + "|" + Env.getAD_Language(ctx);
|
||||
}
|
||||
|
@ -169,17 +172,17 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
* Get Recent Item from Cache using table+recordID (immutable)
|
||||
* @param ctx context
|
||||
* @param AD_Table_ID tableID
|
||||
* @param Record_ID recordID
|
||||
* @param Record_UU record UUID
|
||||
* @return recent item
|
||||
*/
|
||||
public static synchronized MRecentItem get (Properties ctx, int AD_Table_ID, int Record_ID, int AD_User_ID)
|
||||
public static synchronized MRecentItem get (Properties ctx, int AD_Table_ID, String Record_UU, int AD_User_ID)
|
||||
{
|
||||
Iterator<MRecentItem> it = s_cache.values().iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
MRecentItem retValue = it.next();
|
||||
if (retValue.getAD_Table_ID() == AD_Table_ID
|
||||
&& retValue.getRecord_ID() == Record_ID
|
||||
&& retValue.getRecord_UU().equals(Record_UU)
|
||||
&& retValue.getAD_User_ID() == AD_User_ID
|
||||
&& retValue.getAD_Client_ID() == Env.getAD_Client_ID(ctx)
|
||||
&& Env.getAD_Language(ctx).equals(Env.getAD_Language(retValue.getCtx()))
|
||||
|
@ -189,30 +192,9 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
}
|
||||
}
|
||||
//
|
||||
MRecentItem retValue = null;
|
||||
String sql = "SELECT * FROM AD_RecentItem WHERE AD_Table_ID=? AND Record_ID=? AND NVL(AD_User_ID,0)=? AND AD_Client_ID=?";
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt(1, AD_Table_ID);
|
||||
pstmt.setInt(2, Record_ID);
|
||||
pstmt.setInt(3, AD_User_ID);
|
||||
pstmt.setInt(4, Env.getAD_Client_ID(ctx));
|
||||
rs = pstmt.executeQuery ();
|
||||
if (rs.next ())
|
||||
retValue = new MRecentItem (ctx, rs, null);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
throw new AdempiereException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
MRecentItem retValue = new Query(ctx, Table_Name, "AD_Table_ID=? AND Record_UU=? AND AD_User_ID=? AND AD_Client_ID=?", null)
|
||||
.setParameters(AD_Table_ID, Record_UU, AD_User_ID, Env.getAD_Client_ID(ctx))
|
||||
.first();
|
||||
if (retValue != null)
|
||||
{
|
||||
String key = getCacheKey(retValue.getAD_RecentItem_ID(), ctx);
|
||||
|
@ -221,19 +203,28 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
return retValue;
|
||||
} // get
|
||||
|
||||
/*
|
||||
/**
|
||||
* addModifiedField / method to be called when first field is modified on a window
|
||||
* it adds a record in recent item, or touches the record if it was added before
|
||||
* @param ctx
|
||||
* @param AD_Table_ID
|
||||
* @param Record_ID
|
||||
* @param Record_UU
|
||||
* @param AD_User_ID
|
||||
* @param AD_Role_ID
|
||||
* @param AD_Window_ID
|
||||
* @param AD_Tab_ID
|
||||
*/
|
||||
public static void addModifiedField(Properties ctx, int AD_Table_ID, int Record_ID, int AD_User_ID, int AD_Role_ID, int AD_Window_ID, int AD_Tab_ID) {
|
||||
public static void addModifiedField(Properties ctx, int AD_Table_ID, int Record_ID, String Record_UU, int AD_User_ID, int AD_Role_ID, int AD_Window_ID, int AD_Tab_ID) {
|
||||
int maxri = MSysConfig.getIntValue(MSysConfig.RecentItems_MaxSaved, 50, Env.getAD_Client_ID(ctx));
|
||||
if (maxri <= 0)
|
||||
return;
|
||||
MRecentItem ric = get(ctx, AD_Table_ID, Record_ID, AD_User_ID);
|
||||
MRecentItem ric = get(ctx, AD_Table_ID, Record_UU, AD_User_ID);
|
||||
if (ric == null) {
|
||||
MRecentItem ri = new MRecentItem(ctx, 0, null);
|
||||
ri.setAD_Table_ID(AD_Table_ID);
|
||||
ri.setRecord_ID(Record_ID);
|
||||
ri.setRecord_UU(Record_UU);
|
||||
ri.setAD_User_ID(AD_User_ID);
|
||||
ri.setAD_Role_ID(AD_Role_ID);
|
||||
ri.setAD_Window_ID(AD_Window_ID);
|
||||
|
@ -265,6 +256,9 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
publishChangedEvent(AD_User_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AD_User_ID
|
||||
*/
|
||||
public static void publishChangedEvent(int AD_User_ID) {
|
||||
IMessageService service = Core.getMessageService();
|
||||
if (service != null) {
|
||||
|
@ -275,6 +269,9 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AD_User_ID
|
||||
*/
|
||||
public static void postOnChangedEvent(int AD_User_ID) {
|
||||
Map<String, Integer> properties = new HashMap<String, Integer>();
|
||||
properties.put("AD_User_ID", AD_User_ID);
|
||||
|
@ -282,13 +279,17 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
EventManager.getInstance().postEvent(event);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* touchUpdatedRecord / method to be called when a record is saved or updated in database
|
||||
* it touches the record added before
|
||||
* also delete recent items beyond the number of records allowed per user
|
||||
* @param ctx
|
||||
* @param AD_Table_ID
|
||||
* @param Record_UU
|
||||
* @param AD_User_ID
|
||||
*/
|
||||
public static void touchUpdatedRecord(Properties ctx, int AD_Table_ID, int Record_ID, int AD_User_ID) {
|
||||
MRecentItem ri = get(ctx, AD_Table_ID, Record_ID, AD_User_ID);
|
||||
public static void touchUpdatedRecord(Properties ctx, int AD_Table_ID, String Record_UU, int AD_User_ID) {
|
||||
MRecentItem ri = get(ctx, AD_Table_ID, Record_UU, AD_User_ID);
|
||||
if (ri != null) {
|
||||
DB.executeUpdateEx("UPDATE AD_RecentItem SET Updated=getDate() WHERE AD_RecentItem_ID=?", new Object[] {ri.getAD_RecentItem_ID()}, null);
|
||||
deleteExtraRecentItems(ctx, AD_User_ID);
|
||||
|
@ -296,53 +297,44 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the recent items beyond the maximum number of records configured in SysConfig RecentItems_MaxSaved
|
||||
* @param ctx
|
||||
* @param AD_User_ID
|
||||
*/
|
||||
private static void deleteExtraRecentItems(Properties ctx, int AD_User_ID) {
|
||||
int AD_Client_ID = Env.getAD_Client_ID(ctx);
|
||||
int maxri = MSysConfig.getIntValue(MSysConfig.RecentItems_MaxSaved, 50, AD_Client_ID);
|
||||
if (maxri < 0)
|
||||
maxri = 0;
|
||||
int cntri = DB.getSQLValue(null, "SELECT COUNT(*) FROM AD_RecentItem WHERE NVL(AD_User_ID,0)=? AND AD_Client_ID=?", AD_User_ID, AD_Client_ID);
|
||||
if (cntri > maxri) {
|
||||
int cntdel = cntri - maxri;
|
||||
String sql = "SELECT * FROM AD_RecentItem WHERE NVL(AD_User_ID,0)=? AND AD_Client_ID=? ORDER BY Updated";
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt(1, AD_User_ID);
|
||||
pstmt.setInt(2, AD_Client_ID);
|
||||
rs = pstmt.executeQuery ();
|
||||
while (rs.next()) {
|
||||
MRecentItem ri = new MRecentItem(ctx, rs, (String)null);
|
||||
ri.deleteEx(true);
|
||||
cntdel--;
|
||||
if (cntdel == 0)
|
||||
break;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
throw new AdempiereException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(boolean force) {
|
||||
String ii = getCacheKey(getAD_RecentItem_ID(), getCtx());
|
||||
if (maxri <= 0)
|
||||
maxri = 50;
|
||||
final String sql = ""
|
||||
+ "SELECT AD_RecentItem_ID FROM AD_RecentItem "
|
||||
+ "WHERE AD_User_ID=? AND AD_Client_ID=? AND AD_RecentItem_ID NOT IN ( "
|
||||
+ "SELECT AD_RecentItem_ID FROM AD_RecentItem WHERE AD_User_ID=? AND AD_Client_ID=? ORDER BY Updated DESC FETCH FIRST ? ROWS ONLY)";
|
||||
int ids[] = DB.getIDsEx(null, sql, AD_User_ID, AD_Client_ID, AD_User_ID, AD_Client_ID, maxri);
|
||||
if (ids.length > 0) {
|
||||
for (int id : ids) {
|
||||
String ii = getCacheKey(id, ctx);
|
||||
synchronized (MRecentItem.class) {
|
||||
s_cache.remove(ii);
|
||||
}
|
||||
return super.delete(force);
|
||||
}
|
||||
final String delete = ""
|
||||
+ "DELETE FROM AD_RecentItem "
|
||||
+ "WHERE AD_User_ID=? AND AD_Client_ID=? AND AD_RecentItem_ID NOT IN ( "
|
||||
+ "SELECT AD_RecentItem_ID FROM AD_RecentItem WHERE AD_User_ID=? AND AD_Client_ID=? ORDER BY Updated DESC FETCH FIRST ? ROWS ONLY)";
|
||||
DB.executeUpdateEx(delete, new Object[] {AD_User_ID, AD_Client_ID, AD_User_ID, AD_Client_ID, maxri}, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recent items from user - for performance obtain the ids and then get the MRecentItem from cache
|
||||
* @param ctx
|
||||
* @param AD_User_ID
|
||||
* @return
|
||||
*/
|
||||
public static List<MRecentItem> getFromUser(Properties ctx, int AD_User_ID) {
|
||||
int[] ids = new Query(ctx, MRecentItem.Table_Name, "NVL(AD_User_ID,0)=?", null)
|
||||
int[] ids = new Query(ctx, MRecentItem.Table_Name, "AD_User_ID=?", null)
|
||||
.setOnlyActiveRecords(true)
|
||||
.setClient_ID()
|
||||
.setParameters(AD_User_ID)
|
||||
|
@ -368,13 +360,13 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
windowName = win.get_Translation("Name");
|
||||
}
|
||||
MTable table = MTable.get(getCtx(), getAD_Table_ID());
|
||||
PO po = table.getPO(getRecord_ID(), null);
|
||||
PO po = table.getPOByUU(getRecord_UU(), null);
|
||||
if (po == null) {
|
||||
/* Recent Item was deleted (probably with direct SQL DELETE) */
|
||||
if (is_Immutable())
|
||||
new MRecentItem(Env.getCtx(), this).deleteEx(true);
|
||||
else
|
||||
this.deleteEx(true, null);
|
||||
String ii = getCacheKey(getAD_RecentItem_ID(), getCtx());
|
||||
synchronized (MRecentItem.class) {
|
||||
s_cache.remove(ii);
|
||||
}
|
||||
DB.executeUpdateEx("DELETE FROM AD_RecentItem WHERE AD_RecentItem=?", new Object[] {getAD_RecentItem_ID()}, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -406,16 +398,24 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport
|
|||
return m_label;
|
||||
}
|
||||
|
||||
public static synchronized void clearLabel(int AD_Table_ID, int Record_ID) {
|
||||
/**
|
||||
* Clear the label (to display) in a recent item
|
||||
* @param AD_Table_ID
|
||||
* @param Record_ID
|
||||
*/
|
||||
public static synchronized void clearLabel(int AD_Table_ID, String Record_UU) {
|
||||
Iterator<MRecentItem> it = s_cache.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
MRecentItem retValue = it.next();
|
||||
if (retValue.getAD_Table_ID() == AD_Table_ID && retValue.getRecord_ID() == Record_ID) {
|
||||
if (retValue.getAD_Table_ID() == AD_Table_ID && retValue.getRecord_UU().equals(Record_UU)) {
|
||||
retValue.clearLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the label (to display)
|
||||
*/
|
||||
private void clearLabel() {
|
||||
m_label = null;
|
||||
}
|
||||
|
|
|
@ -2690,7 +2690,7 @@ public abstract class PO
|
|||
m_createNew = false;
|
||||
}
|
||||
if (!newRecord)
|
||||
MRecentItem.clearLabel(p_info.getAD_Table_ID(), get_ID());
|
||||
MRecentItem.clearLabel(p_info.getAD_Table_ID(), get_UUID());
|
||||
if (CacheMgt.get().hasCache(p_info.getTableName())) {
|
||||
if (!newRecord)
|
||||
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(p_info.getTableName(), get_ID()));
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_RecentItem extends PO implements I_AD_RecentItem, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20230409L;
|
||||
private static final long serialVersionUID = 20230523L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_RecentItem (Properties ctx, int AD_RecentItem_ID, String trxName)
|
||||
|
@ -309,4 +309,19 @@ public class X_AD_RecentItem extends PO implements I_AD_RecentItem, I_Persistent
|
|||
return 0;
|
||||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** Set Record UUID.
|
||||
@param Record_UU Record UUID
|
||||
*/
|
||||
public void setRecord_UU (String Record_UU)
|
||||
{
|
||||
set_ValueNoCheck (COLUMNNAME_Record_UU, Record_UU);
|
||||
}
|
||||
|
||||
/** Get Record UUID.
|
||||
@return Record UUID */
|
||||
public String getRecord_UU()
|
||||
{
|
||||
return (String)get_Value(COLUMNNAME_Record_UU);
|
||||
}
|
||||
}
|
|
@ -2003,17 +2003,17 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
|
||||
//update recent item
|
||||
if (changed && !readOnly && !toolbar.isSaveEnable() ) {
|
||||
if (tabPanel.getGridTab().getRecord_ID() > 0) {
|
||||
if (!Util.isEmpty(tabPanel.getGridTab().getRecord_UU())) {
|
||||
if (adTabbox.getSelectedIndex() == 0 && !detailTab) {
|
||||
MRecentItem.addModifiedField(ctx, adTabbox.getSelectedGridTab().getAD_Table_ID(),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), Env.getAD_User_ID(ctx),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), adTabbox.getSelectedGridTab().getRecord_UU(), Env.getAD_User_ID(ctx),
|
||||
Env.getAD_Role_ID(ctx), adTabbox.getSelectedGridTab().getAD_Window_ID(),
|
||||
adTabbox.getSelectedGridTab().getAD_Tab_ID());
|
||||
} else {
|
||||
GridTab mainTab = getMainTabAbove();
|
||||
if (mainTab != null) {
|
||||
MRecentItem.addModifiedField(ctx, mainTab.getAD_Table_ID(),
|
||||
mainTab.getRecord_ID(), Env.getAD_User_ID(ctx),
|
||||
mainTab.getRecord_ID(), mainTab.getRecord_UU(), Env.getAD_User_ID(ctx),
|
||||
Env.getAD_Role_ID(ctx), mainTab.getAD_Window_ID(),
|
||||
mainTab.getAD_Tab_ID());
|
||||
}
|
||||
|
@ -2264,7 +2264,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
focusToActivePanel();
|
||||
// IDEMPIERE-1328 - refresh recent item after running a process, i.e. completing a doc that changes documentno
|
||||
MRecentItem.touchUpdatedRecord(ctx, adTabbox.getSelectedGridTab().getAD_Table_ID(),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), Env.getAD_User_ID(ctx));
|
||||
adTabbox.getSelectedGridTab().getRecord_UU(), Env.getAD_User_ID(ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2853,17 +2853,17 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
|
||||
if (wasChanged) {
|
||||
if (newRecord) {
|
||||
if (adTabbox.getSelectedGridTab().getRecord_ID() > 0) {
|
||||
if (!Util.isEmpty(adTabbox.getSelectedGridTab().getRecord_UU())) {
|
||||
if (adTabbox.getSelectedIndex() == 0) {
|
||||
MRecentItem.addModifiedField(ctx, adTabbox.getSelectedGridTab().getAD_Table_ID(),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), Env.getAD_User_ID(ctx),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), adTabbox.getSelectedGridTab().getRecord_UU(), Env.getAD_User_ID(ctx),
|
||||
Env.getAD_Role_ID(ctx), adTabbox.getSelectedGridTab().getAD_Window_ID(),
|
||||
adTabbox.getSelectedGridTab().getAD_Tab_ID());
|
||||
} else {
|
||||
GridTab mainTab = getMainTabAbove();
|
||||
if (mainTab != null) {
|
||||
MRecentItem.addModifiedField(ctx, mainTab.getAD_Table_ID(),
|
||||
mainTab.getRecord_ID(), Env.getAD_User_ID(ctx),
|
||||
mainTab.getRecord_ID(), mainTab.getRecord_UU(), Env.getAD_User_ID(ctx),
|
||||
Env.getAD_Role_ID(ctx), mainTab.getAD_Window_ID(),
|
||||
mainTab.getAD_Tab_ID());
|
||||
}
|
||||
|
@ -2872,12 +2872,12 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
} else {
|
||||
if (adTabbox.getSelectedIndex() == 0) {
|
||||
MRecentItem.touchUpdatedRecord(ctx, adTabbox.getSelectedGridTab().getAD_Table_ID(),
|
||||
adTabbox.getSelectedGridTab().getRecord_ID(), Env.getAD_User_ID(ctx));
|
||||
adTabbox.getSelectedGridTab().getRecord_UU(), Env.getAD_User_ID(ctx));
|
||||
} else {
|
||||
GridTab mainTab = getMainTabAbove();
|
||||
if (mainTab != null) {
|
||||
MRecentItem.touchUpdatedRecord(ctx, mainTab.getAD_Table_ID(),
|
||||
mainTab.getRecord_ID(), Env.getAD_User_ID(ctx));
|
||||
mainTab.getRecord_UU(), Env.getAD_User_ID(ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.compiere.model.MRecentItem;
|
|||
import org.compiere.model.MRole;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
|
@ -230,11 +231,10 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
catch (Exception e) {
|
||||
}
|
||||
|
||||
if (AD_RecentItem_ID > 0) {
|
||||
if ( AD_RecentItem_ID > 0) {
|
||||
MRecentItem ri = MRecentItem.get(Env.getCtx(), AD_RecentItem_ID);
|
||||
String TableName = MTable.getTableName(Env.getCtx(), ri.getAD_Table_ID());
|
||||
MQuery query = MQuery.getEqualQuery(TableName + "_ID", ri.getRecord_ID());
|
||||
|
||||
MQuery query = MQuery.getEqualQuery(PO.getUUIDColumnName(TableName), ri.getRecord_UU());
|
||||
SessionManager.getAppDesktop().openWindow(ri.getAD_Window_ID(), query, null);
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
|
|||
for (MRecentItem ri : ris) {
|
||||
if (ri.getAD_Window_ID() > 0 && MRole.getDefault().getWindowAccess(ri.getAD_Window_ID()) == null)
|
||||
continue;
|
||||
if (ri.getAD_Window_ID() > 0 && !MRole.getDefault().isRecordAccess(ri.getAD_Table_ID(), ri.getRecord_ID(), true))
|
||||
if (ri.getAD_Window_ID() > 0 && ri.getRecord_ID() > 0 && !MRole.getDefault().isRecordAccess(ri.getAD_Table_ID(), ri.getRecord_ID(), true))
|
||||
continue;
|
||||
|
||||
String label = ri.getLabel();
|
||||
|
|
Loading…
Reference in New Issue