IDEMPIERE-6188 Read-Only Session (#2415)
* IDEMPIERE-6188 Read-Only Session * IDEMPIERE-6188 Read-Only Session - improvements suggested by Nicolas Micoud and Alejandro Guerra
This commit is contained in:
parent
bcc6bd5684
commit
aac79ae622
|
|
@ -0,0 +1,50 @@
|
||||||
|
-- IDEMPIERE-6188 Read-Only Session
|
||||||
|
SELECT register_migration_script('202407061229_IDEMPIERE-6188.sql') FROM dual;
|
||||||
|
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:29:56 PM CEST
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203938,0,0,'Y',TO_TIMESTAMP('2024-07-06 12:29:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:29:42','YYYY-MM-DD HH24:MI:SS'),100,'IsReadOnlySession','Read Only Session',NULL,NULL,'Read Only Session','D','6ee179e4-9573-4a3d-8815-23723ef241d7')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:19 PM CEST
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,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,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml,IsPartitionKey) VALUES (216614,0,'Read Only Session',200174,'IsReadOnlySession','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2024-07-06 12:30:18','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:30:18','YYYY-MM-DD HH24:MI:SS'),100,203938,'Y','N','D','N','N','N','Y','8c255baa-fbec-4a90-a43d-5461060368e9','Y',0,'N','N','N','N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:29 PM CEST
|
||||||
|
ALTER TABLE AD_UserPreference ADD IsReadOnlySession CHAR(1) DEFAULT 'N' CHECK (IsReadOnlySession IN ('Y','N')) NOT NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:45 PM CEST
|
||||||
|
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208494,'Read Only Session',200189,216614,'Y',1,170,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2024-07-06 12:30:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:30:45','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','f69131e7-4fca-4011-89d5-650ca506c920','Y',170,2,2)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=110,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206133
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=120,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206134
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=130,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206407
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=140,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208189
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=150, XPosition=5,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208494
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:25 PM CEST
|
||||||
|
UPDATE AD_Field SET IsQuickEntry='Y',Updated=TO_TIMESTAMP('2024-07-06 12:31:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208494
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 9, 2024, 7:48:40 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Read-only session',0,0,'Y',TO_TIMESTAMP('2024-07-09 19:48:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-09 19:48:39','YYYY-MM-DD HH24:MI:SS'),100,200900,'ReadOnlySession','D','dc819f55-662d-4d30-b68d-0a93b46a8458')
|
||||||
|
;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
-- IDEMPIERE-6188 Read-Only Session
|
||||||
|
SELECT register_migration_script('202407061229_IDEMPIERE-6188.sql') FROM dual;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:29:56 PM CEST
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203938,0,0,'Y',TO_TIMESTAMP('2024-07-06 12:29:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:29:42','YYYY-MM-DD HH24:MI:SS'),100,'IsReadOnlySession','Read Only Session',NULL,NULL,'Read Only Session','D','6ee179e4-9573-4a3d-8815-23723ef241d7')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:19 PM CEST
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,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,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml,IsPartitionKey) VALUES (216614,0,'Read Only Session',200174,'IsReadOnlySession','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2024-07-06 12:30:18','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:30:18','YYYY-MM-DD HH24:MI:SS'),100,203938,'Y','N','D','N','N','N','Y','8c255baa-fbec-4a90-a43d-5461060368e9','Y',0,'N','N','N','N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:29 PM CEST
|
||||||
|
ALTER TABLE AD_UserPreference ADD COLUMN IsReadOnlySession CHAR(1) DEFAULT 'N' CHECK (IsReadOnlySession IN ('Y','N')) NOT NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:30:45 PM CEST
|
||||||
|
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208494,'Read Only Session',200189,216614,'Y',1,170,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2024-07-06 12:30:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-06 12:30:45','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','f69131e7-4fca-4011-89d5-650ca506c920','Y',170,2,2)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=110,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206133
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=120,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206134
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=130,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206407
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET SeqNo=140,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208189
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:06 PM CEST
|
||||||
|
UPDATE AD_Field SET IsDisplayed='Y', SeqNo=150, XPosition=5,Updated=TO_TIMESTAMP('2024-07-06 12:31:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208494
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 6, 2024, 12:31:25 PM CEST
|
||||||
|
UPDATE AD_Field SET IsQuickEntry='Y',Updated=TO_TIMESTAMP('2024-07-06 12:31:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208494
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jul 9, 2024, 7:48:40 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Read-only session',0,0,'Y',TO_TIMESTAMP('2024-07-09 19:48:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2024-07-09 19:48:39','YYYY-MM-DD HH24:MI:SS'),100,200900,'ReadOnlySession','D','dc819f55-662d-4d30-b68d-0a93b46a8458')
|
||||||
|
;
|
||||||
|
|
||||||
|
|
@ -62,21 +62,6 @@ public interface I_AD_UserPreference
|
||||||
*/
|
*/
|
||||||
public int getAD_Org_ID();
|
public int getAD_Org_ID();
|
||||||
|
|
||||||
/** Column name AD_User_ID */
|
|
||||||
public static final String COLUMNNAME_AD_User_ID = "AD_User_ID";
|
|
||||||
|
|
||||||
/** Set User/Contact.
|
|
||||||
* User within the system - Internal or Business Partner Contact
|
|
||||||
*/
|
|
||||||
public void setAD_User_ID (int AD_User_ID);
|
|
||||||
|
|
||||||
/** Get User/Contact.
|
|
||||||
* User within the system - Internal or Business Partner Contact
|
|
||||||
*/
|
|
||||||
public int getAD_User_ID();
|
|
||||||
|
|
||||||
public org.compiere.model.I_AD_User getAD_User() throws RuntimeException;
|
|
||||||
|
|
||||||
/** Column name AD_UserPreference_ID */
|
/** Column name AD_UserPreference_ID */
|
||||||
public static final String COLUMNNAME_AD_UserPreference_ID = "AD_UserPreference_ID";
|
public static final String COLUMNNAME_AD_UserPreference_ID = "AD_UserPreference_ID";
|
||||||
|
|
||||||
|
|
@ -95,6 +80,21 @@ public interface I_AD_UserPreference
|
||||||
/** Get AD_UserPreference_UU */
|
/** Get AD_UserPreference_UU */
|
||||||
public String getAD_UserPreference_UU();
|
public String getAD_UserPreference_UU();
|
||||||
|
|
||||||
|
/** Column name AD_User_ID */
|
||||||
|
public static final String COLUMNNAME_AD_User_ID = "AD_User_ID";
|
||||||
|
|
||||||
|
/** Set User/Contact.
|
||||||
|
* User within the system - Internal or Business Partner Contact
|
||||||
|
*/
|
||||||
|
public void setAD_User_ID (int AD_User_ID);
|
||||||
|
|
||||||
|
/** Get User/Contact.
|
||||||
|
* User within the system - Internal or Business Partner Contact
|
||||||
|
*/
|
||||||
|
public int getAD_User_ID();
|
||||||
|
|
||||||
|
public org.compiere.model.I_AD_User getAD_User() throws RuntimeException;
|
||||||
|
|
||||||
/** Column name AutoCommit */
|
/** Column name AutoCommit */
|
||||||
public static final String COLUMNNAME_AutoCommit = "AutoCommit";
|
public static final String COLUMNNAME_AutoCommit = "AutoCommit";
|
||||||
|
|
||||||
|
|
@ -104,6 +104,15 @@ public interface I_AD_UserPreference
|
||||||
/** Get Automatic Commit */
|
/** Get Automatic Commit */
|
||||||
public boolean isAutoCommit();
|
public boolean isAutoCommit();
|
||||||
|
|
||||||
|
/** Column name AutoNew */
|
||||||
|
public static final String COLUMNNAME_AutoNew = "AutoNew";
|
||||||
|
|
||||||
|
/** Set Automatic New Record */
|
||||||
|
public void setAutoNew (boolean AutoNew);
|
||||||
|
|
||||||
|
/** Get Automatic New Record */
|
||||||
|
public boolean isAutoNew();
|
||||||
|
|
||||||
/** Column name AutomaticDecimalPlacesForAmoun */
|
/** Column name AutomaticDecimalPlacesForAmoun */
|
||||||
public static final String COLUMNNAME_AutomaticDecimalPlacesForAmoun = "AutomaticDecimalPlacesForAmoun";
|
public static final String COLUMNNAME_AutomaticDecimalPlacesForAmoun = "AutomaticDecimalPlacesForAmoun";
|
||||||
|
|
||||||
|
|
@ -117,15 +126,6 @@ public interface I_AD_UserPreference
|
||||||
*/
|
*/
|
||||||
public int getAutomaticDecimalPlacesForAmoun();
|
public int getAutomaticDecimalPlacesForAmoun();
|
||||||
|
|
||||||
/** Column name AutoNew */
|
|
||||||
public static final String COLUMNNAME_AutoNew = "AutoNew";
|
|
||||||
|
|
||||||
/** Set Automatic New Record */
|
|
||||||
public void setAutoNew (boolean AutoNew);
|
|
||||||
|
|
||||||
/** Get Automatic New Record */
|
|
||||||
public boolean isAutoNew();
|
|
||||||
|
|
||||||
/** Column name Created */
|
/** Column name Created */
|
||||||
public static final String COLUMNNAME_Created = "Created";
|
public static final String COLUMNNAME_Created = "Created";
|
||||||
|
|
||||||
|
|
@ -177,6 +177,15 @@ public interface I_AD_UserPreference
|
||||||
/** Get Detailed Zoom Across */
|
/** Get Detailed Zoom Across */
|
||||||
public boolean isDetailedZoomAcross();
|
public boolean isDetailedZoomAcross();
|
||||||
|
|
||||||
|
/** Column name IsReadOnlySession */
|
||||||
|
public static final String COLUMNNAME_IsReadOnlySession = "IsReadOnlySession";
|
||||||
|
|
||||||
|
/** Set Read Only Session */
|
||||||
|
public void setIsReadOnlySession (boolean IsReadOnlySession);
|
||||||
|
|
||||||
|
/** Get Read Only Session */
|
||||||
|
public boolean isReadOnlySession();
|
||||||
|
|
||||||
/** Column name IsUseSimilarTo */
|
/** Column name IsUseSimilarTo */
|
||||||
public static final String COLUMNNAME_IsUseSimilarTo = "IsUseSimilarTo";
|
public static final String COLUMNNAME_IsUseSimilarTo = "IsUseSimilarTo";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,8 @@ public class MGoal extends X_PA_Goal
|
||||||
public boolean updateGoal(boolean force)
|
public boolean updateGoal(boolean force)
|
||||||
{
|
{
|
||||||
if (log.isLoggable(Level.CONFIG)) log.config("Force=" + force);
|
if (log.isLoggable(Level.CONFIG)) log.config("Force=" + force);
|
||||||
|
if (Env.isReadOnlySession())
|
||||||
|
return false;
|
||||||
MMeasure measure = MMeasure.get(getPA_Measure_ID());
|
MMeasure measure = MMeasure.get(getPA_Measure_ID());
|
||||||
|
|
||||||
boolean isUpdateByInterfal = false;
|
boolean isUpdateByInterfal = false;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import java.util.logging.Level;
|
||||||
|
|
||||||
import org.adempiere.base.Core;
|
import org.adempiere.base.Core;
|
||||||
import org.adempiere.base.event.EventManager;
|
import org.adempiere.base.event.EventManager;
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.compiere.print.MPrintFormat;
|
import org.compiere.print.MPrintFormat;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
|
|
@ -343,6 +344,9 @@ public class MPInstance extends X_AD_PInstance
|
||||||
procMsg.append(proc.get_Translation("Name")).append(" / ");
|
procMsg.append(proc.get_Translation("Name")).append(" / ");
|
||||||
}
|
}
|
||||||
procMsg.append(proc.getName()).append("]");
|
procMsg.append(proc.getName()).append("]");
|
||||||
|
if (Env.isReadOnlySession())
|
||||||
|
throw new AdempiereException(Msg.getMsg(getCtx(), "ReadOnlySession"));
|
||||||
|
else
|
||||||
throw new IllegalStateException(Msg.getMsg(getCtx(), "CannotAccessProcess", new Object[] {procMsg.toString(), role.getName()}));
|
throw new IllegalStateException(Msg.getMsg(getCtx(), "CannotAccessProcess", new Object[] {procMsg.toString(), role.getName()}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1673,6 +1673,9 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("#" + m_windowAccess.size());
|
if (log.isLoggable(Level.FINE)) log.fine("#" + m_windowAccess.size());
|
||||||
} // reload
|
} // reload
|
||||||
Boolean retValue = m_windowAccess.get(AD_Window_ID);
|
Boolean retValue = m_windowAccess.get(AD_Window_ID);
|
||||||
|
// User Preference window is excluded - otherwise the user would not be able to reset the read-only session preference
|
||||||
|
if (retValue != null && AD_Window_ID != SystemIDs.WINDOW_USER_PREFERENCE && Env.isReadOnlySession())
|
||||||
|
retValue = Boolean.FALSE;
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("getWindowAccess - AD_Window_ID=" + AD_Window_ID + " - " + retValue);
|
if (log.isLoggable(Level.FINE)) log.fine("getWindowAccess - AD_Window_ID=" + AD_Window_ID + " - " + retValue);
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getWindowAccess
|
} // getWindowAccess
|
||||||
|
|
@ -1765,6 +1768,8 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
|
||||||
retValue = null;
|
retValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (retValue != null && Env.isReadOnlySession())
|
||||||
|
retValue = Boolean.FALSE;
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getProcessAccess
|
} // getProcessAccess
|
||||||
|
|
||||||
|
|
@ -1854,6 +1859,8 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
|
||||||
retValue = null;
|
retValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (retValue != null && Env.isReadOnlySession())
|
||||||
|
retValue = Boolean.FALSE;
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getTaskAccess
|
} // getTaskAccess
|
||||||
|
|
||||||
|
|
@ -1943,6 +1950,8 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
|
||||||
retValue = null;
|
retValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (retValue != null && Env.isReadOnlySession())
|
||||||
|
retValue = Boolean.FALSE;
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getFormAccess
|
} // getFormAccess
|
||||||
|
|
||||||
|
|
@ -2032,6 +2041,8 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
|
||||||
retValue = null;
|
retValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (retValue != null && Env.isReadOnlySession())
|
||||||
|
retValue = Boolean.FALSE;
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getWorkflowAccess
|
} // getWorkflowAccess
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ package org.compiere.model;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.compiere.util.CacheMgt;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
|
||||||
public class MUserPreference extends X_AD_UserPreference {
|
public class MUserPreference extends X_AD_UserPreference {
|
||||||
|
|
@ -124,8 +125,17 @@ public class MUserPreference extends X_AD_UserPreference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean afterSave(boolean newRecord, boolean success) {
|
protected boolean afterSave(boolean newRecord, boolean success) {
|
||||||
if (success)
|
if (success) {
|
||||||
fillPreferences();
|
fillPreferences();
|
||||||
|
if (is_ValueChanged(COLUMNNAME_IsReadOnlySession)) {
|
||||||
|
// Cache reset in same thread
|
||||||
|
CacheMgt.get().reset(MRole.Table_Name);
|
||||||
|
// reset cache to re-read the ReadOnly logic
|
||||||
|
CacheMgt.get().reset(MWindow.Table_Name);
|
||||||
|
CacheMgt.get().reset(MTab.Table_Name);
|
||||||
|
CacheMgt.get().reset(MField.Table_Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ public abstract class PO
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 6591172659109078284L;
|
private static final long serialVersionUID = 3145791881535121558L;
|
||||||
|
|
||||||
/* String key to create a new record based in UUID constructor */
|
/* String key to create a new record based in UUID constructor */
|
||||||
public static final String UUID_NEW_RECORD = "";
|
public static final String UUID_NEW_RECORD = "";
|
||||||
|
|
@ -2345,6 +2345,8 @@ public abstract class PO
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checkReadOnlySession())
|
||||||
|
return false;
|
||||||
checkImmutable();
|
checkImmutable();
|
||||||
checkValidContext();
|
checkValidContext();
|
||||||
checkCrossTenant(true);
|
checkCrossTenant(true);
|
||||||
|
|
@ -2569,6 +2571,32 @@ public abstract class PO
|
||||||
}
|
}
|
||||||
} // save
|
} // save
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tables allowed to be written in a read-only session
|
||||||
|
*/
|
||||||
|
final Set<String> ALLOWED_TABLES_IN_RO_SESSION = new HashSet<>(Arrays.asList(new String[] {
|
||||||
|
"AD_ChangeLog",
|
||||||
|
"AD_Preference",
|
||||||
|
"AD_Session",
|
||||||
|
"AD_UserPreference",
|
||||||
|
"AD_Wlistbox_Customization"
|
||||||
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not allow saving if in a read-only session, except the allowed tables
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean checkReadOnlySession() {
|
||||||
|
if (Env.isReadOnlySession()) {
|
||||||
|
if (! ALLOWED_TABLES_IN_RO_SESSION.contains(get_TableName())) {
|
||||||
|
log.saveError("Error", Msg.getMsg(getCtx(), "ReadOnlySession") + " [" + get_TableName() + "]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Value or create new record.
|
* Update Value or create new record.
|
||||||
* @throws AdempiereException
|
* @throws AdempiereException
|
||||||
|
|
@ -3927,6 +3955,8 @@ public abstract class PO
|
||||||
if (is_new())
|
if (is_new())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!checkReadOnlySession())
|
||||||
|
return false;
|
||||||
checkImmutable();
|
checkImmutable();
|
||||||
checkValidContext();
|
checkValidContext();
|
||||||
checkCrossTenant(true);
|
checkCrossTenant(true);
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ public class SystemIDs
|
||||||
public final static int WINDOW_RETURNTOVENDOR = 53098;
|
public final static int WINDOW_RETURNTOVENDOR = 53098;
|
||||||
public final static int WINDOW_SALES_ORDER = 143;
|
public final static int WINDOW_SALES_ORDER = 143;
|
||||||
public final static int WINDOW_SHIPMENT_CUSTOMER = 169;
|
public final static int WINDOW_SHIPMENT_CUSTOMER = 169;
|
||||||
|
public final static int WINDOW_USER_PREFERENCE = 200073;
|
||||||
public final static int WINDOW_VENDOR_RMA = 53099;
|
public final static int WINDOW_VENDOR_RMA = 53099;
|
||||||
public final static int WINDOW_WAREHOUSE_LOCATOR = 139;
|
public final static int WINDOW_WAREHOUSE_LOCATOR = 139;
|
||||||
public final static int WINDOW_WINDOW_TAB_FIELD = 102;
|
public final static int WINDOW_WINDOW_TAB_FIELD = 102;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 20231222L;
|
private static final long serialVersionUID = 20240719L;
|
||||||
|
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
public X_AD_UserPreference (Properties ctx, int AD_UserPreference_ID, String trxName)
|
public X_AD_UserPreference (Properties ctx, int AD_UserPreference_ID, String trxName)
|
||||||
|
|
@ -38,8 +38,10 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
super (ctx, AD_UserPreference_ID, trxName);
|
super (ctx, AD_UserPreference_ID, trxName);
|
||||||
/** if (AD_UserPreference_ID == 0)
|
/** if (AD_UserPreference_ID == 0)
|
||||||
{
|
{
|
||||||
setAD_User_ID (0);
|
|
||||||
setAD_UserPreference_ID (0);
|
setAD_UserPreference_ID (0);
|
||||||
|
setAD_User_ID (0);
|
||||||
|
setIsReadOnlySession (false);
|
||||||
|
// N
|
||||||
setViewFindResult (null);
|
setViewFindResult (null);
|
||||||
// 0
|
// 0
|
||||||
} */
|
} */
|
||||||
|
|
@ -51,8 +53,10 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
super (ctx, AD_UserPreference_ID, trxName, virtualColumns);
|
super (ctx, AD_UserPreference_ID, trxName, virtualColumns);
|
||||||
/** if (AD_UserPreference_ID == 0)
|
/** if (AD_UserPreference_ID == 0)
|
||||||
{
|
{
|
||||||
setAD_User_ID (0);
|
|
||||||
setAD_UserPreference_ID (0);
|
setAD_UserPreference_ID (0);
|
||||||
|
setAD_User_ID (0);
|
||||||
|
setIsReadOnlySession (false);
|
||||||
|
// N
|
||||||
setViewFindResult (null);
|
setViewFindResult (null);
|
||||||
// 0
|
// 0
|
||||||
} */
|
} */
|
||||||
|
|
@ -64,8 +68,10 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
super (ctx, AD_UserPreference_UU, trxName);
|
super (ctx, AD_UserPreference_UU, trxName);
|
||||||
/** if (AD_UserPreference_UU == null)
|
/** if (AD_UserPreference_UU == null)
|
||||||
{
|
{
|
||||||
setAD_User_ID (0);
|
|
||||||
setAD_UserPreference_ID (0);
|
setAD_UserPreference_ID (0);
|
||||||
|
setAD_User_ID (0);
|
||||||
|
setIsReadOnlySession (false);
|
||||||
|
// N
|
||||||
setViewFindResult (null);
|
setViewFindResult (null);
|
||||||
// 0
|
// 0
|
||||||
} */
|
} */
|
||||||
|
|
@ -77,8 +83,10 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
super (ctx, AD_UserPreference_UU, trxName, virtualColumns);
|
super (ctx, AD_UserPreference_UU, trxName, virtualColumns);
|
||||||
/** if (AD_UserPreference_UU == null)
|
/** if (AD_UserPreference_UU == null)
|
||||||
{
|
{
|
||||||
setAD_User_ID (0);
|
|
||||||
setAD_UserPreference_ID (0);
|
setAD_UserPreference_ID (0);
|
||||||
|
setAD_User_ID (0);
|
||||||
|
setIsReadOnlySession (false);
|
||||||
|
// N
|
||||||
setViewFindResult (null);
|
setViewFindResult (null);
|
||||||
// 0
|
// 0
|
||||||
} */
|
} */
|
||||||
|
|
@ -112,34 +120,6 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public org.compiere.model.I_AD_User getAD_User() throws RuntimeException
|
|
||||||
{
|
|
||||||
return (org.compiere.model.I_AD_User)MTable.get(getCtx(), org.compiere.model.I_AD_User.Table_ID)
|
|
||||||
.getPO(getAD_User_ID(), get_TrxName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set User/Contact.
|
|
||||||
@param AD_User_ID User within the system - Internal or Business Partner Contact
|
|
||||||
*/
|
|
||||||
public void setAD_User_ID (int AD_User_ID)
|
|
||||||
{
|
|
||||||
if (AD_User_ID < 1)
|
|
||||||
set_ValueNoCheck (COLUMNNAME_AD_User_ID, null);
|
|
||||||
else
|
|
||||||
set_ValueNoCheck (COLUMNNAME_AD_User_ID, Integer.valueOf(AD_User_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get User/Contact.
|
|
||||||
@return User within the system - Internal or Business Partner Contact
|
|
||||||
*/
|
|
||||||
public int getAD_User_ID()
|
|
||||||
{
|
|
||||||
Integer ii = (Integer)get_Value(COLUMNNAME_AD_User_ID);
|
|
||||||
if (ii == null)
|
|
||||||
return 0;
|
|
||||||
return ii.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set AD_UserPreference_ID.
|
/** Set AD_UserPreference_ID.
|
||||||
@param AD_UserPreference_ID AD_UserPreference_ID
|
@param AD_UserPreference_ID AD_UserPreference_ID
|
||||||
*/
|
*/
|
||||||
|
|
@ -176,6 +156,34 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
return (String)get_Value(COLUMNNAME_AD_UserPreference_UU);
|
return (String)get_Value(COLUMNNAME_AD_UserPreference_UU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public org.compiere.model.I_AD_User getAD_User() throws RuntimeException
|
||||||
|
{
|
||||||
|
return (org.compiere.model.I_AD_User)MTable.get(getCtx(), org.compiere.model.I_AD_User.Table_ID)
|
||||||
|
.getPO(getAD_User_ID(), get_TrxName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set User/Contact.
|
||||||
|
@param AD_User_ID User within the system - Internal or Business Partner Contact
|
||||||
|
*/
|
||||||
|
public void setAD_User_ID (int AD_User_ID)
|
||||||
|
{
|
||||||
|
if (AD_User_ID < 1)
|
||||||
|
set_ValueNoCheck (COLUMNNAME_AD_User_ID, null);
|
||||||
|
else
|
||||||
|
set_ValueNoCheck (COLUMNNAME_AD_User_ID, Integer.valueOf(AD_User_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get User/Contact.
|
||||||
|
@return User within the system - Internal or Business Partner Contact
|
||||||
|
*/
|
||||||
|
public int getAD_User_ID()
|
||||||
|
{
|
||||||
|
Integer ii = (Integer)get_Value(COLUMNNAME_AD_User_ID);
|
||||||
|
if (ii == null)
|
||||||
|
return 0;
|
||||||
|
return ii.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
/** Set Automatic Commit.
|
/** Set Automatic Commit.
|
||||||
@param AutoCommit Automatic Commit
|
@param AutoCommit Automatic Commit
|
||||||
*/
|
*/
|
||||||
|
|
@ -198,6 +206,28 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set Automatic New Record.
|
||||||
|
@param AutoNew Automatic New Record
|
||||||
|
*/
|
||||||
|
public void setAutoNew (boolean AutoNew)
|
||||||
|
{
|
||||||
|
set_Value (COLUMNNAME_AutoNew, Boolean.valueOf(AutoNew));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Automatic New Record.
|
||||||
|
@return Automatic New Record */
|
||||||
|
public boolean isAutoNew()
|
||||||
|
{
|
||||||
|
Object oo = get_Value(COLUMNNAME_AutoNew);
|
||||||
|
if (oo != null)
|
||||||
|
{
|
||||||
|
if (oo instanceof Boolean)
|
||||||
|
return ((Boolean)oo).booleanValue();
|
||||||
|
return "Y".equals(oo);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set Automatic Decimal Places For Amounts.
|
/** Set Automatic Decimal Places For Amounts.
|
||||||
@param AutomaticDecimalPlacesForAmoun Automatically insert a decimal point
|
@param AutomaticDecimalPlacesForAmoun Automatically insert a decimal point
|
||||||
*/
|
*/
|
||||||
|
|
@ -217,28 +247,6 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
return ii.intValue();
|
return ii.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set Automatic New Record.
|
|
||||||
@param AutoNew Automatic New Record
|
|
||||||
*/
|
|
||||||
public void setAutoNew (boolean AutoNew)
|
|
||||||
{
|
|
||||||
set_Value (COLUMNNAME_AutoNew, Boolean.valueOf(AutoNew));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get Automatic New Record.
|
|
||||||
@return Automatic New Record */
|
|
||||||
public boolean isAutoNew()
|
|
||||||
{
|
|
||||||
Object oo = get_Value(COLUMNNAME_AutoNew);
|
|
||||||
if (oo != null)
|
|
||||||
{
|
|
||||||
if (oo instanceof Boolean)
|
|
||||||
return ((Boolean)oo).booleanValue();
|
|
||||||
return "Y".equals(oo);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set Threshold.
|
/** Set Threshold.
|
||||||
@param GridAfterFindThreshold Force grid view when Find panel closes if number of records exceed threshold
|
@param GridAfterFindThreshold Force grid view when Find panel closes if number of records exceed threshold
|
||||||
*/
|
*/
|
||||||
|
|
@ -280,6 +288,28 @@ public class X_AD_UserPreference extends PO implements I_AD_UserPreference, I_Pe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set Read Only Session.
|
||||||
|
@param IsReadOnlySession Read Only Session
|
||||||
|
*/
|
||||||
|
public void setIsReadOnlySession (boolean IsReadOnlySession)
|
||||||
|
{
|
||||||
|
set_Value (COLUMNNAME_IsReadOnlySession, Boolean.valueOf(IsReadOnlySession));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Read Only Session.
|
||||||
|
@return Read Only Session */
|
||||||
|
public boolean isReadOnlySession()
|
||||||
|
{
|
||||||
|
Object oo = get_Value(COLUMNNAME_IsReadOnlySession);
|
||||||
|
if (oo != null)
|
||||||
|
{
|
||||||
|
if (oo instanceof Boolean)
|
||||||
|
return ((Boolean)oo).booleanValue();
|
||||||
|
return "Y".equals(oo);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set Use Similar To.
|
/** Set Use Similar To.
|
||||||
@param IsUseSimilarTo Use Similar To
|
@param IsUseSimilarTo Use Similar To
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -2329,4 +2329,12 @@ public final class Env
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is read only session? Based on user preference
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isReadOnlySession() {
|
||||||
|
return "Y".equals(Env.getContext(Env.getCtx(), "IsReadOnlySession"));
|
||||||
|
}
|
||||||
|
|
||||||
} // Env
|
} // Env
|
||||||
|
|
@ -752,11 +752,11 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
{
|
{
|
||||||
boolean visible = m_data.documentQuery && tabResult.isSelected();
|
boolean visible = m_data.documentQuery && tabResult.isSelected();
|
||||||
|
|
||||||
bRePost.setVisible(visible);
|
bRePost.setVisible(visible && !Env.isReadOnlySession());
|
||||||
bExport.setVisible(tabResult.isSelected());
|
bExport.setVisible(tabResult.isSelected());
|
||||||
bZoom.setVisible(tabResult.isSelected());
|
bZoom.setVisible(tabResult.isSelected());
|
||||||
|
|
||||||
forcePost.setVisible(visible);
|
forcePost.setVisible(visible && !Env.isReadOnlySession());
|
||||||
} // stateChanged
|
} // stateChanged
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.adempiere.util.IProcessUI;
|
import org.adempiere.util.IProcessUI;
|
||||||
import org.adempiere.webui.ISupportMask;
|
import org.adempiere.webui.ISupportMask;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
|
|
@ -91,6 +92,8 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
if (Env.isReadOnlySession())
|
||||||
|
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "ReadOnlySession"));
|
||||||
pi.setSummary (e.getLocalizedMessage());
|
pi.setSummary (e.getLocalizedMessage());
|
||||||
pi.setError (true);
|
pi.setError (true);
|
||||||
log.warning(pi.toString());
|
log.warning(pi.toString());
|
||||||
|
|
@ -168,6 +171,8 @@ public class WProcessCtl extends AbstractProcessCtl {
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
if (Env.isReadOnlySession())
|
||||||
|
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "ReadOnlySession"));
|
||||||
pi.setSummary (e.getLocalizedMessage());
|
pi.setSummary (e.getLocalizedMessage());
|
||||||
pi.setError (true);
|
pi.setError (true);
|
||||||
log.warning(pi.toString());
|
log.warning(pi.toString());
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
|
||||||
syncModel();
|
syncModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type.equals(ON_EVENT_CREATE_EVENT)) {
|
else if (type.equals(ON_EVENT_CREATE_EVENT) && !Env.isReadOnlySession()) {
|
||||||
if (e instanceof CalendarsEvent) {
|
if (e instanceof CalendarsEvent) {
|
||||||
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
|
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
|
||||||
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
|
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
|
||||||
else if (e.getTarget() == divArrowRight)
|
else if (e.getTarget() == divArrowRight)
|
||||||
divArrowClicked(true);
|
divArrowClicked(true);
|
||||||
}
|
}
|
||||||
else if (type.equals(ON_EVENT_CREATE_EVENT)) {
|
else if (type.equals(ON_EVENT_CREATE_EVENT) && ! Env.isReadOnlySession()) {
|
||||||
if (e instanceof CalendarsEvent) {
|
if (e instanceof CalendarsEvent) {
|
||||||
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
|
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
|
||||||
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
|
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue