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:
Carlos Ruiz 2024-07-16 09:57:18 +02:00
parent bcc6bd5684
commit aac79ae622
15 changed files with 293 additions and 86 deletions

View File

@ -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')
;

View File

@ -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')
;

View File

@ -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";

View File

@ -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;

View File

@ -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()}));
} }
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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
*/ */

View File

@ -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

View File

@ -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
/** /**

View File

@ -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());

View File

@ -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);

View File

@ -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);