Merged from PI
authorUnai Martirena <unai.martirena@openbravo.com>
Wed, 04 May 2016 17:29:34 +0200
changeset 29598 38d5bd65817e
parent 29430 cc5778ec2ffc (current diff)
parent 29597 a6cbad47ab80 (diff)
child 29600 e3d34293e490
Merged from PI
modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java
modules/org.openbravo.apachejdbcconnectionpool/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.apachejdbcconnectionpool/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.base.weld/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.base.weld/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.application/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.application/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.htmlwidget/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.htmlwidget/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.kernel/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.kernel/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/SetContextInfoActionHandler.java
modules/org.openbravo.client.myob/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.myob/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.querylist/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.querylist/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.client.widgets/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.client.widgets/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.financial.paymentreport/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.financial.paymentreport/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.reports.ordersawaitingdelivery/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.reports.ordersawaitingdelivery/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.service.integration.google/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.service.integration.google/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.service.integration.openid/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.service.integration.openid/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.service.json/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.service.json/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.service.json/src/org/openbravo/service/json/QueryBuilder.java
modules/org.openbravo.userinterface.selector/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.userinterface.selector/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.userinterface.skin.250to300Comp/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.userinterface.skin.250to300Comp/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.userinterface.smartclient/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.userinterface.smartclient/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.utility.cleanup.log/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.utility.cleanup.log/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.v3.datasets/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.v3.datasets/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.v3.framework/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.v3.framework/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
modules/org.openbravo.v3/src-db/database/sourcedata/AD_MODULE.xml
modules/org.openbravo.v3/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml
src-db/database/lib/dbsourcemanager.jar
src-db/database/model/functions/C_ORDER_POST1.xml
src-db/database/model/functions/M_RESERVE_STOCK_AUTO.xml
src-db/database/sourcedata/AD_COLUMN.xml
src-db/database/sourcedata/AD_ELEMENT.xml
src-db/database/sourcedata/AD_FIELD.xml
src-db/database/sourcedata/AD_MODULE.xml
src-db/database/sourcedata/AD_REF_LIST.xml
src-db/database/sourcedata/OBUIAPP_PROCESS.xml
src-test/src/org/openbravo/test/AllAntTaskTests.java
src/org/openbravo/base/model/ModelProvider.java
src/org/openbravo/base/secureApp/LoginHandler.java
src/org/openbravo/common/datasource/ResultMapCriteriaUtils.java
--- a/.hgsigs	Wed May 04 13:23:26 2016 +0200
+++ b/.hgsigs	Wed May 04 17:29:34 2016 +0200
@@ -189,4 +189,6 @@
 24d2967df096de06913c9991553c1d84b07df9b6 0 iEYEABECAAYFAla9YYIACgkQCX/oGf+2qkNH7wCfV32iOyR/TQKzW/mH1iHTir6f6h4AoIlh4QBWIShpJqbJvx2IhfARpvUZ
 f016ea545c924ad099e9e402689035f1dd73baa2 0 iEYEABECAAYFAlbTzQoACgkQCX/oGf+2qkP28wCdFpNqpw+ODgF0p3cMJAbTZy1IPfoAoNEuRHkZIM5bNJMjwU0/GhjCtwah
 a53670f00eb6c9225829a660075fcfffa1109a1e 0 iEYEABECAAYFAlbqRpEACgkQCX/oGf+2qkN5qQCgsO1APX5AJ4cpb0oJX5vUQnvPMusAoPoDaQxGDihvsB4BSGW60RIxBdGC
+bdeb5a373f19eb7a144377621926d877ae2322f1 0 iEYEABECAAYFAlcgSPgACgkQCX/oGf+2qkMPLwCgzV//EHUa2bHmP8FA2IwnrFWB1X4AnjGHHjYKfSwiucQhltXR9POZXGaX
 38ef1dc10aa3d6fb8210b85beab370f62a4545ca 0 iEYEABECAAYFAlbiTM0ACgkQCX/oGf+2qkNBDwCfXmKXkqNGsAsfiofYOBBdvjA/XgkAoIwLK3DkmHeM71JihwfVOWyB4hmj
+265e8eccf704614fe88220026f2e2bafcebaaf00 0 iEYEABECAAYFAlcgZEQACgkQCX/oGf+2qkPuZgCcDPuB9d77M+51AglMvvmtpCDtnvoAnjqst7QgD6IP3Sv21+4vlqEjLVqU
--- a/.hgtags	Wed May 04 13:23:26 2016 +0200
+++ b/.hgtags	Wed May 04 17:29:34 2016 +0200
@@ -200,4 +200,6 @@
 9985680adffaf70ffcc1f560860feb10f0ee6b33 3.0PR15Q4.3
 70df4e4c5cab6d37f10eceee6b66be039c381556 3.0PR15Q4.4
 21c8ed48293c94cbe5875a8edef08aca0efd2bf4 3.0PR15Q4.5
+8828e6e8e071247f329320c63da66e30c357da9f 3.0PR15Q4.6
 ee5383e071318afe8eece515b4b264cfb46c1a84 3.0PR16Q1
+d386f41fa755d23e0e23f881aece691009051ebd 3.0PR16Q1.1
--- a/.settings/org.eclipse.jdt.core.prefs	Wed May 04 13:23:26 2016 +0200
+++ b/.settings/org.eclipse.jdt.core.prefs	Wed May 04 17:29:34 2016 +0200
@@ -1,4 +1,3 @@
-#Wed Jun 22 21:40:12 CEST 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
--- a/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_ELEMENT.xml	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_ELEMENT.xml	Wed May 04 17:29:34 2016 +0200
@@ -376,6 +376,20 @@
 <!--5D3526B2FC0F4BB2BE7FE13C5E9C009A-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
 <!--5D3526B2FC0F4BB2BE7FE13C5E9C009A--></AD_ELEMENT>
 
+<!--5EE957873DEE4461A57BA8CAEAF50943--><AD_ELEMENT>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <AD_ELEMENT_ID><![CDATA[5EE957873DEE4461A57BA8CAEAF50943]]></AD_ELEMENT_ID>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <COLUMNNAME><![CDATA[ad_org_id_process]]></COLUMNNAME>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <NAME><![CDATA[Process Organization]]></NAME>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <PRINTNAME><![CDATA[Process Organization]]></PRINTNAME>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <DESCRIPTION><![CDATA[Parameter used to save value of current Process Definition ad_org_id parameter.]]></DESCRIPTION>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <HELP><![CDATA[Parameter used to save value of current Process Definition ad_org_id parameter.]]></HELP>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <AD_MODULE_ID><![CDATA[A918E3331C404B889D69AA9BFAFB23AC]]></AD_MODULE_ID>
+<!--5EE957873DEE4461A57BA8CAEAF50943-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
+<!--5EE957873DEE4461A57BA8CAEAF50943--></AD_ELEMENT>
+
 <!--5FD519D1480447A092C2C08E6B462B8E--><AD_ELEMENT>
 <!--5FD519D1480447A092C2C08E6B462B8E-->  <AD_ELEMENT_ID><![CDATA[5FD519D1480447A092C2C08E6B462B8E]]></AD_ELEMENT_ID>
 <!--5FD519D1480447A092C2C08E6B462B8E-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Wed May 04 17:29:34 2016 +0200
@@ -561,6 +561,7 @@
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <DISPLAYLOGIC><![CDATA[@$Element_MC@='Y' & @trxtype@!'']]></DISPLAYLOGIC>
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <AD_FIELDGROUP_ID><![CDATA[800000]]></AD_FIELDGROUP_ID>
+<!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--4DB168F8AC3B4A4CB543489EDFF76AED-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -801,6 +802,7 @@
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <DISPLAYLOGIC><![CDATA[@$Element_AY@='Y' & @trxtype@!'']]></DISPLAYLOGIC>
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <AD_FIELDGROUP_ID><![CDATA[800000]]></AD_FIELDGROUP_ID>
+<!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--6BBDFF5E4AF944CB8AE94FE3D638BC49-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1655,6 +1657,7 @@
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--BAD646D5B19945A9B5DB573C35ABF2C5-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1733,6 +1736,7 @@
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--C11C22D9EDD3481981FEDC94B977E6F4-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--C11C22D9EDD3481981FEDC94B977E6F4-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1791,6 +1795,8 @@
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--C511B1965C2A46C2BD8144DB918CD17B-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
+<!--C511B1965C2A46C2BD8144DB918CD17B-->  <ONCHANGEFUNCTION><![CDATA[OB.APRM.AddTransaction.organizationOnChangeFunction]]></ONCHANGEFUNCTION>
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--C511B1965C2A46C2BD8144DB918CD17B-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1870,6 +1876,7 @@
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--D58EE6F45C72436DB613C79F5FE8A37C-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--D58EE6F45C72436DB613C79F5FE8A37C-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1898,6 +1905,7 @@
 <!--DA22BED18BD944C9B6252B8400B89934-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--DA22BED18BD944C9B6252B8400B89934-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--DA22BED18BD944C9B6252B8400B89934-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--DA22BED18BD944C9B6252B8400B89934-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--DA22BED18BD944C9B6252B8400B89934-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--DA22BED18BD944C9B6252B8400B89934-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--DA22BED18BD944C9B6252B8400B89934-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -1978,6 +1986,7 @@
 <!--E3019D02BA14437A9BE0948000062776-->  <OBUIAPP_PROCESS_ID><![CDATA[E68790A7B65F4D45AB35E2BAE34C1F39]]></OBUIAPP_PROCESS_ID>
 <!--E3019D02BA14437A9BE0948000062776-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--E3019D02BA14437A9BE0948000062776-->  <DISPLAYLOGIC><![CDATA[(@fin_payment_id@==null | @fin_payment_id@==undefined | @fin_payment_id@=='') & @trxtype@!'' & @trxtype@!'BF']]></DISPLAYLOGIC>
+<!--E3019D02BA14437A9BE0948000062776-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--E3019D02BA14437A9BE0948000062776-->  <ONCHANGEFUNCTION><![CDATA[OB.APRM.AddTransaction.glitemOnChangeFunction]]></ONCHANGEFUNCTION>
 <!--E3019D02BA14437A9BE0948000062776-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--E3019D02BA14437A9BE0948000062776-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
@@ -2094,6 +2103,7 @@
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--EE38C8A62FDC4554A241D5C590AD30B0-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--EE38C8A62FDC4554A241D5C590AD30B0-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -2176,6 +2186,7 @@
 <!--F627024CD1994930A448FD641C7BB43F-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--F627024CD1994930A448FD641C7BB43F-->  <DISPLAYLOGIC><![CDATA[@ACCT_DIMENSION_DISPLAY@ & @trxtype@!'']]></DISPLAYLOGIC>
 <!--F627024CD1994930A448FD641C7BB43F-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--F627024CD1994930A448FD641C7BB43F-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--F627024CD1994930A448FD641C7BB43F-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--F627024CD1994930A448FD641C7BB43F-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--F627024CD1994930A448FD641C7BB43F-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -2204,6 +2215,7 @@
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <DISPLAYLOGIC><![CDATA[@$Element_SR@='Y' & @trxtype@!'']]></DISPLAYLOGIC>
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--F83C096DBCD64007B2A5E517D2C81BFC-->  <READONLYLOGIC><![CDATA[@fin_payment_id@!null & @fin_payment_id@!undefined & @fin_payment_id@!'']]></READONLYLOGIC>
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
 <!--F83C096DBCD64007B2A5E517D2C81BFC-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
@@ -2238,6 +2250,34 @@
 <!--FB975E5F2AE3405197173B0DFB172ECC-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
 <!--FB975E5F2AE3405197173B0DFB172ECC--></OBUIAPP_PARAMETER>
 
+<!--FC511079CF1244BD80683D66D25A153D--><OBUIAPP_PARAMETER>
+<!--FC511079CF1244BD80683D66D25A153D-->  <OBUIAPP_PARAMETER_ID><![CDATA[FC511079CF1244BD80683D66D25A153D]]></OBUIAPP_PARAMETER_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_MODULE_ID><![CDATA[A918E3331C404B889D69AA9BFAFB23AC]]></AD_MODULE_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <NAME><![CDATA[Process Organization]]></NAME>
+<!--FC511079CF1244BD80683D66D25A153D-->  <DESCRIPTION><![CDATA[Parameter used to save value of current Process Definition ad_org_id parameter.]]></DESCRIPTION>
+<!--FC511079CF1244BD80683D66D25A153D-->  <HELP><![CDATA[Parameter used to save value of current Process Definition ad_org_id parameter.]]></HELP>
+<!--FC511079CF1244BD80683D66D25A153D-->  <SEQNO><![CDATA[220]]></SEQNO>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_REFERENCE_ID><![CDATA[95E2A8B50A254B2AAE6774B8C2F28120]]></AD_REFERENCE_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_REFERENCE_VALUE_ID><![CDATA[1221BEA5C19F4FA89D3565CA8877A82E]]></AD_REFERENCE_VALUE_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <COLUMNNAME><![CDATA[ad_org_id_process]]></COLUMNNAME>
+<!--FC511079CF1244BD80683D66D25A153D-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--FC511079CF1244BD80683D66D25A153D-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
+<!--FC511079CF1244BD80683D66D25A153D-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_ELEMENT_ID><![CDATA[5EE957873DEE4461A57BA8CAEAF50943]]></AD_ELEMENT_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <ISFIXED><![CDATA[N]]></ISFIXED>
+<!--FC511079CF1244BD80683D66D25A153D-->  <EVALUATEFIXEDVALUE><![CDATA[N]]></EVALUATEFIXEDVALUE>
+<!--FC511079CF1244BD80683D66D25A153D-->  <OBUIAPP_PROCESS_ID><![CDATA[E68790A7B65F4D45AB35E2BAE34C1F39]]></OBUIAPP_PROCESS_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
+<!--FC511079CF1244BD80683D66D25A153D-->  <DISPLAYLOGIC><![CDATA[false]]></DISPLAYLOGIC>
+<!--FC511079CF1244BD80683D66D25A153D-->  <AD_FIELDGROUP_ID><![CDATA[BB8B7EB290B94CA1A0D4F8F9983AE76D]]></AD_FIELDGROUP_ID>
+<!--FC511079CF1244BD80683D66D25A153D-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
+<!--FC511079CF1244BD80683D66D25A153D-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
+<!--FC511079CF1244BD80683D66D25A153D-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
+<!--FC511079CF1244BD80683D66D25A153D--></OBUIAPP_PARAMETER>
+
 <!--FDF5AB17A1154D6AB440E1F5A02B45F5--><OBUIAPP_PARAMETER>
 <!--FDF5AB17A1154D6AB440E1F5A02B45F5-->  <OBUIAPP_PARAMETER_ID><![CDATA[FDF5AB17A1154D6AB440E1F5A02B45F5]]></OBUIAPP_PARAMETER_ID>
 <!--FDF5AB17A1154D6AB440E1F5A02B45F5-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/OBUISEL_SELECTOR.xml	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/OBUISEL_SELECTOR.xml	Wed May 04 17:29:34 2016 +0200
@@ -219,7 +219,7 @@
 <!--EE54530EA4884AD5A10365E480015325-->  <NAME><![CDATA[Payment Selector Transaction for Parameter Window]]></NAME>
 <!--EE54530EA4884AD5A10365E480015325-->  <AD_REFERENCE_ID><![CDATA[3F7FDB0EAC9A42B69E8238335FFA59EC]]></AD_REFERENCE_ID>
 <!--EE54530EA4884AD5A10365E480015325-->  <AD_TABLE_ID><![CDATA[D1A97202E832470285C9B1EB026D54E2]]></AD_TABLE_ID>
-<!--EE54530EA4884AD5A10365E480015325-->  <WHERECLAUSE><![CDATA[e.status in ('RPR', 'PPM') and e.amount <>0 and exists ( select 1 from FinancialMgmtFinAccPaymentMethod as  fapm join fapm.account as fa where fapm.paymentMethod = e.paymentMethod and fa.id = @Fin_Financial_Account_ID@ and (case when e.receipt = true then fapm.payinAllow else fapm.payoutAllow end) = true and fa.currency = e.account.currency) and not exists (select 1 from FIN_Finacc_Transaction as ft where e = ft.finPayment) and AD_ISORGINCLUDED(e.organization.id,@inpadOrgId@,e.client.id)<>-1]]></WHERECLAUSE>
+<!--EE54530EA4884AD5A10365E480015325-->  <WHERECLAUSE><![CDATA[e.status in ('RPR', 'PPM') and e.amount <>0 and exists ( select 1 from FinancialMgmtFinAccPaymentMethod as  fapm join fapm.account as fa where fapm.paymentMethod = e.paymentMethod and fa.id = @Fin_Financial_Account_ID@ and (case when e.receipt = true then fapm.payinAllow else fapm.payoutAllow end) = true and fa.currency = e.account.currency) and not exists (select 1 from FIN_Finacc_Transaction as ft where e = ft.finPayment) and AD_ISORGINCLUDED(e.organization.id,@ad_org_id_process@,e.client.id)<>-1]]></WHERECLAUSE>
 <!--EE54530EA4884AD5A10365E480015325-->  <OBCLKER_TEMPLATE_ID><![CDATA[9314DE8599AD44E7BFC4CC50699042AB]]></OBCLKER_TEMPLATE_ID>
 <!--EE54530EA4884AD5A10365E480015325-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--EE54530EA4884AD5A10365E480015325-->  <SUGGESTIONTEXTMATCHSTYLE><![CDATA[substring]]></SUGGESTIONTEXTMATCHSTYLE>
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddPaymentActionHandler.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddPaymentActionHandler.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -102,10 +102,10 @@
         openedFromMenu = "null".equals(parameters.get("windowId").toString()) ? true : false;
       }
       String strOrgId = null;
-      if (jsonRequest.has("inpadOrgId") && jsonRequest.get("inpadOrgId") != JSONObject.NULL) {
+      if (jsonparams.has("ad_org_id") && jsonparams.get("ad_org_id") != JSONObject.NULL) {
+        strOrgId = jsonparams.getString("ad_org_id");
+      } else if (jsonRequest.has("inpadOrgId") && jsonRequest.get("inpadOrgId") != JSONObject.NULL) {
         strOrgId = jsonRequest.getString("inpadOrgId");
-      } else if (jsonparams.has("ad_org_id") && jsonparams.get("ad_org_id") != JSONObject.NULL) {
-        strOrgId = jsonparams.getString("ad_org_id");
       }
       Organization org = OBDal.getInstance().get(Organization.class, strOrgId);
       boolean isReceipt = jsonparams.getBoolean("issotrx");
@@ -566,11 +566,6 @@
     if (!"Error".equalsIgnoreCase(message.getType())) {
       message.setMessage(strNewPaymentMessage + " " + message.getMessage());
       message.setType(message.getType().toLowerCase());
-    } else {
-      conn = new DalConnectionProvider(true);
-      OBDal.getInstance().getSession().clear();
-      payment = OBDal.getInstance().get(FIN_Payment.class, payment.getId());
-      addCredit(payment, jsonparams, refundAmount, strDifferenceAction);
     }
     if (!strDifferenceAction.equals("refund")) {
       return message;
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddTransactionActionHandler.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddTransactionActionHandler.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -173,7 +173,6 @@
         isReceipt = payment.isReceipt();
         description = StringUtils.isNotBlank(payment.getDescription()) ? payment.getDescription()
             .replace("\n", ". ") : "";
-        organization = payment.getOrganization();
         paymentCurrency = payment.getCurrency();
         convertRate = payment.getFinancialTransactionConvertRate();
         sourceAmount = payment.getAmount();
@@ -183,8 +182,9 @@
         depositAmt = new BigDecimal(strDepositAmount);
         paymentAmt = new BigDecimal(strWithdrawalamt);
         isReceipt = (depositAmt.compareTo(paymentAmt) >= 0);
-        description = (StringUtils.isBlank(strDescription) || strDescription.equals("null")) ? OBMessageUtils.messageBD("APRM_GLItem")
-            + ": " + glItem.getName() : strDescription;
+        description = (StringUtils.isBlank(strDescription) || strDescription.equals("null")) ? OBMessageUtils
+            .messageBD("APRM_GLItem") + ": " + glItem.getName()
+            : strDescription;
       } else { // Bank Fee or transaction without payment and gl item
         depositAmt = new BigDecimal(strDepositAmount);
         paymentAmt = new BigDecimal(strWithdrawalamt);
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddOrderOrInvoiceFilterExpression.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddOrderOrInvoiceFilterExpression.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -59,6 +59,7 @@
         }
       }
     } catch (Exception e) {
+      log.error("Error calculating filter expression", e);
       return "";
     }
     return "";
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/TransactionAddPaymentDefaultValues.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/TransactionAddPaymentDefaultValues.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -155,6 +155,10 @@
   public String getOrganization(Map<String, String> requestMap) throws JSONException {
     // Organization of the current Payment
     JSONObject context = new JSONObject(requestMap.get("context"));
+    if (context.has("ad_org_id") && context.get("ad_org_id") != JSONObject.NULL
+        && StringUtils.isNotEmpty(context.getString("ad_org_id"))) {
+      return context.getString("ad_org_id");
+    }
     if (context.has("inpadOrgId") && context.get("inpadOrgId") != JSONObject.NULL
         && StringUtils.isNotEmpty(context.getString("inpadOrgId"))) {
       return context.getString("inpadOrgId");
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Wed May 04 17:29:34 2016 +0200
@@ -1053,7 +1053,8 @@
                   // Create merged Payment Schedule Detail with the pending to be paid amount
                   if (outStandingAmt.compareTo(BigDecimal.ZERO) != 0) {
                     final FIN_PaymentScheduleDetail mergedScheduleDetail = dao
-                        .getNewPaymentScheduleDetail(payment.getOrganization(), outStandingAmt);
+                        .getNewPaymentScheduleDetail(paymentScheduleDetail.getInvoicePaymentSchedule()
+                           .getInvoice().getOrganization(), outStandingAmt);
                     mergedScheduleDetail.setInvoicePaymentSchedule(paymentScheduleDetail
                         .getInvoicePaymentSchedule());
                     mergedScheduleDetail.setOrderPaymentSchedule(paymentScheduleDetail
@@ -1081,7 +1082,8 @@
                   // Create merged Payment Schedule Detail with the pending to be paid amount
                   if (outStandingAmt.compareTo(BigDecimal.ZERO) != 0) {
                     final FIN_PaymentScheduleDetail mergedScheduleDetail = dao
-                        .getNewPaymentScheduleDetail(payment.getOrganization(), outStandingAmt);
+                        .getNewPaymentScheduleDetail(paymentScheduleDetail.getOrderPaymentSchedule()
+                        	.getOrder().getOrganization(), outStandingAmt);
                     mergedScheduleDetail.setOrderPaymentSchedule(paymentScheduleDetail
                         .getOrderPaymentSchedule());
                     OBDal.getInstance().save(mergedScheduleDetail);
--- a/modules/org.openbravo.advpaymentmngt/web/org.openbravo.advpaymentmngt/js/ob-aprm-addTransaction.js	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/web/org.openbravo.advpaymentmngt/js/ob-aprm-addTransaction.js	Wed May 04 17:29:34 2016 +0200
@@ -27,6 +27,7 @@
     value: bankStatementLineId
   }));
   view.theForm.hideItem('bankStatementLineId');
+  view.theForm.getItem('ad_org_id_process').setValue(view.theForm.getItem('ad_org_id').getValue());
 };
 
 
@@ -123,4 +124,8 @@
 
 OB.APRM.AddTransaction.trxDateOnChangeFunction = function (item, view, form, grid) {
   form.getItem('dateacct').setDateParameterValue(new Date(item.getValue()));
+};
+
+OB.APRM.AddTransaction.organizationOnChangeFunction = function (item, view, form, grid) {
+  form.getItem('ad_org_id_process').setValue(form.getItem('ad_org_id').getValue());
 };
\ No newline at end of file
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/ADAlertDatasourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/ADAlertDatasourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -90,6 +90,12 @@
     }
   }
 
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    // Alert datasource is accessible by all roles. Fetch method implements security access based on
+    // Alerts. Alerts are filtered based on each user/role.
+  }
+
   private List<String> getAlertIds() {
     // Get alert rules visible for context's the role/user.
     try {
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java	Wed May 04 17:29:34 2016 +0200
@@ -53,12 +53,13 @@
 @ApplicationScoped
 public class CachedPreference {
   public static final String ALLOW_UNPAGED_DS_MANUAL_REQUEST = "OBJSON_AllowUnpagedDatasourceManualRequest";
+  public static final String ALLOW_UNSECURED_DS_REQUEST = "OBSERDS_AllowUnsecuredDatasourceRequest";
   public static final String ALLOW_WHERE_PARAMETER = "OBSERDS_AllowWhereParameter";
   public static final String RESTRICT_ERP_ACCESS_IN_STORE_SERVER = "RestrictErpAccessInStoreServer";
 
   private static final Logger log = LoggerFactory.getLogger(CachedPreference.class);
   private List<String> propertyList = new ArrayList<String>(Arrays.asList(
-      ALLOW_UNPAGED_DS_MANUAL_REQUEST, ALLOW_WHERE_PARAMETER, RESTRICT_ERP_ACCESS_IN_STORE_SERVER));
+      ALLOW_UNPAGED_DS_MANUAL_REQUEST, ALLOW_UNSECURED_DS_REQUEST, ALLOW_WHERE_PARAMETER, RESTRICT_ERP_ACCESS_IN_STORE_SERVER));
   private Map<String, String> cachedPreference = new HashMap<String, String>();
 
   /**
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/process/DefaultsProcessActionHandler.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/process/DefaultsProcessActionHandler.java	Wed May 04 17:29:34 2016 +0200
@@ -103,7 +103,8 @@
                 if (field.getObuiappDefaultExpression() != null) {
                   String rawDefaultExpression = field.getObuiappDefaultExpression();
                   Object defaultExpression;
-                  parameters.put("filterExpressionColumnName", field.getColumn().getDBColumnName());
+                  fixedParameters.put("filterExpressionColumnName", field.getColumn()
+                      .getDBColumnName());
                   defaultExpression = ParameterUtils.getJSExpressionResult(fixedParameters,
                       (HttpSession) parameters.get(KernelConstants.HTTP_SESSION),
                       rawDefaultExpression);
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js	Wed May 04 17:29:34 2016 +0200
@@ -954,6 +954,8 @@
     if (request.params.MODE === 'EDIT') {
       this.view.statusBar.mode = 'VIEW';
       this.view.statusBar.setContentLabel(null, null, this.getStatusBarFields());
+    } else if (modeIsNew) {
+      this.view.statusBar.setNewState(true);
     }
 
     if (this.callSaveAfterFICReturn) {
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-base-parameter-window-view.js	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-base-parameter-window-view.js	Wed May 04 17:29:34 2016 +0200
@@ -154,7 +154,7 @@
           // the default
           field.onChangeFunction.sort = 50;
 
-          OB.OnChangeRegistry.register(this.viewId, field.name, field.onChangeFunction, 'default');
+          OB.OnChangeRegistry.register(this.viewId || this.processId, field.name, field.onChangeFunction, 'default');
         }
 
         if (field.type === 'OBSectionItem' && !field.sectionExpanded) {
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-parameter-window-form.js	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-parameter-window-form.js	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -55,10 +55,14 @@
   // this function is invoked on the blur action of the formitems
   // this is the proper place to execute the client-side callouts
   handleItemChange: function (item) {
-    var affectedParams, i, field, me = this;
+    var affectedParams, i, field, me = this,
+        registryId;
+
+    registryId = this.paramWindow.viewId || this.paramWindow.processId;
+
     // Execute onChangeFunctions if they exist
-    if (this && OB.OnChangeRegistry.hasOnChange(this.paramWindow.viewId, item)) {
-      OB.OnChangeRegistry.call(this.paramWindow.viewId, item, this.paramWindow, this, this.paramWindow.viewGrid);
+    if (OB.OnChangeRegistry.hasOnChange(registryId, item)) {
+      OB.OnChangeRegistry.call(registryId, item, this.paramWindow, this, this.paramWindow.viewGrid);
     }
     // Check validation rules (subordinated fields), when value of a
     // parent field is changed, all its subordinated are reset
--- a/modules/org.openbravo.client.kernel/jslint/jscheck	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jscheck	Wed May 04 17:29:34 2016 +0200
@@ -6,7 +6,6 @@
 -and ! -path '*unittest*' \
 -and ! -path '*postest*' \
 -and ! -path '*xmla4js*' \
--and ! -path '*source*' \
 -and ! -path '*VAADIN*' \
 -and ! -path '*saiku*' \
 -and ! -path '*libs*' \
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/SetContextInfoActionHandler.java	Wed May 04 13:23:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-package org.openbravo.client.kernel;
-
-import java.util.Map;
-
-import javax.enterprise.context.ApplicationScoped;
-
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.hibernate.criterion.Restrictions;
-import org.openbravo.dal.core.OBContext;
-import org.openbravo.dal.service.OBCriteria;
-import org.openbravo.dal.service.OBDal;
-import org.openbravo.model.ad.ui.AuxiliaryInput;
-import org.openbravo.model.ad.ui.Tab;
-
-@ApplicationScoped
-public class SetContextInfoActionHandler extends BaseActionHandler {
-
-  @Override
-  protected JSONObject execute(Map<String, Object> parameters, String content) {
-
-    RequestContext rc = RequestContext.get();
-
-    // TODO Auto-generated method stub
-    try {
-      OBContext.setAdminMode();
-
-      JSONObject p = new JSONObject(content);
-
-      String tabId = p.getString("_tabId");
-      Tab tab = OBDal.getInstance().get(Tab.class, tabId);
-      String windowId = tab.getWindow().getId();
-
-      System.out.println("window: " + windowId);
-
-      JSONArray names = p.names();
-      for (int i = 0; i < names.length(); i++) {
-        String name = names.getString(i);
-        String value = p.getString(name);
-
-        rc.setSessionAttribute((windowId + "|" + name).toUpperCase(), value);
-        System.out.println((windowId + "|" + name).toUpperCase() + ":" + value);
-        System.out.println(name + ": " + value);
-      }
-
-      // Auxiliary inputs
-
-      OBCriteria<AuxiliaryInput> qInputs = OBDal.getInstance().createCriteria(AuxiliaryInput.class);
-      qInputs.add(Restrictions.eq(AuxiliaryInput.PROPERTY_TAB, tab));
-      for (AuxiliaryInput input : qInputs.list()) {
-
-      }
-
-    } catch (JSONException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    } finally {
-      OBContext.restorePreviousMode();
-    }
-
-    System.out.println("set context info");
-    return new JSONObject();
-  }
-
-}
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Wed May 04 17:29:34 2016 +0200
@@ -33,6 +33,7 @@
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.data.Sqlc;
 import org.openbravo.erpCommon.businessUtility.Preferences;
+import org.openbravo.erpCommon.utility.PropertyNotFoundException;
 import org.openbravo.model.ad.ui.Field;
 import org.openbravo.model.ad.utility.Tree;
 import org.openbravo.model.ad.utility.TreeNode;
@@ -128,6 +129,7 @@
               .getCurrentOrganization(), OBContext.getOBContext().getUser(), OBContext
               .getOBContext().getRole(), null);
       levels = Integer.parseInt(levelsPreference);
+    } catch (PropertyNotFoundException ignore) {
     } catch (Exception e) {
       if (e instanceof NumberFormatException) {
         log4j.error("ShowProductCharacteristicsParents preference is not a number", e);
--- a/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Wed May 04 17:29:34 2016 +0200
@@ -87,31 +87,13 @@
   private static final Logger log = Logger.getLogger(QueryListDataSource.class);
   private static final String OPERATOR = "$OPERATOR";
 
-  /**
-   * Returns the count of objects based on the passed parameters.
-   * 
-   * @param parameters
-   *          the parameters passed in from the request
-   * @return the total number of objects
-   */
   @Override
-  protected int getCount(Map<String, String> parameters) {
-    return getData(parameters, 0, -1).size();
-  }
-
-  @Override
-  protected List<Map<String, Object>> getData(Map<String, String> parameters, int startRow,
-      int endRow) {
-    // creation of formats is done here because they are not thread safe
-    final SimpleDateFormat xmlDateFormat = JsonUtils.createDateFormat();
-    final SimpleDateFormat xmlDateTimeFormat = JsonUtils.createDateTimeFormat();
-
-    OBContext.setAdminMode();
+  public void checkFetchDatasourceAccess(Map<String, String> parameters) {
+    // Check security: continue only if the widget instance is visible for current user/role
+    OBContext.setAdminMode(true);
     try {
       WidgetClass widgetClass = OBDal.getInstance().get(WidgetClass.class,
           parameters.get("widgetId"));
-
-      // Check security: continue only if the widget instance is visible for current user/role
       WidgetInstance wi = OBDal.getInstance().get(WidgetInstance.class,
           parameters.get("widgetInstanceId"));
 
@@ -141,6 +123,34 @@
         throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
             new String[] { widgetClass.getWidgetTitle() }));
       }
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Returns the count of objects based on the passed parameters.
+   * 
+   * @param parameters
+   *          the parameters passed in from the request
+   * @return the total number of objects
+   */
+  @Override
+  protected int getCount(Map<String, String> parameters) {
+    return getData(parameters, 0, -1).size();
+  }
+
+  @Override
+  protected List<Map<String, Object>> getData(Map<String, String> parameters, int startRow,
+      int endRow) {
+    // creation of formats is done here because they are not thread safe
+    final SimpleDateFormat xmlDateFormat = JsonUtils.createDateFormat();
+    final SimpleDateFormat xmlDateTimeFormat = JsonUtils.createDateTimeFormat();
+
+    OBContext.setAdminMode();
+    try {
+      WidgetClass widgetClass = OBDal.getInstance().get(WidgetClass.class,
+          parameters.get("widgetId"));
 
       boolean isExport = "true".equals(parameters.get("exportToFile"));
       boolean showAll = "true".equals(parameters.get("showAll"));
--- a/modules/org.openbravo.financial.paymentreport/src/org/openbravo/financial/paymentreport/erpCommon/ad_reports/PaymentReportDao.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.financial.paymentreport/src/org/openbravo/financial/paymentreport/erpCommon/ad_reports/PaymentReportDao.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SL 
- * All portions are Copyright (C) 2009-2014 Openbravo SL 
+ * All portions are Copyright (C) 2009-2016 Openbravo SL 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -30,6 +30,7 @@
 import java.util.Set;
 import java.util.Vector;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.apache.log4j.Logger;
 import org.hibernate.LockOptions;
@@ -259,32 +260,46 @@
     ArrayList<FieldProvider> totalData = new ArrayList<FieldProvider>();
     int numberOfElements = 0;
     int lastElement = 0;
-    boolean existsConvRate = false;
     ScrollableResults scroller = null;
 
     OBContext.setAdminMode(true);
     try {
-
       hsqlScript.append(" from FIN_Payment_ScheduleDetail as fpsd ");
-      hsqlScript.append(" left outer join fpsd.paymentDetails.finPayment pay");
-      hsqlScript.append(" left outer join pay.businessPartner paybp");
-      hsqlScript.append(" left outer join paybp.businessPartnerCategory paybpc");
-      hsqlScript.append(" left outer join fpsd.invoicePaymentSchedule invps");
-      hsqlScript.append(" left outer join invps.invoice inv");
-      hsqlScript.append(" left outer join inv.businessPartner invbp");
-      hsqlScript.append(" left outer join invbp.businessPartnerCategory invbpc");
-      hsqlScript.append(" left outer join fpsd.paymentDetails.finPayment.currency paycur");
-      hsqlScript.append(" left outer join fpsd.invoicePaymentSchedule.invoice.currency invcur");
-      hsqlScript.append(" left outer join pay.project paypro");
-      hsqlScript.append(" left outer join inv.project invpro");
-      hsqlScript.append(" where (fpsd.");
-      hsqlScript.append(FIN_PaymentScheduleDetail.PROPERTY_PAYMENTDETAILS);
-      hsqlScript.append(" is not null or invps is not null ");
-      hsqlScript.append(") ");
-
-      hsqlScript.append(" and fpsd.");
-      hsqlScript.append(FIN_PaymentScheduleDetail.PROPERTY_ORGANIZATION);
-      hsqlScript.append(".id in ");
+      hsqlScript.append(" left join fpsd.paymentDetails as fpd");
+      hsqlScript.append(" left join fpd.finPayment as pay");
+      hsqlScript.append(" left join fpsd.invoicePaymentSchedule as invps");
+      hsqlScript.append(" left join invps.invoice as inv");
+      if (StringUtils.equalsIgnoreCase(strGroupCrit, "INS_CURRENCY")
+          || StringUtils.contains(strOrdCrit, "INS_CURRENCY")) {
+        hsqlScript.append(" left join pay.currency as paycur");
+        hsqlScript.append(" left join inv.currency as invcur");
+      }
+      if (StringUtils.equalsIgnoreCase(strGroupCrit, "Project")
+          || StringUtils.contains(strOrdCrit, "Project")) {
+        hsqlScript.append(" left join pay.project as paypro");
+        hsqlScript.append(" left join inv.project as invpro");
+      }
+      if (StringUtils.equalsIgnoreCase(strGroupCrit, "APRM_FATS_BPARTNER")
+          || StringUtils.contains(strOrdCrit, "APRM_FATS_BPARTNER")
+          || StringUtils.equalsIgnoreCase(strGroupCrit, "FINPR_BPartner_Category")
+          || StringUtils.contains(strOrdCrit, "FINPR_BPartner_Category")
+          || (StringUtils.isNotEmpty(strcBPGroupIdIN) && (StringUtils.equals(strcNoBusinessPartner,
+              "include") || StringUtils.equals(strcNoBusinessPartner, "exclude")))) {
+        hsqlScript.append(" left join pay.businessPartner as paybp");
+        hsqlScript.append(" left join inv.businessPartner as invbp");
+        if (StringUtils.equalsIgnoreCase(strGroupCrit, "FINPR_BPartner_Category")
+            || StringUtils.contains(strOrdCrit, "FINPR_BPartner_Category")
+            || (StringUtils.isNotEmpty(strcBPGroupIdIN) && (StringUtils.equals(
+                strcNoBusinessPartner, "include") || StringUtils.equals(strcNoBusinessPartner,
+                "exclude")))) {
+          hsqlScript.append(" left join paybp.businessPartnerCategory as paybpc");
+          hsqlScript.append(" left join invbp.businessPartnerCategory as invbpc");
+        }
+      } else if (StringUtils.isNotEmpty(strFinancialAccountId)) {
+        hsqlScript.append(" left join inv.businessPartner as invbp");
+      }
+      hsqlScript.append(" where (fpd is not null or invps is not null)");
+      hsqlScript.append(" and fpsd.organization.id in ");
       hsqlScript.append(concatOrganizations(OBContext.getOBContext().getReadableOrganizations()));
 
       // organization + include sub-organization
@@ -589,7 +604,7 @@
 
       final StringBuilder firstLineQuery = new StringBuilder();
       firstLineQuery
-          .append("select fpsd, (select a.sequenceNumber from ADList a where a.reference.id = '575BCB88A4694C27BC013DE9C73E6FE7' and a.searchKey = coalesce(pay.status, 'RPAP')) as a");
+          .append("select fpsd.id, (select a.sequenceNumber from ADList a where a.reference.id = '575BCB88A4694C27BC013DE9C73E6FE7' and a.searchKey = coalesce(pay.status, 'RPAP')) as a");
       hsqlScript = firstLineQuery.append(hsqlScript);
 
       hsqlScript.append(" order by ");
@@ -730,11 +745,9 @@
       int i = 0;
       while (scroller.next()) {
         i++;
-        // get 1st column (idx=0)
-        Object value = scroller.get(0);
-
         // TODO: rename variable to not have same name as class
-        FIN_PaymentScheduleDetail FIN_PaymentScheduleDetail = (FIN_PaymentScheduleDetail) value;
+        FIN_PaymentScheduleDetail fpsd = OBDal.getInstance().get(FIN_PaymentScheduleDetail.class,
+            scroller.get(0));
 
         // make a empty FieldProvider instead of saving link to DAL-object
         FieldProvider data = FieldProviderFactory.getFieldProvider(null);
@@ -742,28 +755,27 @@
         if (i % 100 == 0) {
           OBDal.getInstance().getSession().clear();
         }
-        OBDal
-            .getInstance()
-            .getSession()
-            .buildLockRequest(LockOptions.NONE)
-            .lock(org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail.ENTITY_NAME,
-                FIN_PaymentScheduleDetail);
+        OBDal.getInstance().getSession().buildLockRequest(LockOptions.NONE)
+            .lock(FIN_PaymentScheduleDetail.ENTITY_NAME, fpsd);
 
         // search for fin_finacc_transaction for this payment
         FIN_FinaccTransaction trx = null;
-        FIN_PaymentDetail detail = FIN_PaymentScheduleDetail.getPaymentDetails();
-        if (detail != null) {
+        FIN_Payment payment = null;
+        Invoice invoice = null;
+        if (fpsd.getPaymentDetails() != null) {
+          payment = fpsd.getPaymentDetails().getFinPayment();
           OBCriteria<FIN_FinaccTransaction> trxQuery = OBDal.getInstance().createCriteria(
               FIN_FinaccTransaction.class);
-          trxQuery.add(Restrictions.eq(FIN_FinaccTransaction.PROPERTY_FINPAYMENT,
-              detail.getFinPayment()));
+          trxQuery.add(Restrictions.eq(FIN_FinaccTransaction.PROPERTY_FINPAYMENT, payment));
           // uniqueness guaranteed via unique constraint in db
           trx = (FIN_FinaccTransaction) trxQuery.uniqueResult();
+        } else {
+          invoice = fpsd.getInvoicePaymentSchedule().getInvoice();
         }
         // If the payment schedule detail has a payment detail, then, the information is taken from
         // the payment. If not, the information is taken from the invoice (the else).
-        if (FIN_PaymentScheduleDetail.getPaymentDetails() != null) {
-          BusinessPartner bp = getDocumentBusinessPartner(FIN_PaymentScheduleDetail);
+        if (fpsd.getPaymentDetails() != null) {
+          BusinessPartner bp = getDocumentBusinessPartner(fpsd);
           if (bp == null) {
             FieldProviderFactory.setField(data, "BP_GROUP", "");
             FieldProviderFactory.setField(data, "BPARTNER", "");
@@ -776,57 +788,38 @@
           }
 
           // transCurrency
-          transCurrency = FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment()
-              .getCurrency();
+          transCurrency = payment.getCurrency();
           FieldProviderFactory.setField(data, "TRANS_CURRENCY", transCurrency.getISOCode());
           // paymentMethod
-          FieldProviderFactory.setField(data, "PAYMENT_METHOD", FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getPaymentMethod().getIdentifier());
+          FieldProviderFactory.setField(data, "PAYMENT_METHOD", payment.getPaymentMethod()
+              .getIdentifier());
 
           // payment
-          FieldProviderFactory
-              .setField(
-                  data,
-                  "PAYMENT",
-                  ((FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment().getPaymentDate() != null) ? dateFormat
-                      .format(FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment()
-                          .getPaymentDate()) : "Null")
-                      + " - "
-                      + FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment()
-                          .getDocumentNo());
+          FieldProviderFactory.setField(data, "PAYMENT",
+              ((payment.getPaymentDate() != null) ? dateFormat.format(payment.getPaymentDate())
+                  : "Null") + " - " + payment.getDocumentNo());
           // payment description
-          FieldProviderFactory.setField(data, "PAYMENT_DESC", FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getDescription());
+          FieldProviderFactory.setField(data, "PAYMENT_DESC", payment.getDescription());
           // payment_id
-          FieldProviderFactory.setField(data, "PAYMENT_ID", FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getId().toString());
+          FieldProviderFactory.setField(data, "PAYMENT_ID", payment.getId().toString());
           // payment_date
-          FieldProviderFactory
-              .setField(
-                  data,
-                  "PAYMENT_DATE",
-                  (FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment().getPaymentDate() != null) ? dateFormat
-                      .format(FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment()
-                          .getPaymentDate()) : "Null");
+          FieldProviderFactory.setField(data, "PAYMENT_DATE",
+              (payment.getPaymentDate() != null) ? dateFormat.format(payment.getPaymentDate())
+                  : "Null");
           // payment_docNo
-          FieldProviderFactory.setField(data, "PAYMENT_DOCNO", FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getDocumentNo());
+          FieldProviderFactory.setField(data, "PAYMENT_DOCNO", payment.getDocumentNo());
           // payment yes / no
           FieldProviderFactory.setField(data, "PAYMENT_Y_N", "");
           // financialAccount
           FieldProviderFactory.setField(data, "FINANCIAL_ACCOUNT",
-              FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment()
-                  .getFINFinaccTransactionList().size() != 0 ? FIN_PaymentScheduleDetail
-                  .getPaymentDetails().getFinPayment().getFINFinaccTransactionList().get(0)
-                  .getAccount().getName() : FIN_PaymentScheduleDetail.getPaymentDetails()
-                  .getFinPayment().getAccount().getName());
+              !payment.getFINFinaccTransactionList().isEmpty() ? payment
+                  .getFINFinaccTransactionList().get(0).getAccount().getName() : payment
+                  .getAccount().getName());
           // status
-          FieldProviderFactory.setField(data, "STATUS", translateRefList(FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getStatus()));
-          FieldProviderFactory.setField(data, "STATUS_CODE", FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment().getStatus());
+          FieldProviderFactory.setField(data, "STATUS", translateRefList(payment.getStatus()));
+          FieldProviderFactory.setField(data, "STATUS_CODE", payment.getStatus());
           // is receipt
-          if (FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment().isReceipt()) {
+          if (payment.isReceipt()) {
             FieldProviderFactory.setField(data, "ISRECEIPT", "Y");
             isReceipt = true;
           } else {
@@ -843,19 +836,16 @@
         } else {
 
           // bp_group -- bp_category
-          FieldProviderFactory.setField(data, "BP_GROUP", FIN_PaymentScheduleDetail
-              .getInvoicePaymentSchedule().getInvoice().getBusinessPartner()
+          FieldProviderFactory.setField(data, "BP_GROUP", invoice.getBusinessPartner()
               .getBusinessPartnerCategory().getName());
           // bpartner
-          FieldProviderFactory.setField(data, "BPARTNER", FIN_PaymentScheduleDetail
-              .getInvoicePaymentSchedule().getInvoice().getBusinessPartner().getName());
+          FieldProviderFactory.setField(data, "BPARTNER", invoice.getBusinessPartner().getName());
           // transCurrency
-          transCurrency = FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getInvoice()
-              .getCurrency();
+          transCurrency = invoice.getCurrency();
           FieldProviderFactory.setField(data, "TRANS_CURRENCY", transCurrency.getISOCode());
           // paymentMethod
-          FieldProviderFactory.setField(data, "PAYMENT_METHOD", FIN_PaymentScheduleDetail
-              .getInvoicePaymentSchedule().getFinPaymentmethod().getIdentifier());
+          FieldProviderFactory.setField(data, "PAYMENT_METHOD", fpsd.getInvoicePaymentSchedule()
+              .getFinPaymentmethod().getIdentifier());
           // payment
           FieldProviderFactory.setField(data, "PAYMENT", "");
           // payment_id
@@ -872,8 +862,7 @@
           FieldProviderFactory.setField(data, "STATUS", translateRefList("RPAP"));
           FieldProviderFactory.setField(data, "STATUS_CODE", "RPAP");
           // is receipt
-          if (FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getInvoice()
-              .isSalesTransaction()) {
+          if (invoice.isSalesTransaction()) {
             FieldProviderFactory.setField(data, "ISRECEIPT", "Y");
             isReceipt = true;
           } else {
@@ -894,16 +883,13 @@
          * 
          * - Otherwise, it is filled empty.
          */
-        if (FIN_PaymentScheduleDetail.getInvoicePaymentSchedule() != null) {
-          fillLine(dateFormat, data, FIN_PaymentScheduleDetail,
-              FIN_PaymentScheduleDetail.getInvoicePaymentSchedule(), false);
-        } else if (FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment() != null) {
-          java.util.List<Invoice> invoices = getInvoicesUsingCredit(FIN_PaymentScheduleDetail
-              .getPaymentDetails().getFinPayment());
+        if (fpsd.getInvoicePaymentSchedule() != null) {
+          fillLine(dateFormat, data, fpsd, fpsd.getInvoicePaymentSchedule(), false);
+        } else if (payment != null) {
+          java.util.List<Invoice> invoices = getInvoicesUsingCredit(payment);
           if (invoices.size() == 1) {
-            java.util.List<FIN_PaymentSchedule> ps = getInvoicePaymentSchedules(FIN_PaymentScheduleDetail
-                .getPaymentDetails().getFinPayment());
-            fillLine(dateFormat, data, FIN_PaymentScheduleDetail, ps.get(0), true);
+            java.util.List<FIN_PaymentSchedule> ps = getInvoicePaymentSchedules(payment);
+            fillLine(dateFormat, data, fpsd, ps.get(0), true);
           } else {
             // project
             FieldProviderFactory.setField(data, "PROJECT", "");
@@ -962,7 +948,7 @@
         }
 
         // transactional and base amounts
-        transAmount = FIN_PaymentScheduleDetail.getAmount();
+        transAmount = fpsd.getAmount();
 
         Currency baseCurrency = OBDal.getInstance().get(Currency.class, strConvertCurrency);
 
@@ -1013,20 +999,14 @@
         // Balance
         String status = "RPAE";
         try {
-          status = FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment().getStatus();
+          status = payment.getStatus();
         } catch (NullPointerException e) {
         }
-        final boolean isCreditPayment = FIN_PaymentScheduleDetail.getInvoicePaymentSchedule() == null
-            && FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment() != null;
+        final boolean isCreditPayment = fpsd.getInvoicePaymentSchedule() == null && payment != null;
 
         BigDecimal balance = BigDecimal.ZERO;
         if (isCreditPayment && status != null && "PWNC RPR RPPC PPM RDNC".indexOf(status) >= 0) {
-          balance = FIN_PaymentScheduleDetail
-              .getPaymentDetails()
-              .getFinPayment()
-              .getGeneratedCredit()
-              .subtract(
-                  FIN_PaymentScheduleDetail.getPaymentDetails().getFinPayment().getUsedCredit());
+          balance = payment.getGeneratedCredit().subtract(payment.getUsedCredit());
           if (isReceipt) {
             balance = balance.negate();
           }
@@ -1041,28 +1021,24 @@
         }
         FieldProviderFactory.setField(data, "BALANCE", balance.toString());
 
-        finPaymDetail = FIN_PaymentScheduleDetail.getPaymentDetails();
+        finPaymDetail = fpsd.getPaymentDetails();
 
         // Payment Schedule Detail grouping criteria
-        if (finPaymDetail != null && FIN_PaymentScheduleDetail.getInvoicePaymentSchedule() != null) {
-          mustGroup = finPaymDetail.getFinPayment().getId().equalsIgnoreCase(previousPaymentId)
-              && FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getId()
-                  .equalsIgnoreCase(previousFPSDInvoiceId);
-          previousFPSDInvoiceId = FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getId();
-          previousPaymentId = finPaymDetail.getFinPayment().getId();
-        } else if (finPaymDetail != null
-            && FIN_PaymentScheduleDetail.getInvoicePaymentSchedule() == null) {
-          mustGroup = finPaymDetail.getFinPayment().getId().equalsIgnoreCase(previousPaymentId)
+        if (finPaymDetail != null && fpsd.getInvoicePaymentSchedule() != null) {
+          mustGroup = payment.getId().equalsIgnoreCase(previousPaymentId)
+              && fpsd.getInvoicePaymentSchedule().getId().equalsIgnoreCase(previousFPSDInvoiceId);
+          previousFPSDInvoiceId = fpsd.getInvoicePaymentSchedule().getId();
+          previousPaymentId = payment.getId();
+        } else if (finPaymDetail != null && fpsd.getInvoicePaymentSchedule() == null) {
+          mustGroup = payment.getId().equalsIgnoreCase(previousPaymentId)
               && previousFPSDInvoiceId == null;
-          previousPaymentId = finPaymDetail.getFinPayment().getId();
+          previousPaymentId = payment.getId();
           previousFPSDInvoiceId = null;
-        } else if (finPaymDetail == null
-            && FIN_PaymentScheduleDetail.getInvoicePaymentSchedule() != null) {
+        } else if (finPaymDetail == null && fpsd.getInvoicePaymentSchedule() != null) {
           mustGroup = previousPaymentId == null
-              && FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getId()
-                  .equalsIgnoreCase(previousFPSDInvoiceId);
+              && fpsd.getInvoicePaymentSchedule().getId().equalsIgnoreCase(previousFPSDInvoiceId);
           previousPaymentId = null;
-          previousFPSDInvoiceId = FIN_PaymentScheduleDetail.getInvoicePaymentSchedule().getId();
+          previousFPSDInvoiceId = fpsd.getInvoicePaymentSchedule().getId();
         } else {
           mustGroup = false;
         }
@@ -1156,10 +1132,10 @@
 
         // Insert the transactions without payment if necessary
         if (lastElement != numberOfElements) {
-          if (transactionsList.size() > 0) {
+          if (!transactionsList.isEmpty()) {
             try {
-              existsConvRate = insertIntoTotal(lastGroupedDatarow, transactionsList, totalData,
-                  strGroupCrit, strOrdCrit, strConvertCurrency, strConversionDate);
+              insertIntoTotal(lastGroupedDatarow, transactionsList, totalData, strGroupCrit,
+                  strOrdCrit, strConvertCurrency, strConversionDate);
             } catch (OBException e) {
               // If there is no conversion rate
               throw e;
@@ -1224,10 +1200,10 @@
 
       // Insert the transactions without payment if necessary
       if (lastElement != numberOfElements) {
-        if (transactionsList.size() > 0) {
+        if (!transactionsList.isEmpty()) {
           try {
-            existsConvRate = insertIntoTotal(lastGroupedDatarow, transactionsList, totalData,
-                strGroupCrit, strOrdCrit, strConvertCurrency, strConversionDate);
+            insertIntoTotal(lastGroupedDatarow, transactionsList, totalData, strGroupCrit,
+                strOrdCrit, strConvertCurrency, strConversionDate);
           } catch (OBException e) {
             // If there is no conversion rate
             throw e;
@@ -1238,7 +1214,7 @@
       }
 
       // Insert the remaining transactions wihtout payment if necessary
-      while (transactionsList.size() > 0) {
+      while (!transactionsList.isEmpty()) {
         // throws OBException if there is no conversion rate
         FieldProvider transactionData = createFieldProviderForTransaction(transactionsList.get(0),
             strGroupCrit, strConvertCurrency, strConversionDate);
@@ -1265,7 +1241,7 @@
       String strGroupCrit, String strOrdCrit, String strConvertCurrency, String strConversionDate)
       throws OBException {
 
-    while (transactionsList.size() > 0
+    while (!transactionsList.isEmpty()
         && transactionIsBefore(transactionsList.get(0), data, strGroupCrit, strOrdCrit)) {
       // throws OBException if there is no conversion rate
       FieldProvider transactionData = createFieldProviderForTransaction(transactionsList.get(0),
@@ -1989,33 +1965,21 @@
 
   public ConversionRate getConversionRate(Currency transCurrency, Currency baseCurrency,
       String conversionDate) {
-
-    java.util.List<ConversionRate> convRateList;
-    ConversionRate convRate;
-    Date conversionDateObj = FIN_Utility.getDate(conversionDate);
-
     OBContext.setAdminMode(true);
     try {
-
+      Date conversionDateObj = FIN_Utility.getDate(conversionDate);
       final OBCriteria<ConversionRate> obcConvRate = OBDal.getInstance().createCriteria(
           ConversionRate.class);
       obcConvRate.add(Restrictions.eq(ConversionRate.PROPERTY_CURRENCY, transCurrency));
       obcConvRate.add(Restrictions.eq(ConversionRate.PROPERTY_TOCURRENCY, baseCurrency));
       obcConvRate.add(Restrictions.le(ConversionRate.PROPERTY_VALIDFROMDATE, conversionDateObj));
       obcConvRate.add(Restrictions.ge(ConversionRate.PROPERTY_VALIDTODATE, conversionDateObj));
-
-      convRateList = obcConvRate.list();
-
-      if ((convRateList != null) && (convRateList.size() != 0))
-        convRate = convRateList.get(0);
-      else
-        convRate = null;
-
+      obcConvRate.setMaxResults(1);
+      ConversionRate convRate = (ConversionRate) obcConvRate.uniqueResult();
+      return convRate;
     } finally {
       OBContext.restorePreviousMode();
     }
-
-    return convRate;
   }
 
   public String[] getReferenceListValues(String refName, boolean inclEmtyValue) {
@@ -2060,16 +2024,18 @@
         obcTrl.add(Restrictions.eq("lr." + List.PROPERTY_SEARCHKEY, strCode));
         obcTrl.setFilterOnReadableClients(false);
         obcTrl.setFilterOnReadableOrganization(false);
-        strMessage = (obcTrl.list() != null && obcTrl.list().size() > 0) ? obcTrl.list().get(0)
-            .getName() : null;
+        obcTrl.setMaxResults(1);
+        ListTrl listTrl = (ListTrl) obcTrl.uniqueResult();
+        strMessage = listTrl != null ? listTrl.getName() : null;
       }
       if ("en_US".equals(language.getLanguage()) || strMessage == null) {
         OBCriteria<List> obc = OBDal.getInstance().createCriteria(List.class);
         obc.setFilterOnReadableClients(false);
         obc.setFilterOnReadableOrganization(false);
         obc.add(Restrictions.eq(List.PROPERTY_SEARCHKEY, strCode));
-        strMessage = (obc.list() != null && obc.list().size() > 0) ? obc.list().get(0).getName()
-            : null;
+        obc.setMaxResults(1);
+        List list = (List) obc.uniqueResult();
+        strMessage = list != null ? list.getName() : null;
       }
 
       if (strMessage == null || strMessage.equals(""))
@@ -2261,42 +2227,40 @@
     return organizations;
   }
 
+  @SuppressWarnings("unchecked")
   private void createBPList() {
-    bpList = new ArrayList<String>();
-    OBCriteria<BusinessPartner> critBPartner = OBDal.getInstance().createCriteria(
-        BusinessPartner.class);
-    critBPartner.addOrderBy(BusinessPartner.PROPERTY_NAME, true);
-    for (BusinessPartner bp : critBPartner.list()) {
-      bpList.add(bp.getName());
-    }
+    final StringBuilder hql = new StringBuilder();
+    hql.append(" select bp." + BusinessPartner.PROPERTY_NAME);
+    hql.append(" from " + BusinessPartner.ENTITY_NAME + " as bp");
+    hql.append(" order by bp." + BusinessPartner.PROPERTY_NAME);
+    bpList = OBDal.getInstance().getSession().createQuery(hql.toString()).list();
   }
 
+  @SuppressWarnings("unchecked")
   private void createBPCategoryList() {
-    bpCategoryList = new ArrayList<String>();
-    OBCriteria<Category> critBPCategory = OBDal.getInstance().createCriteria(Category.class);
-    critBPCategory.addOrderBy(Category.PROPERTY_NAME, true);
-    for (Category bpc : critBPCategory.list()) {
-      bpCategoryList.add(bpc.getName());
-    }
+    final StringBuilder hql = new StringBuilder();
+    hql.append(" select c." + Category.PROPERTY_NAME);
+    hql.append(" from " + Category.ENTITY_NAME + " as c");
+    hql.append(" order by c." + Category.PROPERTY_NAME);
+    bpCategoryList = OBDal.getInstance().getSession().createQuery(hql.toString()).list();
   }
 
+  @SuppressWarnings("unchecked")
   private void createProjectList() {
-    projectList = new ArrayList<String>();
-    OBCriteria<Project> critProject = OBDal.getInstance().createCriteria(Project.class);
-    critProject.addOrderBy(Project.PROPERTY_NAME, true);
-    for (Project project : critProject.list()) {
-      projectList.add(project.getName());
-    }
+    final StringBuilder hql = new StringBuilder();
+    hql.append(" select p." + Project.PROPERTY_NAME);
+    hql.append(" from " + Project.ENTITY_NAME + " as p");
+    hql.append(" order by p." + Project.PROPERTY_NAME);
+    projectList = OBDal.getInstance().getSession().createQuery(hql.toString()).list();
   }
 
+  @SuppressWarnings("unchecked")
   private void createAcctList() {
-    acctList = new ArrayList<String>();
-    OBCriteria<FIN_FinancialAccount> critAcct = OBDal.getInstance().createCriteria(
-        FIN_FinancialAccount.class);
-    critAcct.addOrderBy(FIN_FinancialAccount.PROPERTY_NAME, true);
-    for (FIN_FinancialAccount acct : critAcct.list()) {
-      acctList.add(acct.getName());
-    }
+    final StringBuilder hql = new StringBuilder();
+    hql.append(" select fa." + FIN_FinancialAccount.PROPERTY_NAME);
+    hql.append(" from " + FIN_FinancialAccount.ENTITY_NAME + " as fa");
+    hql.append(" order by fa." + FIN_FinancialAccount.PROPERTY_NAME);
+    acctList = OBDal.getInstance().getSession().createQuery(hql.toString()).list();
   }
 
 }
--- a/modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_REF_LIST.xml	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_REF_LIST.xml	Wed May 04 17:29:34 2016 +0200
@@ -1,5 +1,17 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <data>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11--><AD_REF_LIST>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <AD_REF_LIST_ID><![CDATA[14E993E1BBD24FF9ACA7A300BF4BDB11]]></AD_REF_LIST_ID>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <VALUE><![CDATA[OBSERDS_AllowUnsecuredDatasourceRequest]]></VALUE>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <NAME><![CDATA[Allow Unsecured Datasource Request]]></NAME>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <DESCRIPTION><![CDATA[This property allows to use unsecured DataSource request.]]></DESCRIPTION>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11-->  <AD_MODULE_ID><![CDATA[A44B9BA75C354D8FB2E3F7D6EB6BFDC4]]></AD_MODULE_ID>
+<!--14E993E1BBD24FF9ACA7A300BF4BDB11--></AD_REF_LIST>
+
 <!--23658853CF2D417B8FB94FE849DB3337--><AD_REF_LIST>
 <!--23658853CF2D417B8FB94FE849DB3337-->  <AD_REF_LIST_ID><![CDATA[23658853CF2D417B8FB94FE849DB3337]]></AD_REF_LIST_ID>
 <!--23658853CF2D417B8FB94FE849DB3337-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -26,8 +26,10 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
+import org.openbravo.client.application.CachedPreference;
 import org.openbravo.client.application.window.ApplicationDictionaryCachedStructures;
 import org.openbravo.client.kernel.Template;
 import org.openbravo.dal.core.DalUtil;
@@ -36,6 +38,8 @@
 import org.openbravo.model.ad.ui.Tab;
 import org.openbravo.model.common.order.Order;
 import org.openbravo.service.json.JsonConstants;
+import org.openbravo.userinterface.selector.Selector;
+import org.openbravo.userinterface.selector.SelectorConstants;
 
 /**
  * A base data source service which can be extended. It combines the common parts for data sources
@@ -58,6 +62,9 @@
   private List<DataSourceProperty> dataSourceProperties = new ArrayList<DataSourceProperty>();
 
   @Inject
+  private CachedPreference cachedPreference;
+
+  @Inject
   private ApplicationDictionaryCachedStructures cachedStructures;
 
   /*
@@ -127,16 +134,50 @@
     setWhereClause(dataSource.getHQLWhereClause());
   }
 
-  public Entity getEntity() {
-    return entity;
+  @Override
+  public void checkEditDatasourceAccess(Map<String, String> parameters) {
+    Entity entityToCheck = getEntity();
+    final OBContext obContext = OBContext.getOBContext();
+    if (entity != null) {
+      try {
+        obContext.getEntityAccessChecker().checkWritableAccess(entityToCheck);
+      } catch (OBSecurityException e) {
+        handleExceptionUnsecuredDSAccess(e);
+      }
+    }
   }
 
-  public void setEntity(Entity entity) {
-    this.entity = entity;
-  }
-
-  public void setName(String name) {
-    this.name = name;
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameters) {
+    Entity entityToCheck = getEntity();
+    final OBContext obContext = OBContext.getOBContext();
+    String selectorId = parameters.get(SelectorConstants.DS_REQUEST_SELECTOR_ID_PARAMETER);
+    if (StringUtils.isNotBlank(selectorId)) {
+      // selectors
+      if (entityToCheck == null) {
+        OBContext.setAdminMode(true);
+        try {
+          Selector sel = OBDal.getInstance().get(Selector.class, selectorId);
+          entityToCheck = ModelProvider.getInstance().getEntityByTableId(
+              (String) DalUtil.getId(sel.getTable()));
+        } finally {
+          OBContext.restorePreviousMode();
+        }
+      }
+      if (entityToCheck != null) {
+        try {
+          obContext.getEntityAccessChecker().checkDerivedAccess(entityToCheck);
+        } catch (OBSecurityException e) {
+          handleExceptionUnsecuredDSAccess(e);
+        }
+      }
+    } else if (entityToCheck != null) {
+      try {
+        obContext.getEntityAccessChecker().checkReadableAccess(entityToCheck);
+      } catch (OBSecurityException e) {
+        handleExceptionUnsecuredDSAccess(e);
+      }
+    }
   }
 
   /**
@@ -172,6 +213,27 @@
     }
   }
 
+  protected void handleExceptionUnsecuredDSAccess(OBSecurityException securityException) {
+    if (!"Y".equals(cachedPreference
+        .getPreferenceValue(CachedPreference.ALLOW_UNSECURED_DS_REQUEST))) {
+      throw new OBSecurityException(securityException);
+    } else {
+      log.warn(securityException.getMessage() + " but in fact it is being allowed access.");
+    }
+  }
+
+  public Entity getEntity() {
+    return entity;
+  }
+
+  public void setEntity(Entity entity) {
+    this.entity = entity;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
   private boolean isRootTab(Tab tab) {
     return tab.getTabLevel() == 0;
   }
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/ComboTableDatasourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/ComboTableDatasourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -75,12 +75,10 @@
 
     OBContext.setAdminMode(true);
     try {
-      // check access to current entity
       field = OBDal.getInstance().get(Field.class, fieldId);
       column = field.getColumn();
       targetEntity = ModelProvider.getInstance().getEntityByTableId(
           (String) DalUtil.getId(column.getTable()));
-      OBContext.getOBContext().getEntityAccessChecker().checkReadable(targetEntity);
 
       if (!StringUtils.isEmpty(parameters.get("criteria"))) {
         String criteria = parameters.get("criteria");
@@ -232,4 +230,29 @@
   public String update(Map<String, String> parameters, String content) {
     throw new OBException("Method not implemented");
   }
+
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameters) {
+    Field field = null;
+    Column column = null;
+    String fieldId = parameters.get("fieldId");
+    Entity targetEntity = null;
+
+    OBContext.setAdminMode(true);
+    try {
+      // check access to current entity
+      field = OBDal.getInstance().get(Field.class, fieldId);
+      column = field.getColumn();
+      targetEntity = ModelProvider.getInstance().getEntityByTableId(
+          (String) DalUtil.getId(column.getTable()));
+      OBContext.getOBContext().getEntityAccessChecker().checkReadableAccess(targetEntity);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  @Override
+  public void checkEditDatasourceAccess(Map<String, String> parameters) {
+    throw new OBException("Method not implemented");
+  }
 }
\ No newline at end of file
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceConstants.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceConstants.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -33,6 +33,9 @@
 
   public static final String OPERATION_TYPE_PARAM = "_operationType";
   public static final String FETCH_OPERATION = "fetch";
+  public static final String REMOVE_OPERATION = "remove";
+
+  public static final String ADD_CONTENT_OPERATION = "addContent";
 
   public static final String NEW_PARAM = "_new";
   public static final String URL_NAME_PARAM = "mapping_name";
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -21,6 +21,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.client.kernel.Template;
 
@@ -115,14 +116,33 @@
 
   public void setEntity(Entity entity);
 
+  /**
+   * This method allows to implement a security access to a DataSource when it is used fetch()
+   * method. It can be overridden in specific DataSources to apply a particular security mechanism.
+   *
+   * @throws OBSecurityException
+   *           is thrown if current role does not have access.
+   */
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) throws OBSecurityException;
+
+  /**
+   * This method allows to implement a security access to a DataSource when it is used add(), update()
+   * or remove() methods. It can be overridden in specific DataSources to apply a particular
+   * security mechanism.
+   *
+   * @throws OBSecurityException
+   *           is thrown if current role does not have access.
+   */
+  public void checkEditDatasourceAccess(Map<String, String> parameter) throws OBSecurityException;
+
   public String getWhereClause();
 
   public void setWhereClause(String whereClause);
 
   /**
-   * The data source read from the database. Note care must be taken when using referenced objects
-   * in the returned DataSource instance. The DataSource is read often in a different thread so the
-   * Hibernate session is not available anymore.
+   * This method allows to implement a security access to a DataSource when it is used add(),
+   * update() or remove() methods. It can be overridden in specific DataSources to apply a
+   * particular security mechanism.
    * 
    * @return the data source read from the database. Note: can be null for data sources which are
    *         created in-memory on request.
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Wed May 04 17:29:34 2016 +0200
@@ -276,6 +276,8 @@
           log.error("Unsupported export format: " + exportAs);
         }
       } else {
+        // Check security: continue only if the entity is accessible for current user/role.
+        getDataSource(request).checkFetchDatasourceAccess(parameters);
         String result = getDataSource(request).fetch(parameters);
         writeResult(response, result);
       }
@@ -774,7 +776,10 @@
 
       // note if clause updates parameter map
       if (checkSetIDDataSourceName(request, response, parameters)) {
-        final String result = getDataSource(request).add(parameters, getRequestContent(request));
+        String content = getRequestContent(request);
+        parameters.put(DataSourceConstants.ADD_CONTENT_OPERATION, content);
+        getDataSource(request).checkEditDatasourceAccess(parameters);
+        final String result = getDataSource(request).add(parameters, content);
         writeResult(response, result);
       }
     } catch (Exception e) {
@@ -801,6 +806,7 @@
         throw new InvalidRequestException("No id parameter");
       }
 
+      getDataSource(request).checkEditDatasourceAccess(parameters);
       final String result = getDataSource(request).remove(parameters);
       writeResult(response, result);
     } catch (Exception e) {
@@ -836,6 +842,7 @@
 
       // note if clause updates parameter map
       if (checkSetIDDataSourceName(request, response, parameters)) {
+        getDataSource(request).checkEditDatasourceAccess(parameters);
         final String result = getDataSource(request).update(parameters, getRequestContent(request));
         writeResult(response, result);
       }
@@ -1027,6 +1034,19 @@
         final List<Process> obuiapProcesses = new ArrayList<Process>();
         for (Parameter parameter : obParameters.list()) {
           obuiapProcesses.add(parameter.getObuiappProcess());
+
+        }
+
+        // If access to process are granted for current user/role return directly true.
+        boolean isAccessGranted = true;
+        final OBContext obContext = OBContext.getOBContext();
+        for (Process process : obuiapProcesses) {
+          if (!obContext.getEntityAccessChecker().checkProcessAccess(process.getId())) {
+            isAccessGranted = false;
+          }
+        }
+        if (isAccessGranted) {
+          return true;
         }
 
         // Finally select all columns that linked with selected processes and get their fields.
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/HQLDataSourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/HQLDataSourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -33,6 +33,7 @@
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.Query;
 import org.hibernate.ScrollableResults;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
@@ -128,6 +129,20 @@
   }
 
   @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    Table table = getTableFromParameters(parameter);
+    try {
+      Entity entity = ModelProvider.getInstance().getEntityByTableId(table.getId());
+      if (entity != null) {
+        obContext.getEntityAccessChecker().checkReadableAccess(entity);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
+
+  @Override
   protected int getCount(Map<String, String> parameters) {
     Table table = getTableFromParameters(parameters);
     boolean justCount = true;
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/NoteDataSource.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/NoteDataSource.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2015 Openbravo SLU
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -21,6 +21,7 @@
 
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
@@ -29,6 +30,7 @@
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.structure.OrganizationEnabled;
 import org.openbravo.client.application.Note;
+import org.openbravo.dal.core.DalUtil;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.security.SecurityChecker;
 import org.openbravo.dal.service.OBDal;
@@ -50,8 +52,65 @@
   @Override
   public String fetch(Map<String, String> parameters) {
     String noteFetch = "";
+    noteFetch = super.fetch(parameters, false);
+    return noteFetch;
+  }
+
+  @Override
+  public String add(Map<String, String> parameters, String content) {
+    String noteAdd = "";
+    noteAdd = super.add(parameters, content, false);
+    return noteAdd;
+  }
+
+  @Override
+  public String remove(Map<String, String> parameters) {
+    String noteRemove = "";
+    noteRemove = super.remove(parameters, false);
+    return noteRemove;
+  }
+
+  @Override
+  public void checkEditDatasourceAccess(Map<String, String> parameter) {
+    String operationType = parameter.get(DataSourceConstants.OPERATION_TYPE_PARAM);
+    if (StringUtils.isNotBlank(operationType)
+        && DataSourceConstants.REMOVE_OPERATION.equals(operationType)) {
+      // Removing a Note: Remove operation type
+      OBContext.setAdminMode(false);
+      try {
+        String noteId = parameter.get("id");
+        Note note = OBDal.getInstance().get(Note.class, noteId);
+        Table table = note.getTable();
+        String tableId = (String) DalUtil.getId(table);
+        String recordId = note.getRecord();
+        readableAccesForUser(tableId, recordId);
+      } catch (Exception ex) {
+        log.error("Exception while trying to remove a note", ex);
+        throw new OBException(ex);
+      } finally {
+        OBContext.restorePreviousMode();
+      }
+    } else {
+      // Adding a Note: Add operation type
+      try {
+        String content = parameter.get(DataSourceConstants.ADD_CONTENT_OPERATION);
+        final JSONObject jsonObject = new JSONObject(content);
+        JSONObject noteData = jsonObject.getJSONObject("data");
+        String tableId = noteData.getString("table");
+        String recordId = noteData.getString("record");
+        readableAccesForUser(tableId, recordId);
+      } catch (JSONException ex) {
+        log.error("Exception while trying to add a new note", ex);
+        throw new OBException(ex);
+      }
+    }
+  }
+
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
     try {
-      JSONObject jsonCriteria = JsonUtils.buildCriteria(parameters);
+      // Fetching Notes: Fetch operation type
+      JSONObject jsonCriteria = JsonUtils.buildCriteria(parameter);
       JSONArray notesCriteria;
       String tableId;
       String recordId;
@@ -59,54 +118,10 @@
       tableId = notesCriteria.getJSONObject(0).getString("value");
       recordId = notesCriteria.getJSONObject(1).getString("value");
       readableAccesForUser(tableId, recordId);
-      noteFetch = super.fetch(parameters, false);
     } catch (JSONException ex) {
       log.error("Exception while trying to perform a fetch", ex);
       throw new OBException(ex);
     }
-    return noteFetch;
-  }
-
-  @Override
-  public String add(Map<String, String> parameters, String content) {
-    String noteAdd = "";
-    try {
-      JSONObject noteData;
-      String tableId;
-      String recordId;
-
-      final JSONObject jsonObject = new JSONObject(content);
-      noteData = jsonObject.getJSONObject("data");
-      tableId = noteData.getString("table");
-      recordId = noteData.getString("record");
-      readableAccesForUser(tableId, recordId);
-      noteAdd = super.add(parameters, content, false);
-    } catch (JSONException ex) {
-      log.error("Exception while trying to add a new note", ex);
-      throw new OBException(ex);
-    }
-    return noteAdd;
-  }
-
-  @Override
-  public String remove(Map<String, String> parameters) {
-    String noteRemove = "";
-    OBContext.setAdminMode(false);
-    try {
-      String noteId = parameters.get("id");
-      Note note = OBDal.getInstance().get(Note.class, noteId);
-      Table table = note.getTable();
-      String tableId = table.getId();
-      String recordId = note.getRecord();
-      readableAccesForUser(tableId, recordId);
-      noteRemove = super.remove(parameters, false);
-    } catch (Exception ex) {
-      log.error("Exception while trying to remove a note", ex);
-      throw new OBException(ex);
-    } finally {
-      OBContext.restorePreviousMode();
-    }
-    return noteRemove;
   }
 
   /**
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Wed May 04 17:29:34 2016 +0200
@@ -94,10 +94,6 @@
     try {
       // We can't get the bob from DAL, it has not been saved yet
       JSONObject bobProperties = new JSONObject(parameters.get("jsonBob"));
-      Entity theEntity = getEntity();
-      if (!hasAccess(theEntity, null, false)) {
-        throw new OBException(OBMessageUtils.messageBD("AccessTableNoView"));
-      }
       addNewNode(bobProperties);
     } catch (Exception e) {
       log.error("Error while adding the tree node", e);
@@ -122,7 +118,6 @@
     try {
       // We can't get the bob from DAL, it has not been saved yet
       JSONObject bobProperties = new JSONObject(parameters.get("jsonBob"));
-      Entity theEntity = getEntity();
       String bobId = bobProperties.getString("id");
       String entityName = bobProperties.getString("_entity");
       Entity entity = ModelProvider.getInstance().getEntity(entityName);
@@ -131,9 +126,6 @@
         // Handle the deletion policy "Do Not Allow If Has Children" if it applies to this entity
         throw new OBException(OBMessageUtils.messageBD("CannotDeleteNodeBecauseChildren"));
       }
-      if (!hasAccess(theEntity, null, false)) {
-        throw new OBException(OBMessageUtils.messageBD("AccessTableNoView"));
-      }
 
       this.deleteNode(bobProperties);
     } catch (Exception e) {
@@ -145,6 +137,14 @@
     return "";
   }
 
+  @Override
+  public void checkEditDatasourceAccess(Map<String, String> parameter) {
+    Entity theEntity = getEntity();
+    if (!hasAccess(theEntity, null, false)) {
+      throw new OBException(OBMessageUtils.messageBD("AccessTableNoView"));
+    }
+  }
+
   /**
    * Classes that extend TreeDatasourceService this method must implement this method to handle the
    * deletion of a node in a tree table
@@ -314,6 +314,20 @@
     return jsonResult.toString();
   }
 
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    String tableId = parameter.get("referencedTableId");
+    try {
+      Entity treeEntity = ModelProvider.getInstance().getEntityByTableId(tableId);
+      if (treeEntity != null) {
+        obContext.getEntityAccessChecker().checkReadableAccess(treeEntity);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
+
   protected abstract Map<String, Object> getDatasourceSpecificParams(Map<String, String> parameters);
 
   private boolean isSubtabCriteria(Entity entity, JSONObject jsonCriteria) {
--- a/modules/org.openbravo.service.json/src-test/org/openbravo/service/json/test/DataQueryServiceTest.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.json/src-test/org/openbravo/service/json/test/DataQueryServiceTest.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -39,12 +39,12 @@
 import org.openbravo.model.financialmgmt.payment.FIN_FinaccTransaction;
 import org.openbravo.service.json.DataEntityQueryService;
 import org.openbravo.service.json.JsonConstants;
-import org.openbravo.service.json.QueryBuilder;
-import org.openbravo.service.json.QueryBuilder.TextMatching;
+import org.openbravo.service.json.AdvancedQueryBuilder;
+import org.openbravo.service.json.AdvancedQueryBuilder.TextMatching;
 import org.openbravo.test.base.OBBaseTest;
 
 /**
- * Test the {@link DataEntityQueryService} and {@link QueryBuilder} classes.
+ * Test the {@link DataEntityQueryService} and {@link AdvancedQueryBuilder} classes.
  * 
  * @author mtaal
  */
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Wed May 04 17:29:34 2016 +0200
@@ -173,6 +173,10 @@
   // in the FROM clause
   private boolean creatingJoinsInWhereClauseIsPrevented = false;
 
+  public static enum TextMatching {
+    startsWith, exact, substring
+  }
+
   public Entity getEntity() {
     return entity;
   }
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/DataEntityQueryService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/DataEntityQueryService.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -51,8 +51,6 @@
  * 
  * This service class can not be used as a singleton.
  * 
- * It makes use of the {@link QueryBuilder} helper class to manage filter information.
- * 
  * @author mtaal
  */
 public class DataEntityQueryService {
@@ -280,8 +278,8 @@
   }
 
   /**
-   * Tells the {@link QueryBuilder} to use the {@link JsonConstants#MAIN_ALIAS} as the alias for
-   * prefixing all properties in the where clause and order by.
+   * Tells the query builder to use the {@link JsonConstants#MAIN_ALIAS} as the alias for prefixing
+   * all properties in the where clause and order by.
    */
   public void setUseAlias() {
     queryBuilder.setMainAlias(JsonConstants.MAIN_ALIAS);
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonDataService.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonDataService.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -51,7 +51,6 @@
    *          the parameters driving the query, one parameter is mandatory:
    *          {@link JsonConstants#ENTITYNAME}
    * @return a json result string
-   * @see QueryBuilder
    */
   public abstract String fetch(Map<String, String> parameters);
 
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/QueryBuilder.java	Wed May 04 13:23:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,737 +0,0 @@
-/*
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html 
- * Software distributed under the License  is  distributed  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License. 
- * The Original Code is Openbravo ERP. 
- * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
- * All Rights Reserved. 
- * Contributor(s):  ______________________________________.
- ************************************************************************
- */
-package org.openbravo.service.json;
-
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import org.openbravo.base.model.Entity;
-import org.openbravo.base.model.ModelProvider;
-import org.openbravo.base.model.Property;
-import org.openbravo.base.structure.IdentifierProvider;
-import org.openbravo.base.util.Check;
-import org.openbravo.client.kernel.RequestContext;
-import org.openbravo.dal.core.DalUtil;
-import org.openbravo.dal.core.OBContext;
-import org.openbravo.erpCommon.utility.Utility;
-import org.openbravo.service.db.DalConnectionProvider;
-
-/**
- * Encapsulates the logic to translate filter properties and values received from the client to a
- * where clauses in the query itself.
- * 
- * @author mtaal
- */
-public class QueryBuilder {
-
-  private static final String PARAM_DELIMITER = "@";
-  private static final String ALIAS_PREFIX = "alias_";
-  private static final char ESCAPE_CHAR = '|';
-
-  public static enum TextMatching {
-    startsWith, exact, substring
-  }
-
-  private static final Logger log = Logger.getLogger(QueryBuilder.class);
-
-  private Map<String, String> filterParameters = new HashMap<String, String>();
-  private List<Object> typedParameters = new ArrayList<Object>();
-  private Entity entity;
-  private boolean doOr = false;
-  private String mainAlias = null;
-  private int aliasIndex = 0;
-  private List<JoinDefinition> joinDefinitions = new ArrayList<JoinDefinition>();
-  private String orderBy;
-
-  private String orderByClause = null;
-  private String whereClause = null;
-  private String joinClause = null;
-
-  private TextMatching textMatching = TextMatching.exact;
-
-  public Entity getEntity() {
-    return entity;
-  }
-
-  public void setEntity(String entityName) {
-    this.entity = ModelProvider.getInstance().getEntity(entityName);
-  }
-
-  public void setEntity(Entity entity) {
-    this.entity = entity;
-  }
-
-  /**
-   * Translates the filter criteria ({@link #addFilterParameter(String, String)}) to a valid HQL
-   * where clause (without the 'where' keyword). After calling this method the method
-   * {@link #getNamedParameters()} can be called. Note that currently only filtering on string and
-   * boolean properties is supported. Also filtering on the identifier of a referenced business
-   * object is supported.
-   * 
-   * @return a valid where clause or an empty string if not set.
-   */
-  public String getWhereClause() {
-
-    if (whereClause != null) {
-      return whereClause;
-    }
-
-    // add some default filter parameters
-    filterParameters
-        .put(JsonConstants.QUERY_PARAM_USER, OBContext.getOBContext().getUser().getId());
-    if (!filterParameters.containsKey(JsonConstants.QUERY_PARAM_CLIENT)) {
-      filterParameters.put(JsonConstants.QUERY_PARAM_CLIENT, OBContext.getOBContext().getUser()
-          .getId());
-    }
-
-    final SimpleDateFormat simpleDateFormat = JsonUtils.createDateFormat();
-
-    Check.isNotNull(entity, "Entity must be set");
-
-    final StringBuilder sb = new StringBuilder();
-    boolean addAnd = false;
-    final StringBuilder orgPart = new StringBuilder();
-    final List<Property> propertyDone = new ArrayList<Property>();
-    String whereParameterValue = null;
-    for (String key : filterParameters.keySet()) {
-      String value = filterParameters.get(key);
-
-      if (key.equals(JsonConstants.WHERE_PARAMETER)) {
-        // there are cases where null is set as a string
-        // handle this
-        if (value.equals("null") || value.length() == 0) {
-          continue;
-        }
-        whereParameterValue = value;
-        continue;
-      }
-
-      // handle the case that we should filter on the accessible organizations
-      if (key.equals(JsonConstants.ORG_PARAMETER)) {
-        if (entity.isOrganizationEnabled() && value != null && value.length() > 0) {
-          final Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider()
-              .getNaturalTree(value);
-          if (orgs.size() > 0) {
-            if (getMainAlias() != null) {
-              orgPart.append(" " + getMainAlias() + ".organization in (");
-            } else {
-              orgPart.append(" organization in (");
-            }
-            boolean addComma = false;
-            for (String org : orgs) {
-              if (addComma) {
-                orgPart.append(",");
-              }
-              orgPart.append("'" + org + "'");
-              addComma = true;
-            }
-            orgPart.append(") ");
-          }
-        }
-        continue;
-      }
-
-      // determine the property
-      final List<Property> properties = JsonUtils.getPropertiesOnPath(getEntity(), key);
-      if (properties.isEmpty()) {
-        continue;
-      }
-      final Property property = properties.get(properties.size() - 1);
-      // invalid propname, ignore this one
-      // TODO: possibly warn about it
-      if (property == null || propertyDone.contains(property)) {
-        continue;
-      }
-      propertyDone.add(property);
-
-      // we know the property and the string representation of the value...
-      // do the conversion
-
-      if (addAnd) {
-        if (doOr) {
-          sb.append(" or ");
-        } else {
-          sb.append(" and ");
-        }
-      }
-
-      String leftWherePart = null;
-      if (isDoOr()) {
-        leftWherePart = resolveJoins(properties, key);
-      } else if (getMainAlias() != null) {
-        leftWherePart = getMainAlias() + "." + key.trim();
-      } else {
-        leftWherePart = key;
-      }
-
-      // get rid of the identifier and replace it with the real property name
-      // or with the concatenation if there are multiple parts
-      // NOTE: the if and else check against the key variable and not the leftwherepart
-      // because the key contains the original string (with the _identifier part).
-      // Within the if the leftWherePart is used because it contains the join aliases
-      if (key.equals(JsonConstants.IDENTIFIER) || key.endsWith("." + JsonConstants.IDENTIFIER)) {
-        // the identifierProperties are read from the owning entity of the
-        // property, that should work fine, as this last property is always part of the
-        // identifier
-        final List<Property> identifierProperties = property.getEntity().getIdentifierProperties();
-        Check.isTrue(identifierProperties.contains(property), "Property " + property
-            + " not part of identifier of " + property.getEntity());
-        final String prefix;
-        final int index = leftWherePart.lastIndexOf(".");
-        if (key.equals(JsonConstants.IDENTIFIER)) {
-          prefix = getMainAlias() + ".";
-        } else if (index == -1) {
-          prefix = "";
-        } else {
-          // the + 1 makes sure that the dot is included
-          prefix = leftWherePart.substring(0, index + 1);
-        }
-        leftWherePart = createIdentifierLeftClause(identifierProperties, prefix);
-
-        // if the value consists of multiple parts then filtering won't work
-        // only search on the first part then, is pragmatic but very workable
-        if (value != null && value.contains(IdentifierProvider.SEPARATOR)) {
-          final int separatorIndex = value.indexOf(IdentifierProvider.SEPARATOR);
-          value = value.substring(0, separatorIndex);
-        }
-      }
-
-      // NOTE: If you change this part, make sure that you sync the changes with the
-      // SelectorDataSourceFilter. Check issue https://issues.openbravo.com/view.php?id=14239
-
-      // NOTE the typedParameters.add call must be done after the call to
-      // getTypedParameterAlias, this to get the correct alias codes
-      if (key.equals(JsonConstants.IDENTIFIER)) {
-        if (textMatching == TextMatching.exact) {
-          sb.append(leftWherePart + " = " + getTypedParameterAlias());
-          typedParameters.add(value);
-        } else if (textMatching == TextMatching.startsWith) {
-          sb.append("upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '"
-              + ESCAPE_CHAR + "' ");
-          typedParameters.add(escapeLike(value.toUpperCase()) + "%");
-        } else {
-          sb.append("upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '"
-              + ESCAPE_CHAR + "' ");
-          typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%");
-        }
-      } else if (!property.isPrimitive()) {
-        // an in parameter use it...
-        if (value.contains(JsonConstants.IN_PARAMETER_SEPARATOR)) {
-          final List<String> values = new ArrayList<String>();
-          final String[] separatedValues = value.split(JsonConstants.IN_PARAMETER_SEPARATOR);
-          for (String separatedValue : separatedValues) {
-            values.add(separatedValue);
-          }
-          sb.append(leftWherePart + ".id in (" + getTypedParameterAlias() + ")");
-          typedParameters.add(values);
-        } else {
-          sb.append(leftWherePart + ".id = " + getTypedParameterAlias());
-          typedParameters.add(value);
-        }
-      } else if (String.class == property.getPrimitiveObjectType()) {
-        if (textMatching == TextMatching.exact) {
-          sb.append(leftWherePart + " = " + getTypedParameterAlias());
-          typedParameters.add(value);
-        } else if (textMatching == TextMatching.startsWith) {
-          sb.append("upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '"
-              + ESCAPE_CHAR + "' ");
-          typedParameters.add(escapeLike(value.toUpperCase()) + "%");
-        } else {
-          sb.append("upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '"
-              + ESCAPE_CHAR + "' ");
-          typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%");
-        }
-      } else if (Boolean.class == property.getPrimitiveObjectType()) {
-        final String alias = getTypedParameterAlias();
-        typedParameters.add(new Boolean(value));
-        sb.append(leftWherePart + " = " + alias);
-      } else if (property.isNumericType()) {
-        try {
-          final String alias = getTypedParameterAlias();
-          final BigDecimal bdValue = new BigDecimal(value);
-          if (Long.class == property.getPrimitiveObjectType()) {
-            typedParameters.add(bdValue.longValue());
-          } else if (Integer.class == property.getPrimitiveObjectType()) {
-            typedParameters.add(bdValue.intValue());
-          } else {
-            typedParameters.add(bdValue);
-          }
-          sb.append(leftWherePart + " = " + alias);
-        } catch (NumberFormatException e) {
-          // ignore on purpose, incorrect value entered by user
-          // add a dummy whereclause to make the query format correct
-          sb.append(" 1=1 ");
-        }
-      } else if (Date.class.isAssignableFrom(property.getPrimitiveObjectType())) {
-        try {
-          final Calendar cal = Calendar.getInstance();
-          cal.setTime(simpleDateFormat.parse(value));
-          final String alias1 = getTypedParameterAlias();
-          typedParameters.add(cal.get(Calendar.DATE));
-          final String alias2 = getTypedParameterAlias();
-          typedParameters.add(cal.get(Calendar.MONTH) + 1);
-          final String alias3 = getTypedParameterAlias();
-          typedParameters.add(cal.get(Calendar.YEAR));
-          sb.append(" (day(" + leftWherePart + ") = " + alias1 + " and month(" + leftWherePart
-              + ") = " + alias2 + " and year(" + leftWherePart + ") = " + alias3 + ") ");
-        } catch (Exception e) {
-          // ignore these errors, just don't filter then
-          // add a dummy whereclause to make the query format correct
-          sb.append(" 1=1 ");
-        }
-
-        // } else if (property.isDate() || property.isDatetime()) {
-        // NOTE: dates arrive in the format of the user....
-        // sb.append(leftWherePart + " = ?");
-        // typedParameters.add(value);
-      } else {
-        // TODO: support this....
-        throw new UnsupportedOperationException("Type " + property.getPrimitiveObjectType()
-            + " not yet supported for parameter " + key);
-      }
-      addAnd = true;
-    }
-
-    log.debug("Whereclause for entity " + entity.getName());
-    log.debug(sb.toString());
-    for (Object param : typedParameters) {
-      log.debug(param);
-    }
-    log.debug("Textmatching " + textMatching);
-
-    if (sb.length() == 0) {
-      whereClause = orgPart.length() > 0 ? orgPart.toString() : "";
-    } else {
-      whereClause = "(" + sb.toString() + ")"
-          + (orgPart.length() > 0 ? " and " + orgPart.toString() : "");
-    }
-    if (whereParameterValue != null) {
-      if (whereClause.length() > 0) {
-        whereClause = " (" + whereClause + ") and (" + whereParameterValue + ") ";
-      } else {
-        whereClause = " " + whereParameterValue;
-      }
-    }
-    if (whereClause.trim().length() > 0) {
-      whereClause = " where " + whereClause;
-    }
-
-    // handle special transactional range parameter
-    if (whereClause.contains(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE)) {
-      final String alias = getTypedParameterAlias();
-      String windowId = RequestContext.get().getRequestParameter("windowId");
-      if (windowId == null) {
-        windowId = "";
-      }
-      final String range = Utility.getTransactionalDate(new DalConnectionProvider(false),
-          RequestContext.get().getVariablesSecureApp(), windowId);
-      final int rangeNum = Integer.parseInt(range);
-      final Calendar cal = Calendar.getInstance();
-      cal.add(Calendar.DAY_OF_MONTH, -1 * rangeNum);
-      whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE, alias);
-      typedParameters.add(cal.getTime());
-    }
-
-    if (whereClause.contains(JsonConstants.QUERY_PARAM_CLIENT)) {
-      final String alias = getTypedParameterAlias();
-      String clientId = (String) DalUtil.getId(OBContext.getOBContext().getCurrentClient());
-      whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_CLIENT, alias);
-      typedParameters.add(clientId);
-    }
-    whereClause = setRequestParameters(whereClause);
-    whereClause = substituteContextParameters(whereClause);
-
-    return whereClause;
-  }
-
-  private String substituteContextParameters(String currentWhereClause) {
-    // This method will check for any remaining @param@s
-    // If there are still some in the whereclause, they will be resolved by calling the getContext()
-    // method
-    if (!currentWhereClause.contains("@")) {
-      return currentWhereClause;
-    }
-    String localWhereClause = currentWhereClause;
-    while (localWhereClause.contains("@")) {
-      int firstAtIndex = localWhereClause.indexOf("@");
-      String prefix = localWhereClause.substring(0, firstAtIndex);
-      String restOfClause = localWhereClause.substring(firstAtIndex + 1);
-      int secondAtIndex = restOfClause.indexOf("@");
-      if (secondAtIndex == -1) {
-        // No second @. We return the clause as it is
-        return localWhereClause;
-      }
-      String suffix = restOfClause.substring(secondAtIndex + 1);
-      String param = restOfClause.substring(0, secondAtIndex);
-      String paramValue = Utility.getContext(new DalConnectionProvider(false), RequestContext.get()
-          .getVariablesSecureApp(), param, RequestContext.get().getRequestParameter("windowId"));
-      localWhereClause = prefix + getTypedParameterAlias() + suffix;
-      typedParameters.add(paramValue);
-    }
-    return localWhereClause;
-  }
-
-  private String setRequestParameters(String currentWhereClause) {
-    // no parameters
-    if (!currentWhereClause.contains(PARAM_DELIMITER)) {
-      return currentWhereClause;
-    }
-    String localWhereClause = currentWhereClause;
-    for (String key : filterParameters.keySet()) {
-      if (!key.startsWith(PARAM_DELIMITER) || !key.endsWith(PARAM_DELIMITER)) {
-        continue;
-      }
-      final int index = localWhereClause.toLowerCase().indexOf(key.toLowerCase());
-      if (index != -1) {
-        localWhereClause = localWhereClause.substring(0, index) + getTypedParameterAlias() + " "
-            + localWhereClause.substring(index + key.length());
-        typedParameters.add(filterParameters.get(key));
-      }
-    }
-
-    return localWhereClause;
-  }
-
-  private String getTypedParameterAlias() {
-    return ":" + ALIAS_PREFIX + typedParameters.size();
-  }
-
-  /**
-   * @return an empty String if there is no join clause, in other cases a String like the following
-   *         is returned " as e left join e.bank as alias_1"
-   */
-  public String getJoinClause() {
-    if (joinClause != null) {
-      return joinClause;
-    }
-
-    // make sure that the join clauses are computed
-    getWhereClause();
-    getOrderByClause();
-
-    if (getMainAlias() == null) {
-      return "";
-    }
-    final StringBuilder sb = new StringBuilder();
-    sb.append(" as " + getMainAlias() + " ");
-    for (JoinDefinition joinDefinition : joinDefinitions) {
-      sb.append(joinDefinition.getJoinStatement());
-    }
-    sb.append(" ");
-    joinClause = sb.toString();
-    return joinClause;
-  }
-
-  /**
-   * Converts the value of the sortBy member into a valid order by clause in a HQL query. The method
-   * handles special cases as sorting by the identifier properties and descending which is
-   * controlled with a minus sign before the property name.
-   * 
-   * @return a valid order by clause (or an empty string if no sorting)
-   */
-  protected String getOrderByClause() {
-    if (orderByClause != null) {
-      return orderByClause;
-    }
-    if (orderBy == null || orderBy.trim().length() == 0) {
-      orderByClause = "";
-      return orderByClause;
-    }
-    final StringBuilder sb = new StringBuilder(" order by ");
-    boolean firstElement = true;
-    for (String localOrderBy : orderBy.split(",")) {
-      if (!firstElement) {
-        sb.append(",");
-      }
-      sb.append(getOrderByClausePart(localOrderBy.trim()));
-      firstElement = false;
-    }
-    orderByClause = sb.toString();
-    return orderByClause;
-  }
-
-  protected String getOrderByClausePart(String orderByParam) {
-    String localOrderBy = orderByParam;
-    final boolean asc = !localOrderBy.startsWith("-");
-    String direction = "";
-    if (!asc) {
-      localOrderBy = localOrderBy.substring(1);
-      direction = " desc ";
-    }
-
-    final List<String> paths = new ArrayList<String>();
-
-    // handle the following case:
-    // table.window.identifier as the sort string
-    boolean isIdenfitier = localOrderBy.equals(JsonConstants.IDENTIFIER)
-        || localOrderBy.endsWith("." + JsonConstants.IDENTIFIER);
-    if (isIdenfitier) {
-      Entity searchEntity = getEntity();
-      // a path to an entity, find the last entity
-      final String prefix;
-      if (!localOrderBy.equals(JsonConstants.IDENTIFIER)) {
-        // be lazy get the last property, it belongs to the last entity
-        final Property prop = DalUtil.getPropertyFromPath(searchEntity, localOrderBy);
-        Check.isNotNull(prop, "Property path " + localOrderBy + " is not valid for entity "
-            + searchEntity);
-        searchEntity = prop.getEntity();
-        prefix = localOrderBy.substring(0, localOrderBy.lastIndexOf(".") + 1);
-      } else {
-        prefix = "";
-      }
-      for (Property prop : searchEntity.getIdentifierProperties()) {
-        if (prop.isOneToMany()) {
-          // not supported ignoring it
-          continue;
-        }
-        if (!prop.isPrimitive()) {
-          // get identifier properties from target entity
-          // TODO: currently only supports one level, recursive
-          // calls have the danger of infinite loops in case of
-          // wrong identifier definitions in the AD
-          final Entity targetEntity = prop.getTargetEntity();
-          for (Property targetEntityProperty : targetEntity.getIdentifierProperties()) {
-            paths.add(prefix + prop.getName() + "." + targetEntityProperty.getName());
-          }
-        } else {
-          paths.add(prefix + prop.getName());
-        }
-      }
-    } else {
-      paths.add(localOrderBy);
-    }
-
-    final StringBuilder sb = new StringBuilder();
-    boolean addComma = false;
-    for (String path : paths) {
-      if (addComma) {
-        sb.append(", ");
-      }
-      addComma = true;
-      final String resolvedPath = resolveJoins(JsonUtils.getPropertiesOnPath(getEntity(), path),
-          path);
-      sb.append(resolvedPath);
-      sb.append(direction);
-    }
-    return sb.toString();
-  }
-
-  // Creates a Hibernate concatenation if there are multiple identifierproperties
-  // note prefix includes the dot at the end
-  private String createIdentifierLeftClause(List<Property> identifierProperties, String prefix) {
-    final StringBuilder sb = new StringBuilder();
-    for (Property prop : identifierProperties) {
-      if (sb.length() > 0) {
-        sb.append(" || '" + IdentifierProvider.SEPARATOR + "' || ");
-      }
-      // note to_char is added to handle null values correctly
-      if (prop.getReferencedProperty() == null) {
-        sb.append("COALESCE(to_char(" + prefix + prop.getName() + "),'')");
-      } else {
-        final List<Property> newIdentifierProperties = prop.getReferencedProperty().getEntity()
-            .getIdentifierProperties();
-        sb.append(createIdentifierLeftClause(newIdentifierProperties, prefix + prop.getName() + "."));
-      }
-    }
-
-    return "(" + sb.toString() + ")";
-  }
-
-  /**
-   * @return true if one of the filter parameters is the {@link JsonConstants#ORG_PARAMETER}.
-   */
-  public boolean hasOrganizationParameter() {
-    final String value = filterParameters.get(JsonConstants.ORG_PARAMETER);
-    return value != null && value.trim().length() > 0;
-  }
-
-  /**
-   * Add a filter parameter, the method {@link #getWhereClause()} will try to convert the String
-   * value to a typed parameter.
-   * 
-   * @param key
-   *          the filter key, can be direct property or a referenced property.
-   * @param value
-   *          the value as a String
-   */
-  public void addFilterParameter(String key, String value) {
-    // ignore these
-    if (value == null) {
-      return;
-    }
-    whereClause = null;
-    typedParameters.clear();
-    filterParameters.put(key, value);
-  }
-
-  public Map<String, Object> getNamedParameters() {
-    final Map<String, Object> parameters = new HashMap<String, Object>();
-    for (int i = 0; i < typedParameters.size(); i++) {
-      parameters.put(ALIAS_PREFIX + Integer.toString(i), typedParameters.get(i));
-    }
-    return parameters;
-  }
-
-  public TextMatching getTextMatching() {
-    return textMatching;
-  }
-
-  /**
-   * The text matching strategy used. See here for a description:
-   * http://www.smartclient.com/docs/7.0rc2/a/b/c/go.html#attr..ComboBoxItem.textMatchStyle
-   * 
-   * @param matchStyle
-   *          the following values are allowed: startsWith, substring, exact
-   */
-  public void setTextMatching(TextMatching matchStyle) {
-    whereClause = null;
-    typedParameters.clear();
-    this.textMatching = matchStyle;
-  }
-
-  public boolean isDoOr() {
-    return doOr;
-  }
-
-  public void setDoOr(boolean doOr) {
-    this.doOr = doOr;
-    // in case of join always do outer joining
-    setMainAlias(JsonConstants.MAIN_ALIAS);
-  }
-
-  // Resolves the list of properties against existing join definitions
-  // creates new join definitions when necessary
-  private String resolveJoins(List<Property> props, String originalPath) {
-    String alias = getMainAlias();
-    if (alias == null) {
-      return originalPath;
-    }
-    int index = 0;
-    int joinedPropertyIndex = -1;
-    for (Property prop : props) {
-      boolean found = false;
-      for (JoinDefinition joinDefinition : joinDefinitions) {
-        if (joinDefinition.appliesTo(alias, prop)) {
-          alias = joinDefinition.getJoinAlias();
-          joinedPropertyIndex = index;
-          found = true;
-          break;
-        }
-      }
-      if (!found) {
-        // no more joins, leave
-        break;
-      }
-      index++;
-    }
-    // check if any new JoinDefinitions should be created
-    for (int i = (joinedPropertyIndex + 1); i < props.size(); i++) {
-      final Property prop = props.get(i);
-      if (prop.isPrimitive()) {
-        break;
-      }
-      // a joinable property
-      final JoinDefinition joinDefinition = new JoinDefinition();
-      joinDefinition.setOwnerAlias(alias);
-      joinDefinition.setJoinAlias(getNewUniqueAlias());
-      joinDefinition.setProperty(prop);
-      joinDefinitions.add(joinDefinition);
-
-      // move the result up to use the new JoinDefinition
-      alias = joinDefinition.getJoinAlias();
-      joinedPropertyIndex = i;
-    }
-    if (joinedPropertyIndex == (props.size() - 1)) {
-      return alias;
-    }
-    return alias + "." + props.get(props.size() - 1).getName();
-  }
-
-  private String getNewUniqueAlias() {
-    return ALIAS_PREFIX + (aliasIndex++);
-  }
-
-  private class JoinDefinition {
-    private Property property;
-    private String joinAlias;
-    private String ownerAlias;
-
-    public boolean appliesTo(String checkAlias, Property checkProperty) {
-      return checkAlias.equals(ownerAlias) && checkProperty == property;
-    }
-
-    public String getJoinStatement() {
-      return " left outer join " + ownerAlias + "." + property.getName() + " as " + joinAlias;
-    }
-
-    public void setProperty(Property property) {
-      this.property = property;
-    }
-
-    public String getJoinAlias() {
-      return joinAlias;
-    }
-
-    public void setJoinAlias(String joinAlias) {
-      this.joinAlias = joinAlias;
-    }
-
-    public void setOwnerAlias(String ownerAlias) {
-      this.ownerAlias = ownerAlias;
-    }
-  }
-
-  public String getMainAlias() {
-    return mainAlias;
-  }
-
-  public void setMainAlias(String mainAlias) {
-    this.mainAlias = mainAlias;
-  }
-
-  public String getOrderBy() {
-    return orderBy;
-  }
-
-  public void setOrderBy(String orderBy) {
-    this.orderBy = orderBy;
-    // do outer joining if the order by has more than 1 dot
-    if (orderBy.indexOf(".") != -1 && orderBy.indexOf(".") != orderBy.lastIndexOf(".")) {
-      setMainAlias(JsonConstants.MAIN_ALIAS);
-    }
-  }
-
-  private String escapeLike(String value) {
-    if (value == null || value.trim().length() == 0) {
-      return value;
-    }
-    String localValue = value.replace(ESCAPE_CHAR + "", ESCAPE_CHAR + ESCAPE_CHAR + "");
-    localValue = localValue.replace("_", ESCAPE_CHAR + "_");
-    localValue = localValue.replace("%", ESCAPE_CHAR + "%");
-    return localValue;
-  }
-}
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/CustomQuerySelectorDatasource.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/CustomQuerySelectorDatasource.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2011-2015 Openbravo SLU
+ * All portions are Copyright (C) 2011-2016 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Wed May 04 17:29:34 2016 +0200
@@ -50,10 +50,10 @@
 import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.model.ad.domain.Validation;
 import org.openbravo.service.datasource.DataSourceFilter;
+import org.openbravo.service.json.AdvancedQueryBuilder.TextMatching;
 import org.openbravo.service.json.DefaultJsonDataService;
 import org.openbravo.service.json.JsonConstants;
 import org.openbravo.service.json.JsonUtils;
-import org.openbravo.service.json.QueryBuilder.TextMatching;
 
 /**
  * Implements the a datasource filter request for the selectors. Used to generates Hibernate where
@@ -370,11 +370,6 @@
           sb.append(" and ");
         }
 
-        // Code duplicated from org.openbravo.service.json.QueryBuilder
-        // Used to identify the type of property and modify the _where parameter
-        // If the this code change, make sure you check the getWhereClause method of the
-        // QueryBuilder. Check issue https://issues.openbravo.com/view.php?id=14239
-
         if (!property.isPrimitive()) {
           sb.append("e." + sf.getProperty() + ".id = '" + result.toString() + "'");
         } else if (String.class == property.getPrimitiveObjectType()) {
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorFieldPropertyDataSource.java	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorFieldPropertyDataSource.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2010-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -23,9 +23,11 @@
 import java.util.Map;
 
 import org.apache.commons.lang.StringUtils;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.service.datasource.ModelDataSourceService;
 
@@ -37,6 +39,21 @@
 public class SelectorFieldPropertyDataSource extends ModelDataSourceService {
 
   private static final String SELECTOR_FIELD = "inpobuiselSelectorId";
+  private static final String TAB_ID = "inpTabId";
+
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    final String tabId = parameter.get(TAB_ID);
+    try {
+      final Entity entity = ModelProvider.getInstance().getEntityByTableId(tabId);
+      if (entity != null) {
+        obContext.getEntityAccessChecker().checkReadableAccess(entity);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
 
   /*
    * (non-Javadoc)
--- a/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Wed May 04 13:23:26 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Wed May 04 17:29:34 2016 +0200
@@ -1112,6 +1112,13 @@
   // Prepares requestProperties adding contextInfo, this is later used in backed
   // to prepare filters 
   prepareDSRequest: function (params, selector) {
+    function setOrgIdParam(params) {
+      if (!params.inpadOrgId) {
+        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
+        params.inpadOrgId = params.ad_org_id || params.AD_Org_ID || OB.User.organizationId;
+      }
+    }
+
     // on purpose not passing the third boolean param
     if (selector.form && selector.form.view && selector.form.view.getContextInfo) {
       // for table and table dir reference values needs to be transformed to classic (ex.: true -> Y)
@@ -1121,20 +1128,14 @@
       if (selector.form && selector.form.paramWindow && selector.form.paramWindow.getContextInfo) {
         isc.addProperties(params, selector.form.paramWindow.getContextInfo());
       }
-      if (!params.inpadOrgId) {
-        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
-        params.inpadOrgId = params.ad_org_id || OB.User.organizationId;
-      }
+      setOrgIdParam(params);
     } else if (selector.view && selector.view.sourceView && selector.view.sourceView.getContextInfo) {
       isc.addProperties(params, selector.view.sourceView.getContextInfo(false, true, null, selector.isComboReference));
     } else if (selector.grid && selector.grid.contentView && selector.grid.contentView.getContextInfo) {
       isc.addProperties(params, selector.grid.contentView.getContextInfo(false, true, null, selector.isComboReference));
     } else if (selector.form && selector.form.paramWindow && selector.form.paramWindow.getContextInfo) {
       isc.addProperties(params, selector.form.paramWindow.getContextInfo());
-      if (!params.inpadOrgId) {
-        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
-        params.inpadOrgId = params.ad_org_id || OB.User.organizationId;
-      }
+      setOrgIdParam(params);
     }
 
     // if the selector belongs to a P&E grid, include the info of the record being edited
Binary file src-db/database/lib/dbsourcemanager.jar has changed
--- a/src-db/database/model/functions/C_INVOICE_CREATE.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/C_INVOICE_CREATE.xml	Wed May 04 17:29:34 2016 +0200
@@ -993,7 +993,7 @@
                 CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 2, 1))
                   WHEN '0'
                   THEN '0'
-                  ELSE sh.C_Order_ID
+                  ELSE COALESCE(sh.C_Order_ID, o.C_Order_ID)
                 END
                 ) ||'-'|| (
                 CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 3, 1))
@@ -1032,7 +1032,7 @@
                   ELSE COALESCE(o.C_PaymentTerm_ID, bp.C_PaymentTerm_ID)
                 END
                 ) ||'-'|| (
-                CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 8, 1))
+                CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 9, 1))
                   WHEN '0'
                   THEN '0'
                   ELSE o.C_Currency_ID
--- a/src-db/database/model/functions/C_ORDER_POST1.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/C_ORDER_POST1.xml	Wed May 04 17:29:34 2016 +0200
@@ -398,12 +398,25 @@
     */
     IF (v_DocAction = 'CO' OR v_DocAction = 'PR') THEN
       SELECT COUNT(*)
-        INTO v_Aux
-       FROM C_ORDERLINE
-       WHERE C_ORDER_ID = v_Record_ID;
-       IF v_Aux=0 THEN
-         RAISE_APPLICATION_ERROR(-20000, '@OrderWithoutLines@');
-       END IF;
+      INTO v_Aux
+      FROM C_ORDERLINE
+      WHERE C_ORDER_ID = v_Record_ID;
+      IF (v_Aux = 0) THEN
+        RAISE_APPLICATION_ERROR(-20000, '@OrderWithoutLines@');
+      END IF;
+    END IF;
+
+    /**
+    * Check if already processed / reactivated
+    */
+    IF (v_DocAction = 'CO' OR v_DocAction = 'PR') THEN
+      IF (v_IsProcessed = 'Y') THEN
+        RAISE_APPLICATION_ERROR(-20000,'@AlreadyPosted@');
+      END IF;
+    ELSIF (v_DocAction='RE') THEN
+      IF (v_IsProcessed = 'N') THEN
+        RAISE_APPLICATION_ERROR(-20000,'@ActionNotSupported@');
+      END IF;
     END IF;
 
     -- Check the cash vat flag for all the taxes matches the order one
--- a/src-db/database/model/functions/MA_PRODUCTION_COST.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/MA_PRODUCTION_COST.xml	Wed May 04 17:29:34 2016 +0200
@@ -22,7 +22,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2014 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************/
@@ -451,12 +451,12 @@
               INSERT INTO M_COSTING (M_COSTING_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY, AD_CLIENT_ID,
                             AD_ORG_ID, M_PRODUCT_ID, DATETO, DATEFROM, ISMANUAL,
                             M_PRODUCTIONLINE_ID, QTY,
-                            PRICE,  CUMQTY,
+                            PRICE,
                             COST, ISPERMANENT, ISPRODUCTION, COSTTYPE)
                      VALUES (v_NextNo,now(), p_User_ID, now(), p_User_ID, Cur_ProductionLine.AD_CLIENT_ID,
                             Cur_ProductionLine.AD_ORG_ID, Cur_ProductionLine.M_PRODUCT_ID, TO_DATE('31-12-9999','DD-MM-YYYY'), v_CostingDate, 'N',
                             Cur_ProductionLine.M_PRODUCTIONLINE_ID, Cur_ProductionLine.MOVEMENTQTY,
-                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4), COALESCE(v_Qty,0) + Cur_ProductionLine.MOVEMENTQTY,
+                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4),
                             (CASE (Cur_ProductionLine.MOVEMENTQTY) WHEN 0 THEN 0 ELSE ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4) END), 'N', 'Y', 'AV');
             ELSE
               v_ResultStr := 'update cost';
@@ -508,13 +508,13 @@
                 INSERT INTO M_COSTING (M_COSTING_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY, AD_CLIENT_ID,
                             AD_ORG_ID, M_PRODUCT_ID, DATETO, DATEFROM, ISMANUAL,
                             M_PRODUCTIONLINE_ID, QTY,
-                            PRICE, CUMQTY,
+                            PRICE,
                             COST,
                             ISPERMANENT, ISPRODUCTION, COSTTYPE)
                        VALUES (v_NextNo,now(), p_User_ID, now(), p_User_ID, Cur_ProductionLine.AD_CLIENT_ID,
                             Cur_ProductionLine.AD_ORG_ID, Cur_ProductionLine.M_PRODUCT_ID, v_DateTo, v_CostingDate, 'N',
                             Cur_ProductionLine.M_PRODUCTIONLINE_ID, Cur_ProductionLine.MOVEMENTQTY,
-                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4), COALESCE(v_Qty,0) + Cur_ProductionLine.MOVEMENTQTY,
+                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4),
                             (CASE (v_Qty+Cur_ProductionLine.MOVEMENTQTY) WHEN 0 THEN 0 ELSE ROUND(((v_Qty*v_CostOld)+(v_Cost))/(v_Qty+Cur_ProductionLine.MOVEMENTQTY),4)END),
                                 'N', 'Y', 'AV');
               ELSIF (v_count2 = 0) THEN
@@ -538,13 +538,13 @@
                 INSERT INTO M_COSTING (M_COSTING_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY, AD_CLIENT_ID,
                             AD_ORG_ID, M_PRODUCT_ID, DATETO, DATEFROM, ISMANUAL,
                             M_PRODUCTIONLINE_ID, QTY,
-                            PRICE, CUMQTY,
+                            PRICE,
                             COST,
                             ISPERMANENT, ISPRODUCTION, COSTTYPE)
                        VALUES (v_NextNo,now(), p_User_ID, now(), p_User_ID, Cur_ProductionLine.AD_CLIENT_ID,
                             Cur_ProductionLine.AD_ORG_ID, Cur_ProductionLine.M_PRODUCT_ID, v_DateTo, v_CostingDate, 'N',
                             Cur_ProductionLine.M_PRODUCTIONLINE_ID, Cur_ProductionLine.MOVEMENTQTY,
-                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4), COALESCE(v_Qty,0) + Cur_ProductionLine.MOVEMENTQTY,
+                            ROUND(v_Cost/Cur_ProductionLine.MOVEMENTQTY,4),
                             (CASE (v_Qty+Cur_ProductionLine.MOVEMENTQTY) WHEN 0 THEN 0 ELSE ROUND(((v_Qty*v_CostOld)+(v_Cost))/(v_Qty+Cur_ProductionLine.MOVEMENTQTY),4)END),
                               'N', 'Y', 'AV');
 
--- a/src-db/database/model/functions/M_GENERATE_AVERAGE_COSTS.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/M_GENERATE_AVERAGE_COSTS.xml	Wed May 04 17:29:34 2016 +0200
@@ -16,7 +16,7 @@
 * under the License.
 * The Original Code is Openbravo ERP.
 * The Initial Developer of the Original Code is Openbravo SLU
-* All portions are Copyright (C) 2001-2012 Openbravo SLU
+* All portions are Copyright (C) 2001-2016 Openbravo SLU
 * All Rights Reserved.
 * Contributor(s):  ______________________________________.
 ************************************************************************/
@@ -560,7 +560,7 @@
 		  M_COSTING_ID, CREATED, CREATEDBY, UPDATED,
 		  UPDATEDBY, AD_CLIENT_ID, AD_ORG_ID, M_PRODUCT_ID,
 		  DATETO, DATEFROM, ISMANUAL, M_INOUTLINE_ID,
-		  C_INVOICELINE_ID, QTY, PRICE, CUMQTY,
+		  C_INVOICELINE_ID, QTY, PRICE,
 		  COST, COSTTYPE, ISPERMANENT
 		)
 		VALUES
@@ -568,7 +568,7 @@
 		  Ad_Sequence_Nextno('M_Costing'), now(), v_User, now(),
 		  v_User, Cur_InOutLine.AD_CLIENT_ID, Cur_InOutLine.AD_ORG_ID, Cur_InOutLine.M_PRODUCT_ID,
 		  COALESCE(v_Date, TO_DATE('31-12-9999', 'DD-MM-YYYY')), Cur_InOutLine.MOVEMENTDATE, 'N', Cur_InOutLine.M_INOUTLINE_ID,
-		  NULL, Cur_InOutLine.MOVEMENTQTY, v_PriceNew, COALESCE(v_Qty, 0) + Cur_InOutLine.MOVEMENTQTY + v_CumQty, v_CostNew,
+		  NULL, Cur_InOutLine.MOVEMENTQTY, v_PriceNew, v_CostNew,
 		  'AV', 'N'
 		);
       END IF; 
--- a/src-db/database/model/functions/M_GENERATE_STANDARD_COSTS.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/M_GENERATE_STANDARD_COSTS.xml	Wed May 04 17:29:34 2016 +0200
@@ -22,7 +22,7 @@
 * under the License.
 * The Original Code is Openbravo ERP.
 * The Initial Developer of the Original Code is Openbravo SLU
-* All portions are Copyright (C) 2001-2006 Openbravo SLU
+* All portions are Copyright (C) 2001-2016 Openbravo SLU
 * All Rights Reserved.
 * Contributor(s):  ______________________________________.
 ************************************************************************/
@@ -102,7 +102,7 @@
           M_COSTING_ID, CREATED, CREATEDBY, UPDATED,
           UPDATEDBY, AD_CLIENT_ID, AD_ORG_ID, M_PRODUCT_ID,
           DATETO, DATEFROM, ISMANUAL, M_INOUTLINE_ID,
-          C_INVOICELINE_ID, QTY, PRICE, CUMQTY,
+          C_INVOICELINE_ID, QTY, PRICE,
           COST, COSTTYPE, ISPERMANENT
         )
         VALUES
@@ -110,7 +110,7 @@
           Ad_Sequence_Nextno('M_Costing'), now(), v_User, now(),
           v_User, Cur_PriceList.AD_CLIENT_ID, Cur_PriceList.AD_ORG_ID, Cur_PriceList.M_PRODUCT_ID,
           TO_DATE('31-12-9999', 'DD-MM-YYYY'), p_Date, 'N', NULL,
-          NULL, 0, Cur_PriceList.COSTSTD, 0,
+          NULL, 0, Cur_PriceList.COSTSTD,
           Cur_PriceList.COSTSTD, 'ST', 'N'
         )
         ;
--- a/src-db/database/model/functions/M_RESERVE_STOCK_AUTO.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/model/functions/M_RESERVE_STOCK_AUTO.xml	Wed May 04 17:29:34 2016 +0200
@@ -44,7 +44,6 @@
   v_pendingtoreserveqty         NUMBER;
   v_pendingqty                  NUMBER;
   v_reserveqty                  NUMBER;
-  v_reservationqty              NUMBER;
   v_dummy                       VARCHAR2(2000) := '';
   v_pinstance_id                VARCHAR2(32) := get_uuid();
   v_prioritywarehouse_id        VARCHAR2(32);
@@ -56,10 +55,10 @@
 BEGIN
   SELECT quantity - COALESCE(reservedqty,0),
          m_product_id, c_uom_id, m_attributesetinstance_id, m_locator_id, m_warehouse_id,
-         ad_client_id, ad_org_id, c_orderline_id, quantity, COALESCE(reservedqty,0)
+         ad_client_id, ad_org_id, c_orderline_id, quantity
     INTO v_pendingtoreserveqty,
          v_product_id, v_uom_id, v_asi_id, v_locator_id, v_warehouse_id,
-         v_client_id, v_org_id, v_soline_id, v_reserveqty, v_reservationqty
+         v_client_id, v_org_id, v_soline_id, v_reserveqty
   FROM m_reservation
   WHERE m_reservation_id = p_reservation_id;
 
@@ -81,7 +80,7 @@
       WHERE c_orderline_id = v_soline_id;
     END IF;
 
-    M_GET_STOCK_PARAM(v_pinstance_id, p_reservation_id, v_pendingtoreserveqty, v_product_id, v_locator_id, v_warehouse_id, v_prioritywarehouse_id, v_org_id, v_asi_id, p_User_ID, v_client_id, v_warehouse_rule_id, v_uom_id, null, null, null, null, '---', p_reservation_id, 'N', v_pinstance_result, v_pinstance_msg);
+    M_GET_STOCK_PARAM(v_pinstance_id, p_reservation_id, v_pendingtoreserveqty, v_product_id, v_locator_id, v_warehouse_id, v_prioritywarehouse_id, v_org_id, v_asi_id, p_User_ID, v_client_id, v_warehouse_rule_id, v_uom_id, null, null, null, null, '---', null, 'N', v_pinstance_result, v_pinstance_msg);
     -- Check result
     IF (v_pinstance_result = 0) THEN
       -- Error on m_get_stock
@@ -105,11 +104,7 @@
     AND sd.m_product_uom_id IS NULL
     ORDER BY sp.priority
   ) LOOP
-    IF (cur_stock.quantity < v_pendingqty) THEN
-      v_qty := cur_stock.quantity - v_reservationqty;
-    ELSE
-      v_qty := v_pendingqty;
-    END IF;
+    v_qty := LEAST(cur_stock.quantity, v_pendingqty);
     M_RESERVE_STOCK_MANUAL(p_reservation_id, 'SD', cur_stock.m_storage_detail_id, v_qty, p_user_id, cur_stock.isallocated, v_dummy);
     v_pendingqty := v_pendingqty - v_qty;
     IF (v_pendingqty <= 0) THEN
--- a/src-db/database/sourcedata/AD_COLUMN.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/AD_COLUMN.xml	Wed May 04 17:29:34 2016 +0200
@@ -349632,7 +349632,10 @@
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <NAME><![CDATA[RecalculatePermissions]]></NAME>
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <DESCRIPTION><![CDATA[Recalculate Permissions]]></DESCRIPTION>
-<!--BD52841FB8554ED8B347EDDD9A48D00E-->  <HELP><![CDATA[A process which recalculates role permissions using role inheritance]]></HELP>
+<!--BD52841FB8554ED8B347EDDD9A48D00E-->  <HELP><![CDATA[This process recalculates role permissions, based on the role inheritance defined. Depending on the role type the behavior varies:
+- If the role is a template one, the permissions for the role will be recalculated and also propagated to every role which is currently inheriting from this template.
+- If the role is not marked as template, just the permissions for this role are recalculated.
+For details - http://wiki.openbravo.com/wiki/Role#Permissions_Inheritance]]></HELP>
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <COLUMNNAME><![CDATA[Recalculatepermissions]]></COLUMNNAME>
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <AD_TABLE_ID><![CDATA[156]]></AD_TABLE_ID>
 <!--BD52841FB8554ED8B347EDDD9A48D00E-->  <AD_REFERENCE_ID><![CDATA[28]]></AD_REFERENCE_ID>
--- a/src-db/database/sourcedata/AD_ELEMENT.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/AD_ELEMENT.xml	Wed May 04 17:29:34 2016 +0200
@@ -33611,7 +33611,10 @@
 <!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <NAME><![CDATA[Recalculate Permissions]]></NAME>
 <!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <PRINTNAME><![CDATA[Recalculate Permissions]]></PRINTNAME>
 <!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <DESCRIPTION><![CDATA[Recalculate Permissions]]></DESCRIPTION>
-<!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <HELP><![CDATA[A process which recalculates role permissions using role inheritance]]></HELP>
+<!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <HELP><![CDATA[This process recalculates role permissions, based on the role inheritance defined. Depending on the role type the behavior varies:
+- If the role is a template one, the permissions for the role will be recalculated and also propagated to every role which is currently inheriting from this template.
+- If the role is not marked as template, just the permissions for this role are recalculated.
+For details - http://wiki.openbravo.com/wiki/Role#Permissions_Inheritance]]></HELP>
 <!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--DE965C6322B04FCAAC6DDCB4334CE52A-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
 <!--DE965C6322B04FCAAC6DDCB4334CE52A--></AD_ELEMENT>
--- a/src-db/database/sourcedata/AD_FIELD.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/AD_FIELD.xml	Wed May 04 17:29:34 2016 +0200
@@ -303159,12 +303159,15 @@
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <NAME><![CDATA[Recalculate Permissions]]></NAME>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <DESCRIPTION><![CDATA[Recalculate Permissions]]></DESCRIPTION>
-<!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <HELP><![CDATA[A process which recalculates role permissions using role inheritance]]></HELP>
+<!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <HELP><![CDATA[This process recalculates role permissions, based on the role inheritance defined. Depending on the role type the behavior varies:
+- If the role is a template one, the permissions for the role will be recalculated and also propagated to every role which is currently inheriting from this template.
+- If the role is not marked as template, just the permissions for this role are recalculated.
+For details - http://wiki.openbravo.com/wiki/Role#Permissions_Inheritance]]></HELP>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <AD_TAB_ID><![CDATA[119]]></AD_TAB_ID>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <AD_COLUMN_ID><![CDATA[BD52841FB8554ED8B347EDDD9A48D00E]]></AD_COLUMN_ID>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <IGNOREINWAD><![CDATA[N]]></IGNOREINWAD>
-<!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
+<!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <ISDISPLAYED><![CDATA[N]]></ISDISPLAYED>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <DISPLAYLENGTH><![CDATA[1]]></DISPLAYLENGTH>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
 <!--E63ED96DC2FB41A2ADD1F6C5B5C08319-->  <SEQNO><![CDATA[160]]></SEQNO>
--- a/src-db/database/sourcedata/AD_REF_LIST.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml	Wed May 04 17:29:34 2016 +0200
@@ -7923,8 +7923,8 @@
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
 <!--06F962562D694CEC88B00D4247A2315A-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--06F962562D694CEC88B00D4247A2315A-->  <VALUE><![CDATA[S]]></VALUE>
-<!--06F962562D694CEC88B00D4247A2315A-->  <NAME><![CDATA[Successfull]]></NAME>
-<!--06F962562D694CEC88B00D4247A2315A-->  <DESCRIPTION><![CDATA[Sesion logged in successfully]]></DESCRIPTION>
+<!--06F962562D694CEC88B00D4247A2315A-->  <NAME><![CDATA[Successful]]></NAME>
+<!--06F962562D694CEC88B00D4247A2315A-->  <DESCRIPTION><![CDATA[Session logged in successfully]]></DESCRIPTION>
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_REFERENCE_ID><![CDATA[86086D70DDBC42B09E2BEB51D25C159F]]></AD_REFERENCE_ID>
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--06F962562D694CEC88B00D4247A2315A--></AD_REF_LIST>
@@ -10477,7 +10477,7 @@
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <VALUE><![CDATA[CUR]]></VALUE>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <NAME><![CDATA[Concurrent Users Limit Reached]]></NAME>
-<!--88EDCB912A6445A4BE6EEA28952212E9-->  <DESCRIPTION><![CDATA[Reached number of maximum concurrent users in the instance]]></DESCRIPTION>
+<!--88EDCB912A6445A4BE6EEA28952212E9-->  <DESCRIPTION><![CDATA[Reached maximum number of allowed concurrent users in the instance]]></DESCRIPTION>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <AD_REFERENCE_ID><![CDATA[86086D70DDBC42B09E2BEB51D25C159F]]></AD_REFERENCE_ID>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--88EDCB912A6445A4BE6EEA28952212E9--></AD_REF_LIST>
@@ -12405,6 +12405,18 @@
 <!--DA3E593E14834F0C9895132B46C51369-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--DA3E593E14834F0C9895132B46C51369--></AD_REF_LIST>
 
+<!--DA98D956E0BF4DCA887932756C327D73--><AD_REF_LIST>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_REF_LIST_ID><![CDATA[DA98D956E0BF4DCA887932756C327D73]]></AD_REF_LIST_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <VALUE><![CDATA[BypassAccessLevelEntityCheck]]></VALUE>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <NAME><![CDATA[Bypass Access Level Entity Check]]></NAME>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <DESCRIPTION><![CDATA[When its value is Y, entity access level check will not be performed.]]></DESCRIPTION>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--DA98D956E0BF4DCA887932756C327D73--></AD_REF_LIST>
+
 <!--DAC02370F50D485BAA4F79957AA1A7A4--><AD_REF_LIST>
 <!--DAC02370F50D485BAA4F79957AA1A7A4-->  <AD_REF_LIST_ID><![CDATA[DAC02370F50D485BAA4F79957AA1A7A4]]></AD_REF_LIST_ID>
 <!--DAC02370F50D485BAA4F79957AA1A7A4-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/OBUIAPP_PROCESS.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/OBUIAPP_PROCESS.xml	Wed May 04 17:29:34 2016 +0200
@@ -650,7 +650,8 @@
 <!--F1EC1AB61DCD4858BAD3A52BE60006F9-->  <NAME><![CDATA[Recalculate Role Permissions]]></NAME>
 <!--F1EC1AB61DCD4858BAD3A52BE60006F9-->  <HELP><![CDATA[This process recalculates role permissions, based on the role inheritance defined. Depending on the role type the behavior varies:
 - If the role is a template one, the permissions for the role will be recalculated and also propagated to every role which is currently inheriting from this template.
-- If the role is not marked as template, just the permissions for this role are recalculated. ]]></HELP>
+- If the role is not marked as template, just the permissions for this role are recalculated.
+For details - http://wiki.openbravo.com/wiki/Role#Permissions_Inheritance]]></HELP>
 <!--F1EC1AB61DCD4858BAD3A52BE60006F9-->  <ACCESSLEVEL><![CDATA[3]]></ACCESSLEVEL>
 <!--F1EC1AB61DCD4858BAD3A52BE60006F9-->  <CLASSNAME><![CDATA[OB.RoleInheritance.recalculatePermissions]]></CLASSNAME>
 <!--F1EC1AB61DCD4858BAD3A52BE60006F9-->  <ISBACKGROUND><![CDATA[N]]></ISBACKGROUND>
--- a/src-db/database/sourcedata/referencedData/C_CURRENCY.xml	Wed May 04 13:23:26 2016 +0200
+++ b/src-db/database/sourcedata/referencedData/C_CURRENCY.xml	Wed May 04 17:29:34 2016 +0200
@@ -855,7 +855,7 @@
 <!--170-->  <CREATEDBY><![CDATA[0]]></CREATEDBY>
 <!--170-->  <UPDATED><![CDATA[2011-02-22 17:06:39.0]]></UPDATED>
 <!--170-->  <UPDATEDBY><![CDATA[0]]></UPDATEDBY>
-<!--170-->  <ISO_CODE><![CDATA[GHC]]></ISO_CODE>
+<!--170-->  <ISO_CODE><![CDATA[GHS]]></ISO_CODE>
 <!--170-->  <CURSYMBOL><![CDATA[ยข]]></CURSYMBOL>
 <!--170-->  <DESCRIPTION><![CDATA[Cedi]]></DESCRIPTION>
 <!--170-->  <STDPRECISION><![CDATA[2]]></STDPRECISION>
--- a/src-test/src/org/openbravo/test/AllAntTaskTests.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/AllAntTaskTests.java	Wed May 04 17:29:34 2016 +0200
@@ -77,6 +77,7 @@
 import org.openbravo.test.scheduling.ProcessSchedulingTest;
 import org.openbravo.test.security.AccessLevelTest;
 import org.openbravo.test.security.AllowedOrganizationsTest;
+import org.openbravo.test.security.BypassAccessLevelCheck;
 import org.openbravo.test.security.EntityAccessTest;
 import org.openbravo.test.security.StandardCrossOrganizationReference;
 import org.openbravo.test.security.WritableReadableOrganizationClientTest;
@@ -159,6 +160,7 @@
     EntityAccessTest.class, //
     WritableReadableOrganizationClientTest.class, //
     StandardCrossOrganizationReference.class, //
+    BypassAccessLevelCheck.class, //
 
     // system
     SystemServiceTest.class, //
--- a/src-test/src/org/openbravo/test/AllWebserviceTests.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/AllWebserviceTests.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2010-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -34,6 +34,7 @@
 import org.openbravo.test.datasource.FetchDSNoActiveEntityObjects;
 import org.openbravo.test.datasource.TestNoteDatasource;
 import org.openbravo.test.security.ExplicitCrossOrganizationReference;
+import org.openbravo.test.datasource.DataSourceSecurity;
 import org.openbravo.test.webservice.JSONWebServices;
 import org.openbravo.test.webservice.PerformanceTest;
 import org.openbravo.test.webservice.WSAddRecordWithComputedColumns;
@@ -70,6 +71,7 @@
     ExtendedNavigationModelTest.class, //
     WSWithNoActiveDalObjects.class, //
     FetchDSNoActiveEntityObjects.class, //
-    ExplicitCrossOrganizationReference.class })
+    ExplicitCrossOrganizationReference.class, //
+    DataSourceSecurity.class })
 public class AllWebserviceTests {
 }
--- a/src-test/src/org/openbravo/test/base/OBBaseTest.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/base/OBBaseTest.java	Wed May 04 17:29:34 2016 +0200
@@ -71,12 +71,20 @@
   @Rule
   public TestWatcher watchFailures = new TestWatcher() {
     @Override
+    protected void starting(Description description) {
+      log.info("*** Starting test case: " + getTestName(description));
+    };
+
+    @Override
     protected void failed(Throwable e, Description description) {
       errorOccured = true;
     }
 
     @Override
     protected void finished(Description description) {
+      log.info("*** Finished test case: " + getTestName(description)
+          + (errorOccured ? " - with errors" : ""));
+
       // if not an administrator but still admin mode set throw an exception
       if (!OBContext.getOBContext().getUser().getId().equals("0")
           && !OBContext.getOBContext().getRole().getId().equals("0")
@@ -107,6 +115,11 @@
 
       super.finished(description);
     }
+
+    private String getTestName(Description description) {
+      return description.getClassName() + "." + description.getMethodName();
+    }
+
   };
 
   private static final Logger log = Logger.getLogger(OBBaseTest.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/datasource/DataSourceSecurity.java	Wed May 04 17:29:34 2016 +0200
@@ -0,0 +1,400 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2016 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.datasource;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.openbravo.base.provider.OBProvider;
+import org.openbravo.dal.core.DalUtil;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.ad.access.Role;
+import org.openbravo.model.ad.access.RoleOrganization;
+import org.openbravo.model.ad.access.UserRoles;
+import org.openbravo.model.ad.domain.Preference;
+import org.openbravo.model.ad.system.Client;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.common.uom.UOM;
+import org.openbravo.model.materialmgmt.onhandquantity.Reservation;
+import org.openbravo.service.json.JsonConstants;
+
+/**
+ * Test cases to ensure that mechanism of security DataSource access is working properly.
+ *
+ * @author inigo.sanchez
+ *
+ */
+@RunWith(Parameterized.class)
+public class DataSourceSecurity extends BaseDataSourceTestDal {
+  private static final String ASTERISK_ORG_ID = "0";
+  private static final String CONTEXT_USER = "100";
+  private static final String LANGUAGE_ID = "192";
+  private static final String WAREHOUSE_ID = "B2D40D8A5D644DD89E329DC297309055";
+  private static final String ROLE_INTERNATIONAL_ADMIN = "42D0EEB1C66F497A90DD526DC597E6F0";
+  private static final String ROLE_NO_ACCESS = "1";
+  private static final String ROLE_SYSTEM_ADMIN = "0";
+  private static final String ESP_ORG = "E443A31992CB4635AFCAEABE7183CE85";
+  private static final String CLIENT = "23C59575B9CF467C9620760EB255B389";
+
+  private static final String TABLE_WINDOWS_TABS_FIELDS_ID = "105";
+  private static final String RECORD_OF_WINDOWS_TABS_FIELDS_ID = "283";
+  private static final String ID_TESTING = "11";
+  private static final Object PROD_RESERVATION = "DA7FC1BB3BA44EC48EC1AB9C74168CED";
+
+  private RoleType role;
+  private DataSource dataSource;
+  private int expectedResponseStatus;
+
+  private enum RoleType {
+    ADMIN_ROLE(ROLE_INTERNATIONAL_ADMIN, ESP_ORG), //
+    NO_ACCESS_ROLE(ROLE_NO_ACCESS, ESP_ORG), //
+    SYSTEM_ROLE(ROLE_SYSTEM_ADMIN, ASTERISK_ORG_ID);
+
+    private String roleId;
+    private String orgId;
+
+    private RoleType(String roleId, String orgId) {
+      this.roleId = roleId;
+      this.orgId = orgId;
+    }
+  }
+
+  @SuppressWarnings("serial")
+  private enum DataSource {
+    Order("Order"), //
+    Alert("DB9F062472294F12A0291A7BD203F922"), //
+    ProductByPriceAndWarehouse("ProductByPriceAndWarehouse", new HashMap<String, String>() {
+      {
+        try {
+          put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
+          put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
+          put("_sortBy", "_identifier");
+          put("_requestType", "Window");
+          put("_distinct", "productPrice");
+
+          // To reproduce this problem is important not to add the targetProperty parameter. For
+          // this reason targetProperty=null.
+          put("_inpTableId", "293");
+          put("_textMatchStyle", "substring");
+
+          // Filter selector
+          JSONObject criteria = new JSONObject();
+          criteria.put("fieldName", "productPrice$priceListVersion$_identifier");
+          criteria.put("operator", "iContains");
+          criteria.put("value", "Tarifa");
+          put("criteria", criteria.toString());
+        } catch (Exception ignore) {
+        }
+      }
+    }), //
+    PropertySelector("83B60C4C19AE4A9EBA947B948C5BA04D", new HashMap<String, String>() {
+      {
+        // Property selector invocation from Windows > Tab > Field > Property field
+        put("_selectorDefinitionId", "387D9FFC48A74054835C5DF6E6FD08F7");
+        put("inpadTableId", "259");
+        put("inpTabId", "107");
+        put("targetProperty", "property");
+      }
+    }), //
+    ManageVariants("6654D607F650425A9DFF7B6961D54920", new HashMap<String, String>() {
+      {
+        put("@Product.id@", ID_TESTING);
+      }
+    }), //
+    Note("090A37D22E61FE94012E621729090048", new HashMap<String, String>() {
+      {
+        // Note of a record in Windows, Tabs and Fields.
+        String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
+            + TABLE_WINDOWS_TABS_FIELDS_ID
+            + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
+            + RECORD_OF_WINDOWS_TABS_FIELDS_ID + "\"}";
+        String entityName = "OBUIAPP_Note";
+        put("criteria", criteria);
+        put("_entityName", entityName);
+      }
+    }), //
+    ProductCharacteristics("BE2735798ECC4EF88D131F16F1C4EC72"), //
+    Combo("ComboTableDatasourceService", new HashMap<String, String>() {
+      {
+        // Sales Order > Payment Terms
+        put("fieldId", "1099");
+      }
+    }), //
+    CustomQuerySelectorDatasource("F8DD408F2F3A414188668836F84C21AF",
+        new HashMap<String, String>() {
+          {
+            // Sales Invoice > Selector Business Partner
+            put("_selectorDefinitionId", "862F54CB1B074513BD791C6789F4AA42");
+            put("inpTableId", "318");
+            put("targetProperty", "businessPartner");
+          }
+        }), //
+    CustomQuerySelectorDatasourceProcess("ADList", new HashMap<String, String>() {
+      {
+        // Sales Order > Add Payment process > Selector Action Regarding Document
+        put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
+        put("_processDefinitionId", "9BED7889E1034FE68BD85D5D16857320");
+        put("targetProperty", "businessPartner");
+      }
+    }), //
+    SelectorGLItemDatasource("FinancialMgmtGLItem", new HashMap<String, String>() {
+      {
+        // Payment In > Add Details process > GLItem section > Selector GLItem
+        put("_selectorDefinitionId", "9FAD469CE4414A25974CF45C0AD22D35");
+        put("inpTableId", "D1A97202E832470285C9B1EB026D54E2");
+        put("targetProperty", "gLItem");
+      }
+    }), //
+    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E"), //
+    QuickCreate("C17951F970E942FD9F3771B7BE91D049"), //
+    HQLDataSource("3C1148C0AB604DE1B51B7EA4112C325F", new HashMap<String, String>() {
+      {
+        // Invocation from Sales Order > Add Payment process > Credit to Use.
+        put("tableId", "58AF4D3E594B421A9A7307480736F03E");
+      }
+    }), //
+    ADTree("90034CAE96E847D78FBEF6D38CB1930D", new HashMap<String, String>() {
+      {
+        // Organization tree view.
+        put("referencedTableId", "155");
+        put("tabId", "143");
+        String selectedPro = "[\"searchKey\",\"name\",\"description\",\"active\",\"summaryLevel\",\"socialName\",\"organizationType\",\"currency\",\"allowPeriodControl\",\"calendar\"]";
+        put("_selectedProperties", selectedPro);
+      }
+    }), //
+    AccountTree("D2F94DC86DEC48D69E4BFCE59DC670CF", new HashMap<String, String>() {
+      {
+        // Account tree > Element value > Open tree view.
+        put("referencedTableId", "188");
+        put("tabId", "132");
+        String selectedPro = "[\"searchKey\",\"name\",\"elementLevel\",\"accountType\",\"showValueCondition\",\"summaryLevel\"]";
+        put("_selectedProperties", selectedPro);
+        put("@FinancialMgmtElement.client@", CLIENT);
+        put("@FinancialMgmtElement.id@", "56E65CF592BD4DAF8A8A879810646266");
+        put("@FinancialMgmtElement.organization@", "B843C30461EA4501935CB1D125C9C25A");
+      }
+    }), //
+    StockReservations("2F5B70D7F12E4F5C8FE20D6F17D69ECF", new HashMap<String, String>() {
+      {
+        // Manage Stock from Stock Reservations
+        put("@MaterialMgmtReservation.id@", ID_TESTING);
+      }
+    }), //
+    QueryList("DD17275427E94026AD721067C3C91C18", new HashMap<String, String>() {
+      {
+        // Query List Widget > Best Sellers
+        put("widgetId", "CD1B06C4ED974B5F905A5A01B097DF4E");
+      }
+    });
+
+    private String ds;
+    private Map<String, String> params;
+
+    private DataSource(String ds) {
+      this.ds = ds;
+      params = new HashMap<String, String>();
+      params.put("_operationType", "fetch");
+      params.put("_startRow", "0");
+      params.put("_endRow", "1");
+    }
+
+    private DataSource(String ds, Map<String, String> extraParams) {
+      this(ds);
+      params.putAll(extraParams);
+    }
+  }
+
+  public DataSourceSecurity(RoleType role, DataSource dataSource, int expectedResponseStatus) {
+    this.role = role;
+    this.dataSource = dataSource;
+    this.expectedResponseStatus = expectedResponseStatus;
+  }
+
+  @Parameters(name = "{0} - dataSource: {1}")
+  public static Collection<Object[]> parameters() {
+    List<Object[]> testCases = new ArrayList<Object[]>();
+    for (RoleType type : RoleType.values()) {
+      int accessForAdminOnly = type == RoleType.ADMIN_ROLE ? JsonConstants.RPCREQUEST_STATUS_SUCCESS
+          : JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR;
+      int accessForAdminAndSystemOnly = type == RoleType.NO_ACCESS_ROLE ? JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR
+          : JsonConstants.RPCREQUEST_STATUS_SUCCESS;
+
+      testCases.add(new Object[] { type, DataSource.Order, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.ManageVariants, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.ProductCharacteristics, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.Combo, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.CustomQuerySelectorDatasource,
+          accessForAdminAndSystemOnly });
+      testCases.add(new Object[] { type, DataSource.CustomQuerySelectorDatasourceProcess,
+          accessForAdminAndSystemOnly });
+
+      // QuickLaunch ds should be always accessible
+      testCases.add(new Object[] { type, DataSource.QuickLaunch,
+          JsonConstants.RPCREQUEST_STATUS_SUCCESS });
+
+      // QuickCreate ds should be always accessible
+      testCases.add(new Object[] { type, DataSource.QuickCreate,
+          JsonConstants.RPCREQUEST_STATUS_SUCCESS });
+      testCases.add(new Object[] { type, DataSource.HQLDataSource, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.ADTree, accessForAdminAndSystemOnly });
+      testCases.add(new Object[] { type, DataSource.AccountTree, accessForAdminOnly });
+      testCases.add(new Object[] { type, DataSource.StockReservations, accessForAdminOnly });
+
+      // QueryList ds is accessible if current role has access to widgetId
+      testCases.add(new Object[] { type, DataSource.QueryList,
+          JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR });
+      testCases.add(new Object[] {
+          type,
+          DataSource.PropertySelector,
+          type == RoleType.SYSTEM_ROLE ? JsonConstants.RPCREQUEST_STATUS_SUCCESS
+              : JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR });
+
+      // Alert ds should be always accessible
+      testCases
+          .add(new Object[] { type, DataSource.Alert, JsonConstants.RPCREQUEST_STATUS_SUCCESS });
+
+      // Note ds is accessible if current role has access to entity of the notes. This note is
+      // invocated from a record in Windows, Tabs and Fields.
+      testCases.add(new Object[] { type, DataSource.Note, accessForAdminAndSystemOnly });
+
+      // Selector into a datasource into a P&E Window.
+      testCases.add(new Object[] { type, DataSource.SelectorGLItemDatasource,
+          accessForAdminAndSystemOnly });
+    }
+    // testing a problem detected in how properties are initialized.
+    testCases.add(new Object[] { RoleType.ADMIN_ROLE, DataSource.ProductByPriceAndWarehouse,
+        JsonConstants.RPCREQUEST_STATUS_SUCCESS });
+
+    return testCases;
+  }
+
+  /** Creates dummy role without any access for testing purposes */
+  @BeforeClass
+  public static void createNoAccessRoleAndGenericProduct() {
+    OBContext.setOBContext(CONTEXT_USER);
+
+    Role noAccessRole = OBProvider.getInstance().get(Role.class);
+    noAccessRole.setId("1");
+    noAccessRole.setNewOBObject(true);
+    noAccessRole.setOrganization(OBDal.getInstance().get(Organization.class, ASTERISK_ORG_ID));
+    noAccessRole.setName("Test No Access");
+    noAccessRole.setManual(true);
+    noAccessRole.setUserLevel(" CO");
+    noAccessRole.setClientList(OBContext.getOBContext().getCurrentClient().getId());
+    noAccessRole.setOrganizationList(ASTERISK_ORG_ID);
+    OBDal.getInstance().save(noAccessRole);
+
+    RoleOrganization noAcessRoleOrg = OBProvider.getInstance().get(RoleOrganization.class);
+    noAcessRoleOrg.setOrganization((Organization) OBDal.getInstance().getProxy(
+        Organization.ENTITY_NAME, ESP_ORG));
+    noAcessRoleOrg.setRole(noAccessRole);
+    OBDal.getInstance().save(noAcessRoleOrg);
+
+    UserRoles noAccessRoleUser = OBProvider.getInstance().get(UserRoles.class);
+    noAccessRoleUser.setOrganization(noAccessRole.getOrganization());
+    noAccessRoleUser.setUserContact(OBContext.getOBContext().getUser());
+    noAccessRoleUser.setRole(noAccessRole);
+    OBDal.getInstance().save(noAccessRoleUser);
+
+    // Create product generic for manage variants
+    Product productToClone = OBDal.getInstance().get(Product.class,
+        "DA7FC1BB3BA44EC48EC1AB9C74168CED");
+    Product product = (Product) DalUtil.copy(productToClone, false);
+    product.setId(ID_TESTING);
+    product.setNewOBObject(true);
+    product.setOrganization(OBDal.getInstance().get(Organization.class, ASTERISK_ORG_ID));
+    product.setName("Generic Product Test");
+    product.setSearchKey("GEN-1 ");
+    product.setClient(OBDal.getInstance().get(Client.class, CLIENT));
+    product.setGeneric(true);
+    OBDal.getInstance().save(product);
+
+    // Preference StockReservations
+    Preference preference = OBProvider.getInstance().get(Preference.class);
+    preference.setId(ID_TESTING);
+    preference.setNewOBObject(true);
+    preference.setClient(OBDal.getInstance().get(Client.class, CLIENT));
+    preference.setOrganization(OBDal.getInstance().get(Organization.class, ESP_ORG));
+    preference.setVisibleAtClient(OBDal.getInstance().get(Client.class, CLIENT));
+    preference.setVisibleAtOrganization(OBDal.getInstance().get(Organization.class, ESP_ORG));
+    preference.setPropertyList(true);
+    preference.setProperty("StockReservations");
+    preference.setSearchKey("Y");
+    OBDal.getInstance().save(preference);
+
+    Reservation reservation = OBProvider.getInstance().get(Reservation.class);
+    reservation.setId(ID_TESTING);
+    reservation.setNewOBObject(true);
+    reservation.setClient(OBDal.getInstance().get(Client.class, CLIENT));
+    reservation.setOrganization(OBDal.getInstance().get(Organization.class, ESP_ORG));
+    reservation.setProduct(OBDal.getInstance().get(Product.class, PROD_RESERVATION));
+    reservation.setQuantity(new BigDecimal(1));
+    reservation.setUOM(OBDal.getInstance().get(UOM.class, "100"));
+    OBDal.getInstance().save(reservation);
+
+    OBDal.getInstance().commitAndClose();
+  }
+
+  /** Tests datasource allows or denies fetch action based on role access */
+  @Test
+  public void fetchShouldBeAllowedOnlyIfRoleIsGranted() throws Exception {
+    OBContext.setOBContext(CONTEXT_USER);
+    changeProfile(role.roleId, LANGUAGE_ID, role.orgId, WAREHOUSE_ID);
+    JSONObject jsonResponse = null;
+    jsonResponse = fetchDataSource();
+    assertThat("Request status", jsonResponse.getInt("status"), is(expectedResponseStatus));
+
+  }
+
+  private JSONObject fetchDataSource() throws Exception {
+    String response = doRequest("/org.openbravo.service.datasource/" + dataSource.ds,
+        dataSource.params, 200, "POST");
+
+    return new JSONObject(response).getJSONObject("response");
+  }
+
+  /** Deletes dummy testing role and product */
+  @AfterClass
+  public static void cleanUp() {
+    OBContext.setOBContext(CONTEXT_USER);
+    OBDal.getInstance().remove(OBDal.getInstance().get(Role.class, ROLE_NO_ACCESS));
+    OBDal.getInstance().remove(OBDal.getInstance().get(Product.class, ID_TESTING));
+    OBDal.getInstance().remove(OBDal.getInstance().get(Preference.class, ID_TESTING));
+    OBDal.getInstance().remove(OBDal.getInstance().get(Reservation.class, ID_TESTING));
+
+    OBDal.getInstance().commitAndClose();
+  }
+}
--- a/src-test/src/org/openbravo/test/datasource/DataSourceWhereParameter.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/DataSourceWhereParameter.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2015 Openbravo SLU 
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -127,6 +127,7 @@
             put("_org", "E443A31992CB4635AFCAEABE7183CE85");
             put("_startRow", "0");
             put("_endRow", "75");
+            put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
           }
         }), //
 
--- a/src-test/src/org/openbravo/test/datasource/ProductSelectorDataSourceTest.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/ProductSelectorDataSourceTest.java	Wed May 04 17:29:34 2016 +0200
@@ -83,6 +83,9 @@
     params.put("_endRow", "75");
     params.put("_textMatchStyle", "substring");
 
+    params.put("targetProperty", "product");
+    params.put("inpTableId", "FF8080812E381D1E012E3898C5DD0010");
+
     if (addFilter) {
       JSONObject filterCriteria = new JSONObject();
       filterCriteria.put("fieldName", "storageBin$warehouse$_identifier");
--- a/src-test/src/org/openbravo/test/datasource/TestAllowUnpagedDatasourcePreference.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/TestAllowUnpagedDatasourcePreference.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2015 Openbravo SLU 
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -63,6 +63,11 @@
   protected Logger logger = Logger.getLogger(this.getClass());
   private String preferenceValue;
 
+  private static final String ROLE_SYSTEM = "0";
+  private static final String ORGANIZATION = "0";
+  private static final String LANGUAGE_ID = "192";
+  private static final String WAREHOUSE_ID = "B2D40D8A5D644DD89E329DC297309055";
+
   /**
    * @param preferenceValue
    *          value to be assigned to the preference
@@ -80,7 +85,7 @@
   }
 
   @Test
-  public void testDatasourceRequest() {
+  public void testDatasourceRequest() throws Exception {
     OBContext.setAdminMode();
     User user = null;
     String defaultClient = null;
@@ -101,6 +106,9 @@
       user.setDefaultRole(OBDal.getInstance().get(Role.class, "0"));
       OBDal.getInstance().commitAndClose();
 
+      // ensures a role with an access to a UOM entity
+      changeProfile(ROLE_SYSTEM, LANGUAGE_ID, ORGANIZATION, WAREHOUSE_ID);
+
       // Create the 'Allow Unpaged Datasource In Manual Request' preference
       preferenceId = createPreference(preferenceValue);
       // Create a manual request to the datasource
--- a/src-test/src/org/openbravo/test/datasource/TestComboDatasource.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/TestComboDatasource.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -154,6 +154,9 @@
   @Test
   public void testFilter() throws Exception {
     setOBContext("100");
+    // Set F&B International Admin role
+    changeProfile("42D0EEB1C66F497A90DD526DC597E6F0", "192", "E443A31992CB4635AFCAEABE7183CE85",
+        "B2D40D8A5D644DD89E329DC297309055");
     // Using values of visible at user in preference
     Map<String, String> params = new HashMap<String, String>();
     params.put("fieldId", "927D156048246E92E040A8C0CF071D3D");
@@ -179,6 +182,9 @@
   @Test
   public void testFilterWithPagination() throws Exception {
     setOBContext("100");
+    // Set F&B International Admin role
+    changeProfile("42D0EEB1C66F497A90DD526DC597E6F0", "192", "E443A31992CB4635AFCAEABE7183CE85",
+        "B2D40D8A5D644DD89E329DC297309055");
     // Using values of visible at user in preference
     Map<String, String> params = new HashMap<String, String>();
     params.put("fieldId", "927D156048246E92E040A8C0CF071D3D");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/security/BypassAccessLevelCheck.java	Wed May 04 17:29:34 2016 +0200
@@ -0,0 +1,93 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C) 2016 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.security;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertThat;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.openbravo.base.exception.OBSecurityException;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBCriteria;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.ad.access.Role;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.test.base.OBBaseTest;
+
+/**
+ * By default access level in entity and role is checked preventing reading data if role's user
+ * level is Organization and the entity trying to be accessed is Client or System. These checks can
+ * be bypassed.
+ * 
+ * @author alostale
+ *
+ */
+public class BypassAccessLevelCheck extends OBBaseTest {
+  private static String ORG_LEVEL_ROLE;
+  private static final String CURRENCY_WINDOW = "115";
+  private static final String SPAIN_ORG = "357947E87C284935AD1D783CF6F099A1";
+
+  @Rule
+  public ExpectedException exception = ExpectedException.none();
+
+  @BeforeClass
+  public static void createOrgLevelRole() {
+    Role role = ExplicitCrossOrganizationReference.createOrgUserLevelRole();
+    ORG_LEVEL_ROLE = role.getId();
+    ExplicitCrossOrganizationReference.grantWindowAccess(role, CURRENCY_WINDOW);
+
+    OBDal.getInstance().commitAndClose();
+  }
+
+  /** By default Org level roles cannot see data in System level entities */
+  @Test
+  public void orgLevelShouldntGrantAccessToSystemEntity() {
+    OBContext.setOBContext("100", ORG_LEVEL_ROLE, QA_TEST_CLIENT_ID, SPAIN_ORG);
+
+    assertThat("doOrgClientAccessCheck", OBContext.getOBContext().doOrgClientAccessCheck(),
+        is(true));
+
+    exception.expect(OBSecurityException.class);
+    exception.expectMessage(containsString("Entity Currency is not readable"));
+
+    OBDal.getInstance().createCriteria(Currency.class);
+  }
+
+  /** Default behavior of for access level check can be bypassed */
+  @Test
+  public void orgLevelCanAccessEntityAccessIfEnabled() {
+    OBContext.setOBContext("100", ORG_LEVEL_ROLE, QA_TEST_CLIENT_ID, SPAIN_ORG);
+    OBContext.getOBContext().setCheckAccessLevel(false);
+    OBCriteria<Currency> q = OBDal.getInstance().createCriteria(Currency.class);
+
+    assertThat("Visible currencies", q.count(), is(greaterThan(0)));
+  }
+
+  @AfterClass
+  public static void cleanUpCreatedObjects() {
+    CrossOrganizationReference.removeCreatedObjects();
+  }
+}
--- a/src-test/src/org/openbravo/test/security/CrossOrganizationReference.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/security/CrossOrganizationReference.java	Wed May 04 17:29:34 2016 +0200
@@ -182,6 +182,7 @@
         OBDal.getInstance().flush();
       }
       OBDal.getInstance().commitAndClose();
+      createdObjects.clear();
     } catch (Exception ignore) {
     } finally {
       OBContext.restorePreviousMode();
--- a/src-test/src/org/openbravo/test/security/ExplicitCrossOrganizationReference.java	Wed May 04 13:23:26 2016 +0200
+++ b/src-test/src/org/openbravo/test/security/ExplicitCrossOrganizationReference.java	Wed May 04 17:29:34 2016 +0200
@@ -31,6 +31,7 @@
 
 import org.apache.log4j.Level;
 import org.codehaus.jettison.json.JSONObject;
+import org.hibernate.criterion.Restrictions;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
@@ -39,13 +40,16 @@
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.dal.core.DalLayerInitializer;
 import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.model.ad.access.Role;
 import org.openbravo.model.ad.access.RoleOrganization;
 import org.openbravo.model.ad.access.User;
 import org.openbravo.model.ad.access.UserRoles;
+import org.openbravo.model.ad.access.WindowAccess;
 import org.openbravo.model.ad.datamodel.Column;
 import org.openbravo.model.ad.module.Module;
+import org.openbravo.model.ad.ui.Window;
 import org.openbravo.model.common.businesspartner.BusinessPartner;
 import org.openbravo.model.common.enterprise.Organization;
 import org.openbravo.model.common.enterprise.Warehouse;
@@ -60,6 +64,7 @@
  *
  */
 public class ExplicitCrossOrganizationReference extends CrossOrganizationReference {
+  private static final String SALES_ORDER_WINDOW = "143";
   private static String QA_ONLY_SPAIN_ROLE;
   private static final String CORE = "0";
   private static final String ORDER_WAREHOUSE_COLUMN = "2202";
@@ -485,7 +490,15 @@
     DalLayerInitializer.getInstance().setInitialized(false);
     setDalUp();
 
-    // crate a role with access only to Spain org
+    Role qaRole = createOrgUserLevelRole();
+    QA_ONLY_SPAIN_ROLE = qaRole.getId();
+    grantWindowAccess(qaRole, SALES_ORDER_WINDOW);
+
+    OBDal.getInstance().commitAndClose();
+  }
+
+  /** Creates a role with Org user level, and access to Spain Org */
+  static Role createOrgUserLevelRole() {
     setQAAdminRole();
     Role spainRole = OBProvider.getInstance().get(Role.class);
     spainRole.setName("QA Only Spain - " + System.currentTimeMillis()); // some randomness
@@ -496,7 +509,6 @@
     spainRole.setUserLevel("  O");
     OBDal.getInstance().save(spainRole);
     createdObjects.add(spainRole);
-    QA_ONLY_SPAIN_ROLE = spainRole.getId();
 
     RoleOrganization orgAccess = OBProvider.getInstance().get(RoleOrganization.class);
     orgAccess.setOrganization(OBDal.getInstance().getProxy(Organization.class, SPAIN_ORG));
@@ -511,7 +523,21 @@
     OBDal.getInstance().save(userRole);
     createdObjects.add(userRole);
 
-    OBDal.getInstance().commitAndClose();
+    return spainRole;
+  }
+
+  static void grantWindowAccess(Role role, String windowId) {
+    WindowAccess windowAccess = OBProvider.getInstance().get(WindowAccess.class);
+    final OBCriteria<Window> obCriteria = OBDal.getInstance().createCriteria(Window.class);
+    obCriteria.add(Restrictions.eq(Window.PROPERTY_ID, windowId));
+    obCriteria.setMaxResults(1);
+    windowAccess.setClient(role.getClient());
+    windowAccess.setOrganization(role.getOrganization());
+    windowAccess.setRole(role);
+    windowAccess.setWindow((Window) obCriteria.uniqueResult());
+    windowAccess.setEditableField(true);
+    OBDal.getInstance().save(windowAccess);
+    createdObjects.add(windowAccess);
   }
 
   @AfterClass
--- a/src/index.jsp	Wed May 04 13:23:26 2016 +0200
+++ b/src/index.jsp	Wed May 04 17:29:34 2016 +0200
@@ -13,6 +13,13 @@
 <%@ page import="org.openbravo.model.ad.access.User" %>
 <%@ page import="org.openbravo.dal.service.OBDal" %>
 <%@ page import="org.openbravo.base.secureApp.VariablesSecureApp" %>
+<%@ page import="org.openbravo.erpCommon.obps.ActivationKey" %>
+<%@ page import="org.openbravo.base.secureApp.LoginHandler" %>
+<%@ page import="org.openbravo.base.HttpBaseUtils" %>
+<%@ page import="org.openbravo.erpCommon.utility.OBMessageUtils" %>
+<%@ page import="org.openbravo.erpCommon.utility.OBError" %>
+<%@ page import="java.util.Date" %>
+<%@ page import="org.openbravo.erpCommon.obps.ActivationKey.LicenseRestriction" %>
 <%@ page contentType="text/html; charset=UTF-8" %>
 <%
   /*
@@ -44,6 +51,41 @@
   return;
 }
 
+OBContext.setAdminMode(false);
+String sessionId = null;
+try {
+  sessionId = (String) session.getAttribute("#AD_SESSION_ID");
+  if (sessionId != null && !"".equals(sessionId) && !"Y".equals(session.getAttribute("forceLogin"))) {
+    org.openbravo.model.ad.access.Session dbSession = OBDal.getInstance().get(org.openbravo.model.ad.access.Session.class, sessionId);
+    String currentSessionType = dbSession.getLoginStatus();
+
+    if (!ActivationKey.consumesConcurrentUser(currentSessionType)) {
+      // session was created not counting concurrent users, now switching to backend so they
+      // should be counted
+      dbSession.setLoginStatus(LoginHandler.SUCCESS_SESSION_STANDARD);
+      OBDal.getInstance().flush();
+
+      if (ActivationKey.getInstance().checkOPSLimitations(sessionId) == LicenseRestriction.NUMBER_OF_CONCURRENT_USERS_REACHED) {
+        dbSession.setSessionActive(false);
+        OBDal.getInstance().flush();
+
+        OBError errMsg = new OBError();
+        errMsg.setTitle(OBMessageUtils.messageBD("NUMBER_OF_CONCURRENT_USERS_REACHED_TITLE", false, true));
+        errMsg.setMessage(OBMessageUtils.messageBD("NUMBER_OF_CONCURRENT_USERS_REACHED", false, true));
+        session.setAttribute("LOGINERRORMSG", errMsg);
+
+        response.sendRedirect(authManager.getLoginURL(request));
+        return;
+      }
+    }
+  }
+} catch (Exception e) {
+  log.error("Error resetting login status for session "  + sessionId,e);
+} finally {
+  OBContext.restorePreviousMode();
+}
+
+
 boolean uncompSC = false;
 String scDevModulePackage = "org.openbravo.userinterface.smartclient.dev";
 OBContext.setAdminMode();
--- a/src/org/openbravo/authentication/AuthenticationManager.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/authentication/AuthenticationManager.java	Wed May 04 17:29:34 2016 +0200
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2001-2013 Openbravo S.L.U.
+ * Copyright (C) 2001-2016 Openbravo S.L.U.
  * Licensed under the Apache Software License version 2.0
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  * Unless required by applicable law or agreed to  in writing,  software  distributed
@@ -12,6 +12,8 @@
 
 package org.openbravo.authentication;
 
+import static org.openbravo.base.secureApp.LoginHandler.SUCCESS_SESSION_STANDARD;
+
 import java.io.IOException;
 import java.io.PrintWriter;
 
@@ -52,7 +54,6 @@
   private static final Logger log4j = Logger.getLogger(AuthenticationManager.class);
   private static final String DEFAULT_AUTH_CLASS = "org.openbravo.authentication.basic.DefaultAuthenticationManager";
 
-  private static final String SUCCESS_SESSION_STANDARD = "S";
   private static final String SUCCESS_SESSION_WEB_SERVICE = "WS";
   private static final String REJECTED_SESSION_WEB_SERVICE = "WSR";
   private static final String SUCCESS_SESSION_CONNECTOR = "WSC";
@@ -151,19 +152,22 @@
       return null;
     }
 
+    if (userId == null && !response.isCommitted()) {
+      response.sendRedirect(getLoginURL(request));
+      return null;
+    }
+
+    return userId;
+  }
+
+  /** Returns the URL that displays the login window (request for user/password) */
+  public String getLoginURL(HttpServletRequest request) {
     // A restricted resource can define a custom login URL
     // It just need to set an the attribute loginURL in the request
     final String customLoginURL = (String) request.getAttribute("loginURL");
 
-    final String loginURL = localAdress
+    return localAdress
         + (customLoginURL == null || "".equals(customLoginURL) ? defaultServletUrl : customLoginURL);
-
-    if (userId == null && !response.isCommitted()) {
-      response.sendRedirect(loginURL);
-      return null;
-    }
-
-    return userId;
   }
 
   /**
--- a/src/org/openbravo/base/model/ModelProvider.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/base/model/ModelProvider.java	Wed May 04 17:29:34 2016 +0200
@@ -894,10 +894,7 @@
    * @throws CheckException
    */
   public Table getTable(String tableName) throws CheckException {
-    if (tablesByTableName == null)
-      getModel();
-    // search case insensitive!
-    final Table table = tablesByTableName.get(tableName.toLowerCase());
+    final Table table = getTableWithoutCheck(tableName);
     if (table == null) {
       if (OBPropertiesProvider.isFriendlyWarnings()) {
         // this error won't be logged...
@@ -911,6 +908,17 @@
   }
 
   /**
+   * Retrieves a table using the tableName. If not found then continue without exception.
+   *
+   * @return Table if exists, otherwise null.
+   */
+  public Table getTableWithoutCheck(String tableName) {
+    if (tablesByTableName == null)
+      getModel();
+    return tablesByTableName.get(tableName.toLowerCase());
+  }
+
+  /**
    * Retrieves an Entity using the entityName. If not found then a CheckException is thrown.
    * 
    * @param entityName
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Wed May 04 17:29:34 2016 +0200
@@ -528,6 +528,10 @@
    * 
    */
   private boolean hasLevelAccess(VariablesSecureApp vars, String accessLevel) {
+    if (!OBContext.getOBContext().doAccessLevelCheck()) {
+      return true;
+    }
+
     final String userLevel = vars.getSessionValue("#User_Level");
 
     boolean retValue = true;
--- a/src/org/openbravo/base/secureApp/LoginHandler.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/base/secureApp/LoginHandler.java	Wed May 04 17:29:34 2016 +0200
@@ -63,6 +63,7 @@
  */
 public class LoginHandler extends HttpBaseServlet {
   private static final long serialVersionUID = 1L;
+  public static final String SUCCESS_SESSION_STANDARD = "S";
 
   @Inject
   private ServerControllerHandler serverController;
@@ -197,7 +198,7 @@
       boolean forceNamedUserLogin = "FORCE_NAMED_USER".equals(vars.getCommand());
 
       LicenseRestriction limitation = ak.checkOPSLimitations(sessionId, username,
-          forceNamedUserLogin);
+          forceNamedUserLogin, getSessionType());
       boolean doRedirect = redirect
           || (limitation == LicenseRestriction.NO_RESTRICTION && forceNamedUserLogin);
 
@@ -395,6 +396,11 @@
 
   }
 
+  /** Returns how the successful session will be marked in ad_session. It can be app specific. */
+  protected String getSessionType() {
+    return SUCCESS_SESSION_STANDARD;
+  }
+
   /**
    * Returns true if the access to the current login handler should be restricted in the store
    * servers
--- a/src/org/openbravo/base/secureApp/LoginUtils.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/base/secureApp/LoginUtils.java	Wed May 04 17:29:34 2016 +0200
@@ -32,6 +32,7 @@
 import org.openbravo.erpCommon.businessUtility.Preferences;
 import org.openbravo.erpCommon.security.SessionLogin;
 import org.openbravo.erpCommon.utility.DimensionDisplayUtility;
+import org.openbravo.erpCommon.utility.PropertyException;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.access.RoleOrganization;
 import org.openbravo.model.ad.domain.Preference;
@@ -209,6 +210,18 @@
       return false;
     }
 
+    boolean shouldCheckAccessLevel = true;
+
+    try {
+      shouldCheckAccessLevel = "N".equals(Preferences.getPreferenceValue(
+          "BypassAccessLevelEntityCheck", true, OBContext.getOBContext().getCurrentClient(),
+          OBContext.getOBContext().getCurrentOrganization(), OBContext.getOBContext().getUser(),
+          OBContext.getOBContext().getRole(), null));
+    } catch (PropertyException prefNotDefined) {
+    }
+
+    OBContext.getOBContext().setCheckAccessLevel(shouldCheckAccessLevel);
+
     // Set session vars
     vars.setSessionValue("#AD_User_ID", strUserAuth);
     vars.setSessionValue("#SalesRep_ID", strUserAuth);
--- a/src/org/openbravo/common/datasource/ResultMapCriteriaUtils.java	Wed May 04 13:23:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,520 +0,0 @@
-package org.openbravo.common.datasource;
-
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Map;
-
-import org.apache.commons.lang.StringUtils;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.openbravo.base.structure.BaseOBObject;
-import org.openbravo.service.json.JsonUtils;
-
-class ResultMapCriteriaUtils {
-  private static final String CRITERIA_KEY = "criteria";
-  private static final String VALUE_KEY = "value";
-  private static final String FIELD_NAME_KEY = "fieldName";
-  private static final String OPERATOR_KEY = "operator";
-
-  private static final String OPERATOR_AND = "and";
-  private static final String OPERATOR_OR = "or";
-
-  private static final String OPERATOR_EQUALS = "equals";
-  private static final String OPERATOR_NOTEQUAL = "notEqual";
-  private static final String OPERATOR_IEQUALS = "iEquals";
-  private static final String OPERATOR_INOTEQUAL = "iNotEqual";
-  private static final String OPERATOR_GREATERTHAN = "greaterThan";
-  private static final String OPERATOR_LESSTHAN = "lessThan";
-  private static final String OPERATOR_GREATEROREQUAL = "greaterOrEqual";
-  private static final String OPERATOR_LESSOREQUAL = "lessOrEqual";
-  private static final String OPERATOR_IGREATERTHAN = "iGreaterThan";
-  private static final String OPERATOR_ILESSTHAN = "iLessThan";
-  private static final String OPERATOR_IGREATEROREQUAL = "iGreaterOrEqual";
-  private static final String OPERATOR_ILESSOREQUAL = "iLessOrEqual";
-  private static final String OPERATOR_CONTAINS = "contains";
-  private static final String OPERATOR_STARTSWITH = "startsWith";
-  private static final String OPERATOR_ENDSWITH = "endsWith";
-  private static final String OPERATOR_ICONTAINS = "iContains";
-  private static final String OPERATOR_ISTARTSWITH = "iStartsWith";
-  private static final String OPERATOR_IENDSWITH = "iEndsWith";
-  private static final String OPERATOR_NOTCONTAINS = "notContains";
-  private static final String OPERATOR_NOTSTARTSWITH = "notStartsWith";
-  private static final String OPERATOR_NOTENDSWITH = "notEndsWith";
-  private static final String OPERATOR_INOTCONTAINS = "iNotContains";
-  private static final String OPERATOR_INOTSTARTSWITH = "iNotStartsWith";
-  private static final String OPERATOR_INOTENDSWITH = "iNotEndsWith";
-  // private static final String OPERATOR_REGEXP = "regexp";
-  // private static final String OPERATOR_IREGEXP = "iregexp";
-  private static final String OPERATOR_ISNULL = "isNull";
-  private static final String OPERATOR_NOTNULL = "notNull";
-  private static final String OPERATOR_INSET = "inSet";
-  private static final String OPERATOR_NOTINSET = "notInSet";
-  private static final String OPERATOR_EQUALSFIELD = "equalsField";
-  private static final String OPERATOR_NOTEQUALFIELD = "notEqualField";
-  private static final String OPERATOR_GREATERTHANFIElD = "greaterThanField";
-  private static final String OPERATOR_LESSTHANFIELD = "lessThanField";
-  private static final String OPERATOR_GREATEROREQUALFIELD = "greaterOrEqualField";
-  private static final String OPERATOR_LESSOREQUALFIElD = "lessOrEqualField";
-  private static final String OPERATOR_CONTAINSFIELD = "containsField";
-  private static final String OPERATOR_STARTSWITHFIELD = "startsWithField";
-  private static final String OPERATOR_ENDSWITHFIELD = "endsWithField";
-  private static final String OPERATOR_NOT = "not";
-  private static final String OPERATOR_BETWEEN = "between";
-  private static final String OPERATOR_BETWEENINCLUSIVE = "betweenInclusive";
-  private static final String OPERATOR_IBETWEEN = "iBetween";
-  private static final String OPERATOR_IBETWEENINCLUSIVE = "iBetweenInclusive";
-  private static final String OPERATOR_EXISTS = "exists";
-
-  Map<String, Object> recordMap;
-  JSONArray criteriaArray;
-  boolean mainOperatorIsAnd;
-
-  private int UTCServerMinutesTimeZoneDiff = 0;
-  private int clientUTCMinutesTimeZoneDiff = 0;
-
-  private SimpleDateFormat simpleDateFormat = JsonUtils.createDateFormat();
-  private SimpleDateFormat simpleDateTimeFormat = JsonUtils.createJSTimeFormat();
-
-  ResultMapCriteriaUtils(Map<String, Object> orderMap, Map<String, String> parameters) {
-    JSONArray _criteriaArray = null;
-    try {
-      _criteriaArray = (JSONArray) JsonUtils.buildCriteria(parameters).get("criteria");
-    } catch (JSONException e) {
-      _criteriaArray = null;
-    }
-    String mainOperator = parameters.get("operator");
-
-    this.recordMap = orderMap;
-    this.criteriaArray = _criteriaArray;
-    this.mainOperatorIsAnd = OPERATOR_AND.equals(mainOperator);
-  }
-
-  boolean applyFilter() throws JSONException {
-    if (criteriaArray == null) {
-      return true;
-    }
-    boolean finalResult = mainOperatorIsAnd;
-    for (int i = 0; i < criteriaArray.length(); i++) {
-      // Each element of the criteria array is added assuming an OR statement.
-      JSONObject criteria = criteriaArray.getJSONObject(i);
-      boolean critResult = parseCriteria(criteria);
-      if (mainOperatorIsAnd) {
-        finalResult &= critResult;
-      } else {
-        finalResult |= critResult;
-      }
-    }
-    return finalResult;
-  }
-
-  private boolean parseCriteria(JSONObject jsonCriteria) throws JSONException {
-    // a constructor so the content is an advanced criteria
-    if (jsonCriteria.has("_constructor") || hasOrAndOperator(jsonCriteria)) {
-      return parseAdvancedCriteria(jsonCriteria);
-    }
-    return parseSingleClause(jsonCriteria);
-  }
-
-  private boolean hasOrAndOperator(JSONObject jsonCriteria) throws JSONException {
-    if (!jsonCriteria.has(OPERATOR_KEY)) {
-      return mainOperatorIsAnd;
-    }
-    return OPERATOR_OR.equals(jsonCriteria.get(OPERATOR_KEY))
-        || OPERATOR_AND.equals(jsonCriteria.get(OPERATOR_KEY));
-  }
-
-  private boolean parseSingleClause(JSONObject jsonCriteria) throws JSONException {
-    String operator = jsonCriteria.getString(OPERATOR_KEY);
-
-    if (operator.equals(OPERATOR_BETWEEN) || operator.equals(OPERATOR_BETWEENINCLUSIVE)
-        || operator.equals(OPERATOR_IBETWEEN) || operator.equals(OPERATOR_IBETWEENINCLUSIVE)) {
-      return parseBetween(jsonCriteria, operator, true);
-    }
-
-    Object value = jsonCriteria.has(VALUE_KEY) ? jsonCriteria.get(VALUE_KEY) : null;
-
-    if (operator.equals(OPERATOR_EXISTS)) {
-      // not supported
-      return mainOperatorIsAnd;
-    }
-
-    String fieldName = jsonCriteria.getString(FIELD_NAME_KEY);
-
-    // translate to a OR for each value
-    if (value instanceof JSONArray) {
-      final JSONArray jsonArray = (JSONArray) value;
-      final JSONObject advancedCriteria = new JSONObject();
-      advancedCriteria.put(OPERATOR_KEY, OPERATOR_OR);
-      final JSONArray subCriteria = new JSONArray();
-      for (int i = 0; i < jsonArray.length(); i++) {
-        final JSONObject subCriterion = new JSONObject();
-        subCriterion.put(OPERATOR_KEY, operator);
-        subCriterion.put(FIELD_NAME_KEY, fieldName);
-        subCriterion.put(VALUE_KEY, jsonArray.get(i));
-        subCriteria.put(i, subCriterion);
-      }
-      advancedCriteria.put(CRITERIA_KEY, subCriteria);
-      return parseAdvancedCriteria(advancedCriteria);
-    }
-
-    // Retrieves the UTC time zone offset of the client
-    if (jsonCriteria.has("minutesTimezoneOffset")) {
-      int clientMinutesTimezoneOffset = Integer.parseInt(jsonCriteria.get("minutesTimezoneOffset")
-          .toString());
-      Calendar now = Calendar.getInstance();
-      // Obtains the UTC time zone offset of the server
-      int serverMinutesTimezoneOffset = (now.get(Calendar.ZONE_OFFSET) + now
-          .get(Calendar.DST_OFFSET)) / (1000 * 60);
-      // Obtains the time zone offset between the server and the client
-      clientUTCMinutesTimeZoneDiff = clientMinutesTimezoneOffset;
-      UTCServerMinutesTimeZoneDiff = serverMinutesTimezoneOffset;
-    }
-
-    if (operator.equals(OPERATOR_ISNULL) || operator.equals(OPERATOR_NOTNULL)) {
-      value = null;
-    }
-
-    // if a comparison is done on an equal date then replace
-    // with a between start time and end time on that date
-    if (operator.equals(OPERATOR_EQUALS) || operator.equals(OPERATOR_EQUALSFIELD)) {
-      Object curValue = recordMap.get(fieldName);
-      if (curValue instanceof Date) {
-        if (operator.equals(OPERATOR_EQUALS)) {
-          return parseSimpleClause(fieldName, OPERATOR_GREATEROREQUAL, value)
-              && parseSimpleClause(fieldName, OPERATOR_LESSOREQUAL, value);
-
-        } else {
-          return parseSimpleClause(fieldName, OPERATOR_GREATEROREQUALFIELD, value)
-              && parseSimpleClause(fieldName, OPERATOR_LESSOREQUALFIElD, value);
-        }
-      }
-    }
-
-    return parseSimpleClause(fieldName, operator, value);
-  }
-
-  private boolean parseBetween(JSONObject jsonCriteria, String operator, boolean inclusive)
-      throws JSONException {
-    final String fieldName = jsonCriteria.getString(FIELD_NAME_KEY);
-    final Object start = jsonCriteria.get("start");
-    final Object end = jsonCriteria.get("end");
-    final boolean leftClause = parseSimpleClause(fieldName, getBetweenOperator(operator, false),
-        start);
-    final boolean rightClause = parseSimpleClause(fieldName, getBetweenOperator(operator, true),
-        end);
-    return leftClause && rightClause;
-  }
-
-  private boolean parseSimpleClause(String fieldName, String operator, Object value)
-      throws JSONException {
-
-    String hqlOperator = getHqlOperator(operator);
-    String strField = fieldName;
-    boolean filterIdentifier = false;
-    // if (strField.endsWith("$_identifier")) {
-    // strField = strField.substring(0, strField.length() - 12);
-    // filterIdentifier = true;
-    // }
-    Object mapValue = recordMap.get(strField);
-    if (operator.equals(OPERATOR_NOTNULL)) {
-      return mapValue != null;
-    } else if (operator.equals(OPERATOR_ISNULL)) {
-      return mapValue == null;
-    }
-
-    Object localValue = value;
-    if (ignoreCase(mapValue, operator)) {
-      localValue = localValue.toString().toUpperCase();
-    }
-
-    boolean returnVal = mainOperatorIsAnd;
-
-    if ("id".equals(strField)) {
-      // ID is always equals
-      returnVal = mapValue != JSONObject.NULL && ((String) localValue).equals(mapValue);
-    } else if (filterIdentifier) {
-      BaseOBObject currentVal = (BaseOBObject) mapValue;
-      String strCurrValIdentifier = currentVal.getIdentifier();
-      String strCurrentFilter = (String) localValue;
-      returnVal = StringUtils.containsIgnoreCase(strCurrValIdentifier, strCurrentFilter);
-    } else if (mapValue instanceof Boolean) {
-      returnVal = (Boolean) mapValue == (Boolean) localValue;
-    } else if (mapValue instanceof BigDecimal) {
-      BigDecimal filterValue = new BigDecimal((Integer) localValue);
-      int compare = filterValue.compareTo((BigDecimal) mapValue);
-      if ("=".equals(hqlOperator)) {
-        returnVal = compare == 0;
-      } else if ("!=".equals(hqlOperator)) {
-        returnVal = compare != 0;
-      } else if (">".equals(hqlOperator)) {
-        returnVal = compare > 0;
-      } else if (">=".equals(hqlOperator)) {
-        returnVal = compare >= 0;
-      } else if ("<".equals(hqlOperator)) {
-        returnVal = compare < 0;
-      } else if ("<=".equals(hqlOperator)) {
-        returnVal = compare <= 0;
-      }
-
-    } else if (mapValue instanceof Date) {
-      try {
-        Date filterValue;
-        try {
-          filterValue = simpleDateTimeFormat.parse(localValue.toString());
-        } catch (ParseException e) {
-          // When a DateTime column is filtered, plan Date values are used
-          // See issue https://issues.openbravo.com/view.php?id=23203
-          filterValue = simpleDateFormat.parse(localValue.toString());
-        }
-        final Calendar calendar = Calendar.getInstance();
-        calendar.setTime(filterValue);
-        // Applies the time zone offset difference of the client
-        calendar.add(Calendar.MINUTE, clientUTCMinutesTimeZoneDiff);
-        // move the date to the beginning of the day
-        if (isGreaterOperator(operator)) {
-          calendar.set(Calendar.HOUR, 0);
-          calendar.set(Calendar.MINUTE, 0);
-          calendar.set(Calendar.SECOND, 0);
-          calendar.set(Calendar.MILLISECOND, 0);
-        } else if (isLesserOperator(operator)) {
-          // move the data to the end of the day
-          calendar.set(Calendar.HOUR, 23);
-          calendar.set(Calendar.MINUTE, 59);
-          calendar.set(Calendar.SECOND, 59);
-          calendar.set(Calendar.MILLISECOND, 999);
-        }
-        // Applies the time zone offset difference of the server
-        calendar.add(Calendar.MINUTE, -UTCServerMinutesTimeZoneDiff);
-        Date mapDate = (Date) mapValue;
-        boolean isBefore = mapDate.before(calendar.getTime());
-        boolean isAfter = mapDate.after(calendar.getTime());
-        boolean sameDate = mapDate.compareTo(calendar.getTime()) == 0;
-        if ("=".equals(hqlOperator)) {
-          returnVal = sameDate;
-        } else if ("!=".equals(hqlOperator)) {
-          returnVal = !sameDate;
-        } else if (">".equals(hqlOperator)) {
-          returnVal = isAfter;
-        } else if (">=".equals(hqlOperator)) {
-          returnVal = isAfter || sameDate;
-        } else if ("<".equals(hqlOperator)) {
-          returnVal = isBefore;
-        } else if ("<=".equals(hqlOperator)) {
-          returnVal = isBefore || sameDate;
-        }
-      } catch (Exception e) {
-        throw new IllegalArgumentException(e);
-      }
-    } else if (mapValue instanceof String) {
-      String strCurrentValue = (String) mapValue;
-      String strCurrentFilter = (String) localValue;
-      returnVal = StringUtils.containsIgnoreCase(strCurrentValue, strCurrentFilter);
-    }
-
-    if (isNot(operator)) {
-      return !returnVal;
-    } else {
-      return returnVal;
-    }
-  }
-
-  private boolean isGreaterOperator(String operator) {
-    return operator != null
-        && (operator.equals(OPERATOR_GREATERTHAN) || operator.equals(OPERATOR_GREATEROREQUAL)
-            || operator.equals(OPERATOR_IGREATERTHAN) || operator.equals(OPERATOR_IGREATEROREQUAL)
-            || operator.equals(OPERATOR_GREATERTHANFIElD) || operator
-              .equals(OPERATOR_GREATEROREQUALFIELD));
-  }
-
-  private boolean isLesserOperator(String operator) {
-    return operator != null
-        && (operator.equals(OPERATOR_LESSTHAN) || operator.equals(OPERATOR_LESSOREQUAL)
-            || operator.equals(OPERATOR_ILESSTHAN) || operator.equals(OPERATOR_ILESSOREQUAL)
-            || operator.equals(OPERATOR_LESSTHANFIELD) || operator
-              .equals(OPERATOR_LESSOREQUALFIElD));
-  }
-
-  private boolean parseAdvancedCriteria(JSONObject advancedCriteria) throws JSONException {
-    final String operator = advancedCriteria.getString(OPERATOR_KEY);
-    if (operator.equals(OPERATOR_NOT)) {
-      final boolean clause = parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY),
-          OPERATOR_OR);
-      return !clause;
-    }
-    if (operator.equals(OPERATOR_AND)) {
-      return parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY), OPERATOR_AND);
-    }
-    if (operator.equals(OPERATOR_OR)) {
-      final boolean value = parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY),
-          OPERATOR_OR);
-      return value;
-    }
-    return parseSingleClause(advancedCriteria);
-  }
-
-  private boolean parseStructuredClause(JSONArray clauses, String hqlOperator) throws JSONException {
-    boolean doOr = OPERATOR_OR.equals(hqlOperator);
-    boolean doAnd = OPERATOR_AND.equals(hqlOperator);
-    for (int i = 0; i < clauses.length(); i++) {
-      final JSONObject clause = clauses.getJSONObject(i);
-      if (clause.has(VALUE_KEY) && clause.get(VALUE_KEY) != null
-          && clause.getString(VALUE_KEY).equals("")) {
-        continue;
-      }
-      final boolean clauseResult = parseCriteria(clause);
-      if (doOr && clauseResult) {
-        return true;
-      }
-      if (doAnd && !clauseResult) {
-        return false;
-      }
-    }
-    if (doOr) {
-      return false;
-    } else if (doAnd) {
-      return true;
-    }
-    return mainOperatorIsAnd;
-  }
-
-  private String getBetweenOperator(String operator, boolean rightClause) {
-    if (operator.equals(OPERATOR_IBETWEEN)) {
-      if (rightClause) {
-        return OPERATOR_ILESSTHAN;
-      } else {
-        return OPERATOR_IGREATERTHAN;
-      }
-    }
-    if (operator.equals(OPERATOR_BETWEEN)) {
-      if (rightClause) {
-        return OPERATOR_LESSTHAN;
-      } else {
-        return OPERATOR_GREATERTHAN;
-      }
-    }
-    if (operator.equals(OPERATOR_IBETWEENINCLUSIVE)) {
-      if (rightClause) {
-        return OPERATOR_ILESSOREQUAL;
-      } else {
-        return OPERATOR_IGREATEROREQUAL;
-      }
-    }
-    if (operator.equals(OPERATOR_BETWEENINCLUSIVE)) {
-      if (rightClause) {
-        return OPERATOR_LESSOREQUAL;
-      } else {
-        return OPERATOR_GREATEROREQUAL;
-      }
-    }
-    throw new IllegalArgumentException("Operator not supported " + operator);
-  }
-
-  private boolean ignoreCase(Object mapValue, String operator) {
-    if (mapValue instanceof BigDecimal || mapValue instanceof Date) {
-      return false;
-    }
-    return operator.equals(OPERATOR_IEQUALS) || operator.equals(OPERATOR_INOTEQUAL)
-        || operator.equals(OPERATOR_CONTAINS) || operator.equals(OPERATOR_ENDSWITH)
-        || operator.equals(OPERATOR_STARTSWITH) || operator.equals(OPERATOR_ICONTAINS)
-        || operator.equals(OPERATOR_INOTSTARTSWITH) || operator.equals(OPERATOR_INOTENDSWITH)
-        || operator.equals(OPERATOR_NOTSTARTSWITH) || operator.equals(OPERATOR_NOTCONTAINS)
-        || operator.equals(OPERATOR_INOTCONTAINS) || operator.equals(OPERATOR_NOTENDSWITH)
-        || operator.equals(OPERATOR_IENDSWITH) || operator.equals(OPERATOR_ISTARTSWITH)
-        || operator.equals(OPERATOR_IBETWEEN) || operator.equals(OPERATOR_IGREATEROREQUAL)
-        || operator.equals(OPERATOR_ILESSOREQUAL) || operator.equals(OPERATOR_IGREATERTHAN)
-        || operator.equals(OPERATOR_ILESSTHAN) || operator.equals(OPERATOR_IBETWEENINCLUSIVE);
-  }
-
-  private boolean isNot(String operator) {
-    return operator.equals(OPERATOR_NOTCONTAINS) || operator.equals(OPERATOR_NOTENDSWITH)
-        || operator.equals(OPERATOR_NOTSTARTSWITH) || operator.equals(OPERATOR_INOTCONTAINS)
-        || operator.equals(OPERATOR_INOTENDSWITH) || operator.equals(OPERATOR_INOTSTARTSWITH)
-        || operator.equals(OPERATOR_NOT) || operator.equals(OPERATOR_NOTINSET);
-  }
-
-  private String getHqlOperator(String operator) {
-    if (operator.equals(OPERATOR_EQUALS)) {
-      return "=";
-    } else if (operator.equals(OPERATOR_INSET)) {
-      return "in";
-    } else if (operator.equals(OPERATOR_NOTINSET)) {
-      return "in";
-    } else if (operator.equals(OPERATOR_NOTEQUAL)) {
-      return "!=";
-    } else if (operator.equals(OPERATOR_IEQUALS)) {
-      return "=";
-    } else if (operator.equals(OPERATOR_INOTEQUAL)) {
-      return "!=";
-    } else if (operator.equals(OPERATOR_GREATERTHAN)) {
-      return ">";
-    } else if (operator.equals(OPERATOR_LESSTHAN)) {
-      return "<";
-    } else if (operator.equals(OPERATOR_GREATEROREQUAL)) {
-      return ">=";
-    } else if (operator.equals(OPERATOR_LESSOREQUAL)) {
-      return "<=";
-    } else if (operator.equals(OPERATOR_IGREATERTHAN)) {
-      return ">";
-    } else if (operator.equals(OPERATOR_ILESSTHAN)) {
-      return "<";
-    } else if (operator.equals(OPERATOR_IGREATEROREQUAL)) {
-      return ">=";
-    } else if (operator.equals(OPERATOR_ILESSOREQUAL)) {
-      return "<=";
-    } else if (operator.equals(OPERATOR_CONTAINS)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_STARTSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_ENDSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_ICONTAINS)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_ISTARTSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_IENDSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_NOTCONTAINS)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_NOTSTARTSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_NOTENDSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_INOTCONTAINS)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_INOTSTARTSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_INOTENDSWITH)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_EQUALSFIELD)) {
-      return "=";
-    } else if (operator.equals(OPERATOR_NOTEQUALFIELD)) {
-      return "!=";
-    } else if (operator.equals(OPERATOR_GREATERTHANFIElD)) {
-      return ">";
-    } else if (operator.equals(OPERATOR_LESSTHANFIELD)) {
-      return "<";
-    } else if (operator.equals(OPERATOR_GREATEROREQUALFIELD)) {
-      return ">=";
-    } else if (operator.equals(OPERATOR_LESSOREQUALFIElD)) {
-      return "<=";
-    } else if (operator.equals(OPERATOR_CONTAINSFIELD)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_STARTSWITHFIELD)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_ENDSWITHFIELD)) {
-      return "like";
-    } else if (operator.equals(OPERATOR_ISNULL)) {
-      return "is";
-    } else if (operator.equals(OPERATOR_NOTNULL)) {
-      return "is not";
-    } else if (operator.equals(OPERATOR_EXISTS)) {
-      return "exists";
-    }
-    // todo throw exception
-    return null;
-  }
-}
--- a/src/org/openbravo/common/datasource/StockReservationPickAndEditDataSource.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/common/datasource/StockReservationPickAndEditDataSource.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -39,6 +39,7 @@
 import org.hibernate.criterion.Criterion;
 import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Restrictions;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.provider.OBProvider;
@@ -97,6 +98,19 @@
     return jsonResult.toString();
   }
 
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    try {
+      Entity entityToCheck = ModelProvider.getInstance().getEntityByTableId(AD_TABLE_ID);
+      if (entityToCheck != null) {
+        obContext.getEntityAccessChecker().checkReadableAccess(entityToCheck);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
+
   private List<JSONObject> fetchJSONObject(Map<String, String> parameters) {
     final int startRow = Integer.parseInt(parameters.get(JsonConstants.STARTROW_PARAMETER));
     final int endRow = Integer.parseInt(parameters.get(JsonConstants.ENDROW_PARAMETER));
--- a/src/org/openbravo/dal/core/OBContext.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/dal/core/OBContext.java	Wed May 04 17:29:34 2016 +0200
@@ -573,6 +573,8 @@
   // check whether using new or old UI
   private boolean newUI = false;
 
+  private boolean checkAccessLevel = true;
+
   public String getUserLevel() {
     return userLevel;
   }
@@ -1111,6 +1113,19 @@
     return !(adminModeSet.get() != null || isAdministrator);
   }
 
+  /**
+   * Defines whether entity check should or not compare entity's access level with role's user level
+   * in order to completely prevent access to that entity.
+   */
+  public boolean doAccessLevelCheck() {
+    return checkAccessLevel;
+  }
+
+  /** @see OBContext#doAccessLevelCheck() */
+  public void setCheckAccessLevel(boolean checkAccessLevel) {
+    this.checkAccessLevel = checkAccessLevel;
+  }
+
   public boolean isAdminContext() {
     return this == adminContext;
   }
--- a/src/org/openbravo/dal/core/OBInterceptor.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/dal/core/OBInterceptor.java	Wed May 04 17:29:34 2016 +0200
@@ -298,8 +298,8 @@
             && bob.getEntity().getProperty(propertyNames[i]).isAllowedCrossOrgReference();
 
         if (!skipCrossOrgCheck
-            && !obContext.getOrganizationStructureProvider(o1.getClient().getId()).isInNaturalTree(
-                o1, o2)) {
+            && !obContext.getOrganizationStructureProvider((String) DalUtil.getId(o1.getClient()))
+                .isInNaturalTree(o1, o2)) {
           throw new OBSecurityException("Entity " + bob.getIdentifier() + " ("
               + bob.getEntityName() + ") with organization " + o1.getIdentifier()
               + " references an entity " + ((BaseOBObject) currentState[i]).getIdentifier()
--- a/src/org/openbravo/dal/security/EntityAccessChecker.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/dal/security/EntityAccessChecker.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2008-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2008-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -31,11 +31,20 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.Table;
 import org.openbravo.base.provider.OBNotSingleton;
+import org.openbravo.client.application.Process;
+import org.openbravo.client.application.ProcessAccess;
+import org.openbravo.client.application.RefWindow;
+import org.openbravo.dal.core.DalUtil;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.core.SessionHandler;
+import org.openbravo.dal.service.OBDal;
 import org.openbravo.model.ad.access.TableAccess;
+import org.openbravo.model.ad.domain.Reference;
 import org.openbravo.model.ad.ui.Tab;
+import org.openbravo.model.ad.ui.Window;
+import org.openbravo.userinterface.selector.Selector;
 
 /**
  * This class is responsible for determining the allowed read/write access for a combination of user
@@ -61,6 +70,9 @@
 public class EntityAccessChecker implements OBNotSingleton {
   private static final Logger log = Logger.getLogger(EntityAccessChecker.class);
 
+  private static final String SELECTOR_REFERENCE = "95E2A8B50A254B2AAE6774B8C2F28120";
+  private static final String WINDOW_REFERENCE = "FF80818132D8F0F30132D9BC395D0038";
+
   // Table Access Level:
   // "6";"System/Client"
   // "1";"Organization"
@@ -84,6 +96,10 @@
   // readable
   // the completely readable entities are present in the readableEntities
   private Set<Entity> derivedReadableEntities = new HashSet<Entity>();
+  // the derived entities from process only contains the entities which are
+  // derived from process definition
+  private Set<Entity> derivedEntitiesFromProcess = new HashSet<Entity>();
+  private Set<String> processes = new HashSet<String>();
   private Set<Entity> nonReadableEntities = new HashSet<Entity>();
   private boolean isInitialized = false;
 
@@ -92,7 +108,8 @@
   /**
    * Reads the windows from the database using the current role of the user. Then it iterates
    * through the windows and tabs to determine which entities are readable/writable for that user.
-   * In addition non-readable and derived-readable entities are computed.
+   * In addition non-readable and derived-readable entities are computed. Besides derived entities
+   * from process definition are being computed too.
    * 
    * @see ModelProvider
    */
@@ -172,6 +189,65 @@
         }
       }
 
+      // and take into account derived entities from process definition
+      // union of writableEntities and readableEntities
+      List<Entity> processEntities = new ArrayList<Entity>(writableEntities);
+      for (final Entity readableEntity : readableEntities) {
+        if (!processEntities.contains(readableEntity)) {
+          processEntities.add(readableEntity);
+        }
+      }
+      if (processEntities.size() > 0) {
+        String inTables = "(";
+        for (final Entity entity : processEntities) {
+          Table table = mp.getTableWithoutCheck(entity.getTableName());
+          if (table == null) {
+            continue;
+          }
+          inTables = inTables + "'" + table.getId() + "',";
+        }
+        inTables = inTables.substring(0, inTables.length() - 1) + ")";
+
+        // take into account processes
+        final String processButStr = "select p.id from ADColumn c inner join c.table t inner join "
+            + "c.oBUIAPPProcess p where t.id in " + inTables;
+        @SuppressWarnings("unchecked")
+        final List<String> processAccessButtons = SessionHandler.getInstance()
+            .createQuery(processButStr).list();
+        for (String processButton : processAccessButtons) {
+          if (!processes.contains(processButton)) {
+            processes.add(processButton);
+            // addEntitiesFromProcess(processButton);
+          }
+        }
+
+        // take into account processes linked with selectors
+        final String processSelStr = "select p.id from ADColumn c inner join c.table t inner join "
+            + "c.referenceSearchKey r inner join r.oBUISELSelectorList s inner join s.processDefintion "
+            + "p  where r.parentReference='" + SELECTOR_REFERENCE + "' and t.id in " + inTables;
+        @SuppressWarnings("unchecked")
+        final List<String> processAccessSelectors = SessionHandler.getInstance()
+            .createQuery(processSelStr).list();
+        for (String processSelector : processAccessSelectors) {
+          if (!processes.contains(processSelector)) {
+            processes.add(processSelector);
+          }
+        }
+      }
+
+      // and take into account explicit process access
+      final String processAccessQryStr = "select p.obuiappProcess.id from "
+          + ProcessAccess.class.getName() + " p where p.role.id='" + getRoleId() + "'";
+      @SuppressWarnings("unchecked")
+      final List<String> processAccessQuery = SessionHandler.getInstance()
+          .createQuery(processAccessQryStr).list();
+      for (final String processAccess : processAccessQuery) {
+        if (!processes.contains(processAccess)) {
+          processes.add(processAccess);
+        }
+      }
+
+      addEntitiesFromProcesses();
       isInitialized = true;
     } finally {
       OBContext.restorePreviousMode();
@@ -190,6 +266,10 @@
    */
   private boolean hasCorrectAccessLevel(String userLevel, int accessLevel) {
     // copied from HttpSecureAppServlet.
+    if (!OBContext.getOBContext().doAccessLevelCheck()) {
+      return true;
+    }
+
     if (accessLevel == 4 && userLevel.indexOf("S") == -1) {
       return false;
     } else if (accessLevel == 1 && userLevel.indexOf("O") == -1) {
@@ -220,6 +300,11 @@
     dumpSorted(derivedReadableEntities);
 
     log.info("");
+    log.info(">>> Derived entities from process: ");
+    log.info("");
+    dumpSorted(derivedEntitiesFromProcess);
+
+    log.info("");
     log.info(">>> Writable entities: ");
     log.info("");
     dumpSorted(writableEntities);
@@ -236,6 +321,13 @@
     log.info("");
     log.info("");
 
+    log.info("");
+    log.info(">>> Processes accessible: ");
+    log.info("");
+    dumpSortedProcess(processes);
+    log.info("");
+    log.info("");
+
   }
 
   private void dumpSorted(Set<Entity> set) {
@@ -249,6 +341,22 @@
     }
   }
 
+  private void dumpSortedProcess(Set<String> set) {
+    final List<String> names = new ArrayList<String>();
+    OBContext.setAdminMode(true);
+    try {
+      for (final String p : set) {
+        names.add(OBDal.getInstance().get(Process.class, p).getName());
+      }
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+    Collections.sort(names);
+    for (final String n : names) {
+      log.info(n);
+    }
+  }
+
   // a special case whereby an identifier property is again a reference to
   // another entity, then this other entity is also derived readable, etc.
   private void addDerivedReadableIdentifierProperties(Entity entity) {
@@ -294,11 +402,7 @@
     if (obContext.isInAdministratorMode()) {
       return true;
     }
-
-    if (!writableEntities.contains(entity)) {
-      return false;
-    }
-    return true;
+    return isWritableWithoutAdminMode(entity);
   }
 
   /**
@@ -345,6 +449,57 @@
     }
   }
 
+  /**
+   * Checks if an entity is readable for current user. It is not take into account admin mode.
+   * 
+   * @param entity
+   *          the entity to check
+   */
+  public void checkReadableAccess(Entity entity) {
+    if (!isReadableWithoutAdminMode(entity)) {
+      throw new OBSecurityException("Entity " + entity + " is not accessible by this role/user: "
+          + obContext.getRole().getName() + "/" + obContext.getUser().getName());
+    }
+  }
+
+  /**
+   * Checks if an entity is derived for current user. It is not take into account admin mode.
+   * 
+   * @param entity
+   *          the entity to check
+   */
+  public void checkDerivedAccess(Entity entity) {
+    if (!isDerivedWithoutAdminMode(entity)) {
+      throw new OBSecurityException("Entity " + entity + " is not accessible by this role/user: "
+          + obContext.getRole().getName() + "/" + obContext.getUser().getName());
+    }
+  }
+
+  /**
+   * Checks if an entity is writable for current user. It is not take into account admin mode.
+   * 
+   * @param entity
+   *          the entity to check
+   */
+  public void checkWritableAccess(Entity entity) {
+    if (!isWritableWithoutAdminMode(entity)) {
+      throw new OBSecurityException("Entity " + entity + " is not writable by this role/user: "
+          + obContext.getRole().getName() + "/" + obContext.getUser().getName());
+    }
+  }
+
+  /**
+   * Checks if a process is accessible for current user. It is not take into account admin mode.
+   */
+  public boolean checkProcessAccess(String processId) {
+    // prevent infinite looping
+    if (!isInitialized) {
+      return false;
+    }
+
+    return processes.contains(processId);
+  }
+
   public String getRoleId() {
     return roleId;
   }
@@ -369,4 +524,167 @@
     return writableEntities;
   }
 
+  public Set<Entity> getDerivedReadableEntities() {
+    return derivedReadableEntities;
+  }
+
+  public Set<Entity> getDerivedEntitiesFromProcess() {
+    return derivedEntitiesFromProcess;
+  }
+
+  private boolean isReadableWithoutAdminMode(Entity entity) {
+    // prevent infinite looping
+    if (!isInitialized) {
+      return false;
+    }
+
+    if (readableEntities.contains(entity)) {
+      return true;
+    }
+
+    return false;
+  }
+
+  private boolean isDerivedWithoutAdminMode(Entity entity) {
+    // prevent infinite looping
+    if (!isInitialized) {
+      return false;
+    }
+
+    if (readableEntities.contains(entity)) {
+      return true;
+    }
+
+    if (derivedReadableEntities.contains(entity)) {
+      return true;
+    }
+
+    if (derivedEntitiesFromProcess.contains(entity)) {
+      return true;
+    }
+
+    return false;
+  }
+
+  private boolean isWritableWithoutAdminMode(Entity entity) {
+    // prevent infinite looping
+    if (!isInitialized) {
+      return false;
+    }
+    return writableEntities.contains(entity);
+  }
+
+  /**
+   * For those processes that are granted, entities used by them through selectors and grids (window
+   * references) need also to be granted
+   */
+  private void addEntitiesFromProcesses() {
+    if (processes.isEmpty()) {
+      return;
+    }
+    String processesInList = createWhereInCondition(processes);
+
+    String hql = "select p.referenceSearchKey from OBUIAPP_Parameter p where p.reference.id in('"
+        + WINDOW_REFERENCE + "','" + SELECTOR_REFERENCE + "') and p.obuiappProcess.id in ("
+        + processesInList + ")";
+    @SuppressWarnings("unchecked")
+    final List<Reference> references = SessionHandler.getInstance().createQuery(hql).list();
+
+    for (Reference ref : references) {
+      addEntitiesFromProcessReference(ref);
+    }
+  }
+
+  private void addEntitiesFromProcessReference(Reference ref) {
+    final ModelProvider mp = ModelProvider.getInstance();
+
+    // RefWindows reference is checked and added to readable and writable entities
+    if (WINDOW_REFERENCE.equals(DalUtil.getId(ref.getParentReference()))) {
+      RefWindow refWindow = !ref.getOBUIAPPRefWindowList().isEmpty() ? ref
+          .getOBUIAPPRefWindowList().get(0) : null;
+      if (refWindow == null) {
+        return;
+      }
+      final Window window = refWindow.getWindow();
+      addEntitiesOfWindowReference(mp, window);
+
+      // Selector reference is checked and added to derivedReadableEntities entities
+    } else if (SELECTOR_REFERENCE.equals(DalUtil.getId(ref.getParentReference()))) {
+      addEntitiesOfSelectorReference(mp, ref);
+    }
+  }
+
+  /**
+   * Obtain entity from selector and added to derivedReadableEntities to take into account as a
+   * derived entity.
+   */
+  private void addEntitiesOfSelectorReference(ModelProvider mp, Reference ref) {
+    for (Selector sel : ref.getOBUISELSelectorList()) {
+      org.openbravo.model.ad.datamodel.Table table = sel.getTable();
+      // Table is not mandatory property of selector
+      if (table == null) {
+        continue;
+      }
+      final Entity derivedEntity = mp.getEntityByTableId((String) DalUtil.getId(table));
+      if (!writableEntities.contains(derivedEntity) && !readableEntities.contains(derivedEntity)
+          && !derivedReadableEntities.contains(derivedEntity)
+          && !nonReadableEntities.contains(derivedEntity)) {
+        derivedEntitiesFromProcess.add(derivedEntity);
+      }
+    }
+  }
+
+  /**
+   * Obtain entities from window and added to readable and writable entities.
+   */
+  private void addEntitiesOfWindowReference(ModelProvider mp, Window window) {
+    Set<String> tabs = new HashSet<String>();
+    for (Tab tab : window.getADTabList()) {
+      tabs.add((String) DalUtil.getId(tab));
+      final Entity derivedEntity = mp.getEntityByTableId((String) DalUtil.getId(tab.getTable()));
+      if (!writableEntities.contains(derivedEntity) && !readableEntities.contains(derivedEntity)
+          && !nonReadableEntities.contains(derivedEntity)) {
+        readableEntities.add(derivedEntity);
+        writableEntities.add(derivedEntity);
+        // Removed from derived entities
+        if (derivedReadableEntities.contains(derivedEntity)) {
+          derivedReadableEntities.remove(derivedEntity);
+        }
+      }
+    }
+    if (tabs.isEmpty()) {
+      return;
+    }
+    String tabInList = createWhereInCondition(tabs);
+    addEntitiesSelectorsFromTabs(mp, tabInList);
+  }
+
+  /**
+   * Obtain selector references in tabs and added to derivedReadableEntities to take into account as
+   * a derived entity.
+   */
+  private void addEntitiesSelectorsFromTabs(ModelProvider mp, String tabs) {
+    String hql = "select r from ADField f inner join f.column c inner join c.referenceSearchKey r  where r.parentReference='"
+        + SELECTOR_REFERENCE + "' and f.tab.id in(" + tabs + ")";
+    @SuppressWarnings("unchecked")
+    final List<Reference> references = SessionHandler.getInstance().createQuery(hql).list();
+    if (!references.isEmpty()) {
+      for (Reference ref : references) {
+        addEntitiesOfSelectorReference(mp, ref);
+      }
+    }
+  }
+
+  private String createWhereInCondition(Set<String> list) {
+    StringBuilder processesInList = new StringBuilder();
+    boolean first = true;
+    for (String p : list) {
+      if (!first) {
+        processesInList.append(", ");
+      }
+      first = false;
+      processesInList.append("'").append(p).append("'");
+    }
+    return processesInList.toString();
+  }
 }
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.html	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.html	Wed May 04 17:29:34 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2011 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -145,6 +145,35 @@
   return true;
 }
 
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText && document.getElementById('inpcAcctSchemaId').value != strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                    refreshComboReports();
+                }
+                else {
+                    refreshComboYears();
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "GeneralAccountingReports.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
 }
 </script>
@@ -173,12 +202,12 @@
 	setTabTableParentElement();
 	enableShortcuts('edition');
 	setBrowserAutoComplete(false);
-	
 	resizeArea();
 	updateMenuIcon('buttonMenu');
 
 	setWindowElementFocus('firstElement');
-       displayLogic();
+	setDefaultLedger();
+	displayLogic();
 }
 
 function onResizeDo(){
@@ -366,7 +395,7 @@
 
                 <tr>
                   <td class="TitleCell"><span class="LabelText">Organization</span></td>
-                  <td class="Combo_ContentCell" colspan="2"> <select name="inpOrganizacion" id="inpOrganizacion" class="ComboKey Combo_TwoCells_width" onchange="refreshComboYears(); logChanges(this); return true;">
+                  <td class="Combo_ContentCell" colspan="2"> <select name="inpOrganizacion" id="inpOrganizacion" class="ComboKey Combo_TwoCells_width" onchange="setDefaultLedger(); logChanges(this); return true;">
                       <option value=""></option><div id="reportC_Org_ID"></div>
                     </select></td>
                 </tr>
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Wed May 04 17:29:34 2016 +0200
@@ -54,6 +54,7 @@
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.erpCommon.utility.WindowTreeData;
@@ -127,8 +128,19 @@
       printPagePDF(request, response, vars, strAgno, strAgnoRef, strDateFrom, strDateTo,
           strDateFromRef, strDateToRef, strAsDateTo, strAsDateToRef, strElementValue,
           strConImporte, strOrg, strLevel, strConCodigo, strcAcctSchemaId, strPageNo);
-    } else
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars
+          .getGlobalVariable("inpOrganizacion", "GeneralAccountingReports|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    }
+
+    else {
       pageError(response);
+    }
   }
 
   private void printPagePDF(HttpServletRequest request, HttpServletResponse response,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.html	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.html	Wed May 04 17:29:34 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2012 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -89,6 +89,32 @@
   return true;
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportGeneralLedger.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdTo', 'inpElementValueIdTo_DES', document.frmMain.inpElementValueIdTo_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdTo_DES", "null");
@@ -123,11 +149,14 @@
     updateMenuIcon('buttonMenu');
 
     setWindowElementFocus('firstElement');
+    setDefaultLedger();
+
   }
 
   function onResizeDo(){
     resizeArea();
   }
+  
 
   function openGeneralLedgerJournal(recordid) {
       
@@ -370,7 +399,7 @@
             </tr>
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
-              <td class="Combo_ContentCell" colspan="2"> <select name="inpOrg" id="inpOrg" class="Combo Combo_TwoCells_width">
+              <td class="Combo_ContentCell" colspan="2"> <select name="inpOrg" id="inpOrg" class="Combo Combo_TwoCells_width" onChange="setDefaultLedger();">
                   <div id="reportAD_ORGID"></div>
                 </select>
               </td>              
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -46,6 +46,7 @@
 import org.openbravo.erpCommon.utility.LimitRowsScrollableFieldProviderFilter;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.xmlEngine.XmlDocument;
@@ -192,16 +193,27 @@
       String strGroupBy = vars
           .getRequestGlobalVariable("inpGroupBy", "ReportGeneralLedger|GroupBy");
       String strPageNo = vars.getGlobalVariable("inpPageNo", "ReportGeneralLedger|PageNo", "1");
-      if (vars.commandIn("PDF"))
+      if (vars.commandIn("PDF")) {
         printPageDataPDF(request, response, vars, strDateFrom, strDateTo, strAmtFrom, strAmtTo,
             strcelementvaluefrom, strcelementvalueto, strOrg, strcBpartnerId, strmProductId,
             strcProjectId, strGroupBy, strcAcctSchemaId, strPageNo, strShowOpenBalances);
-      else
+      } else {
         printPageDataXLS(request, response, vars, strDateFrom, strDateTo, strAmtFrom, strAmtTo,
             strcelementvaluefrom, strcelementvalueto, strOrg, strcBpartnerId, strmProductId,
             strcProjectId, strGroupBy, strcAcctSchemaId, strShowOpenBalances);
-    } else
+      }
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "ReportGeneralLedger|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    }
+
+    else {
       pageError(response);
+    }
   }
 
   private void printPageDataSheet(HttpServletResponse response, VariablesSecureApp vars,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.html	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.html	Wed May 04 17:29:34 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -89,6 +89,33 @@
     return true;
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText && document.getElementById('inpcAcctSchemaId').value != strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                    selectDocument();
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportGeneralLedgerJournal.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdTo', 'inpElementValueIdTo_DES', document.frmMain.inpElementValueIdTo_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdTo_DES", "null");
@@ -289,6 +316,7 @@
         updateMenuIcon('buttonMenu');
 
         setWindowElementFocus('firstElement');
+        setDefaultLedger();
         displayDocumentNo();
         displayAdvancedFilters();
         selectDocument();
@@ -514,7 +542,7 @@
             </tr>
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
-              <td class="Combo_ContentCell" colspan="2"> <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width required Combo_focus" required="true" onchange="selectDocument();">
+              <td class="Combo_ContentCell" colspan="2"> <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width required Combo_focus" required="true" onchange="setDefaultLedger();">
                  <div id="reportAD_ORGID"></div>
                 </select></td>
               <td class="TitleCell"> <span class="LabelText">General Ledger</span></td>
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -55,6 +55,7 @@
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.datamodel.Table;
@@ -268,8 +269,9 @@
           strPageNo, strEntryNo, strShowDescription, strShowRegular, strShowDivideUp, "", "",
           strcelementvaluefrom, strcelementvalueto, strcelementvaluefromdes, strcelementvaluetodes);
     } else if (vars.commandIn("PDF", "XLS")) {
-      if (log4j.isDebugEnabled())
+      if (log4j.isDebugEnabled()) {
         log4j.debug("PDF");
+      }
       String strcAcctSchemaId = vars.getRequestGlobalVariable("inpcAcctSchemaId",
           "ReportGeneralLedger|cAcctSchemaId");
       String strDateFrom = vars.getRequestGlobalVariable("inpDateFrom",
@@ -409,9 +411,16 @@
       PrintWriter out = response.getWriter();
       out.println("objson = " + combobox);
       out.close();
-
-    } else
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "ReportGeneralLedgerJournal|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    } else {
       pageError(response);
+    }
   }
 
   private void printPageDataSheet(HttpServletResponse response, VariablesSecureApp vars,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.html	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.html	Wed May 04 17:29:34 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -87,6 +87,32 @@
     }    
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportTrialBalance.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   displayLogic();
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
@@ -273,6 +299,7 @@
   updateMenuIcon('buttonMenu');
 
   setWindowElementFocus('firstElement');
+  setDefaultLedger();
   displayAdvancedFilters();
 }
 
@@ -550,7 +577,7 @@
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
               <td class="Combo_ContentCell">
-                <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width" required="true">
+                <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width" required="true" onchange="setDefaultLedger();">
                  <div id="reportAD_ORGID"></div>
                 </select></td>
               <td class="TitleCell"/></td>
--- a/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -50,6 +50,7 @@
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.financialmgmt.accounting.coa.AcctSchema;
@@ -211,7 +212,13 @@
       printPageOpen(response, vars, strDateFrom, strDateTo, strOrg, strLevel, strcBpartnerId,
           strmProductId, strcProjectId, strcAcctSchemaId, strGroupBy, strAccountId,
           strNotInitialBalance);
-
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "AgingInquiry|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
     } else {
       pageError(response);
     }
@@ -469,7 +476,7 @@
             Utility.getContext(this, vars, "#User_Client", ""), strcProjectIdAux));
 
     if (data != null && data.length > 0) {
-      if ("Y".equals(strIncludeZeroFigures) &&  "S".equals(strLevel))
+      if ("Y".equals(strIncludeZeroFigures) && "S".equals(strLevel))
         data = includeZeroFigures(data, strcAcctSchemaId, strOrg, strAccountFromValue,
             strAccountToValue);
       xmlDocument.setData("structure1", data);
@@ -663,7 +670,7 @@
             Utility.messageBD(this, "ProcessStatus-W", vars.getLanguage()),
             Utility.messageBD(this, "NoDataFound", vars.getLanguage()));
       } else {
-        if ("Y".equals(strIncludeZeroFigures) &&  "S".equals(strLevel)) {
+        if ("Y".equals(strIncludeZeroFigures) && "S".equals(strLevel)) {
           data = includeZeroFigures(data, strcAcctSchemaId, strOrg, strAccountFromValue,
               strAccountToValue);
         }
--- a/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -25,6 +25,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.secureApp.HttpSecureAppServlet;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.costing.CostingBackground;
@@ -39,6 +40,7 @@
 import org.openbravo.erpCommon.utility.DateTimeData;
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
+import org.openbravo.erpCommon.utility.OBCurrencyUtils;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -63,6 +65,7 @@
 
     // Get user Client's base currency
     String strUserCurrencyId = Utility.stringBaseCurrencyId(this, vars.getClient());
+
     if (vars.commandIn("DEFAULT", "RELATION")) {
       String strDate = vars.getGlobalVariable("inpDate", "ReportValuationStock|Date",
           DateTimeData.today(this));
@@ -70,8 +73,11 @@
           "ReportValuationStock|Warehouse", "");
       String strCategoryProduct = vars.getGlobalVariable("inpCategoryProduct",
           "ReportValuationStock|CategoryProduct", "");
-      String strCurrencyId = vars.getGlobalVariable("inpCurrencyId",
-          "ReportValuationStock|currency", strUserCurrencyId);
+      String strCurrencyId = OBCurrencyUtils.getOrgCurrency(vars.getOrg());
+      if (StringUtils.isEmpty(strCurrencyId)) {
+        strCurrencyId = strUserCurrencyId;
+      }
+
       printPageDataSheet(request, response, vars, strDate, strWarehouse, strCategoryProduct,
           strCurrencyId);
     } else if (vars.commandIn("FIND")) {
--- a/src/org/openbravo/erpCommon/obps/ActivationKey.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/obps/ActivationKey.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -53,6 +53,7 @@
 import javax.crypto.Cipher;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
+import javax.servlet.http.HttpSession;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Appender;
@@ -68,6 +69,7 @@
 import org.openbravo.base.session.OBPropertiesProvider;
 import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.dal.core.DalContextListener;
+import org.openbravo.dal.core.DalUtil;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
@@ -75,6 +77,7 @@
 import org.openbravo.erpCommon.obps.DisabledModules.Artifacts;
 import org.openbravo.erpCommon.obps.ModuleLicenseRestrictions.ActivationMsg;
 import org.openbravo.erpCommon.obps.ModuleLicenseRestrictions.MsgSeverity;
+import org.openbravo.erpCommon.security.SessionListener;
 import org.openbravo.erpCommon.utility.HttpsUtils;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -232,14 +235,14 @@
   private static final String ON_DEMAND_PLATFORM_CHECK_URL = "http://localhost:20290/checkOnDemand?qry=";
 
   /**
-   * Session types that are considered for user concurrency
+   * Session types that are not taken into account for counting concurrent users
    */
   @SuppressWarnings("serial")
-  private static final List<String> ACTIVE_SESSION_TYPES = new ArrayList<String>() {
+  private static final List<String> NO_CU_SESSION_TYPES = new ArrayList<String>() {
     {
-      add("S");
-      add("CUR");
-      add("SUR");
+      add("WS"); // Web service
+      add("WSC"); // Connector
+      add("OBPOS_POS"); // WebPOS
     }
   };
   public static final Long NO_LIMIT = -1L;
@@ -862,7 +865,9 @@
     return new ActivationMsg(severity, customMsg);
   }
 
-  /** gets HTML to be injected in Instance Activation window with additional actions to be performed */
+  /**
+   * gets HTML to be injected in Instance Activation window with additional actions to be performed
+   */
   public String getInstanceActivationExtraActionsHtml(XmlEngine xmlEngine) {
     String html = "";
 
@@ -885,15 +890,24 @@
     return checkOPSLimitations("");
   }
 
+  /** @see ActivationKey#checkOPSLimitations(String, String) */
+  public LicenseRestriction checkOPSLimitations(String currentSession) {
+    return checkOPSLimitations(currentSession, null);
+  }
+
   /**
    * Checks the current activation key
    * 
    * @param currentSession
    *          Current session, not to be taken into account
+   * @param sessionType
+   *          Successful session type: if the session is finally successful this is the type that
+   *          will be marked with in {@code AD_Session}, it is used to determine whether it should
+   *          or not count for CU limitation. In case it is {@code null} it will be counted.
    * 
    * @return {@link LicenseRestriction} with the status of the restrictions
    */
-  public LicenseRestriction checkOPSLimitations(String currentSession) {
+  public LicenseRestriction checkOPSLimitations(String currentSession, String sessionType) {
     LicenseRestriction result = LicenseRestriction.NO_RESTRICTION;
     if (!isOPSInstance()) {
       return LicenseRestriction.NO_RESTRICTION;
@@ -921,7 +935,8 @@
     }
 
     // maxUsers==0 is unlimited concurrent users
-    if (maxUsers != 0) {
+    boolean checkConcurrentUsers = maxUsers != 0 && consumesConcurrentUser(sessionType);
+    if (checkConcurrentUsers) {
       OBContext.setAdminMode();
       int activeSessions = 0;
       try {
@@ -973,14 +988,24 @@
     return result;
   }
 
+  /** Returns whether a session type is counted for concurrent users */
+  public static boolean consumesConcurrentUser(String sessionType) {
+    return sessionType == null || !NO_CU_SESSION_TYPES.contains(sessionType);
+  }
+
   public LicenseRestriction checkOPSLimitations(String currentSession, String username,
       boolean forceNamedUserLogin) {
+    return checkOPSLimitations(currentSession, username, forceNamedUserLogin, null);
+  }
+
+  public LicenseRestriction checkOPSLimitations(String currentSession, String username,
+      boolean forceNamedUserLogin, String sessionType) {
     if (forceNamedUserLogin) {
       // Forcing log in even there are other sessions for same user: disabling the other sessions
       disableOtherSessionsOfUser(currentSession, username);
     }
 
-    LicenseRestriction result = checkOPSLimitations(currentSession);
+    LicenseRestriction result = checkOPSLimitations(currentSession, sessionType);
 
     boolean checkNamedUserLimitation = StringUtils.isNotEmpty(username) && limitNamedUsers;
 
@@ -1060,16 +1085,22 @@
         Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true),
         Restrictions.or(Restrictions.isNull(Session.PROPERTY_LASTPING),
             Restrictions.lt(Session.PROPERTY_LASTPING, lastValidPingTime))));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
-    obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSessionId));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
+
+    if (currentSessionId != null) {
+      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSessionId));
+    }
 
     boolean sessionDeactivated = false;
     for (Session expiredSession : obCriteria.list()) {
-      expiredSession.setSessionActive(false);
-      sessionDeactivated = true;
-      log4j.info("Deactivated session: " + expiredSession.getId()
-          + " beacuse of ping time out. Last ping: " + expiredSession.getLastPing()
-          + ". Last valid ping time: " + lastValidPingTime);
+      if (shouldDeactivateSession(expiredSession, lastValidPingTime)) {
+        expiredSession.setSessionActive(false);
+        sessionDeactivated = true;
+        log4j.info("Deactivated session: " + expiredSession.getId()
+            + " beacuse of ping time out. Last ping: " + expiredSession.getLastPing()
+            + ". Last valid ping time: " + lastValidPingTime);
+      }
     }
     if (sessionDeactivated) {
       OBDal.getInstance().flush();
@@ -1080,12 +1111,29 @@
   }
 
   /**
+   * Do not deactivate those sessions that are not using ping but consume concurrent users (ie.
+   * mobile apps) if activity from them has been recently detected.
+   */
+  private boolean shouldDeactivateSession(Session expiredSession, Date lastValidPingTime) {
+    String sessionId = (String) DalUtil.getId(expiredSession);
+    HttpSession session = SessionListener.getActiveSession(sessionId);
+    if (session == null) {
+      log4j.debug("Session " + sessionId + " not found in context");
+      return true;
+    }
+    Date lastRequestTime = new Date(session.getLastAccessedTime());
+    log4j.debug("Last request received from session " + sessionId + ": " + lastRequestTime);
+    return lastRequestTime.compareTo(lastValidPingTime) < 0;
+  }
+
+  /**
    * Returns the number of current active sessions
    */
   private int getActiveSessions(String currentSession) {
     OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
     obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
 
     if (currentSession != null && !currentSession.equals("")) {
       obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
@@ -1097,7 +1145,8 @@
     OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
     obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
     obCriteria.add(Restrictions.eq(Session.PROPERTY_USERNAME, username));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
     if (currentSession != null && !currentSession.equals("")) {
       obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
     }
--- a/src/org/openbravo/erpCommon/security/SessionListener.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/erpCommon/security/SessionListener.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -21,12 +21,14 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.Vector;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSessionEvent;
 import javax.servlet.http.HttpSessionListener;
 
@@ -34,13 +36,18 @@
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.database.SessionInfo;
 
+/**
+ * Keeps track of active sessions in this context so they can be marked as no active in database
+ * when they are destroyed. Also used to keep last activity info for CU management.
+ */
 public class SessionListener implements HttpSessionListener, ServletContextListener {
 
   private static final int PING_TIMEOUT_SECS = 120;
 
   private static final Logger log = Logger.getLogger(SessionListener.class);
 
-  private static Vector<String> sessionsInContext = new Vector<String>();
+  private static Set<String> sessionsInContext = new HashSet<String>();
+  private static Set<HttpSession> activeHttpSessions = new HashSet<HttpSession>();
   private static ServletContext context = null;
 
   /**
@@ -51,11 +58,16 @@
   @Override
   public void sessionDestroyed(HttpSessionEvent event) {
     log.debug("Destroying session");
-    String sessionId = (String) event.getSession().getAttribute("#AD_SESSION_ID");
+    HttpSession session = event.getSession();
+    String sessionId = (String) session.getAttribute("#AD_SESSION_ID");
     if (sessionId != null) {
       deactivateSession(sessionId);
+    }
+    synchronized (activeHttpSessions) {
+      activeHttpSessions.remove(session);
+    }
 
-    }
+    log.debug("Session destroyed. Active sessions count: " + activeHttpSessions.size());
   }
 
   /**
@@ -87,7 +99,7 @@
    * @param sessionId
    *          db id for the session to keep track
    */
-  public static void addSession(String sessionId) {
+  public static synchronized void addSession(String sessionId) {
     sessionsInContext.add(sessionId);
   }
 
@@ -136,12 +148,36 @@
 
   @Override
   public void sessionCreated(HttpSessionEvent event) {
-    // do nothing
+    synchronized (activeHttpSessions) {
+      activeHttpSessions.add(event.getSession());
+    }
+
+    log.debug("Session created. Active sessions count: " + activeHttpSessions.size());
+  }
+
+  /**
+   * Returns the {@code HttpSession} identified by {@code sessionId} it is present in this context.
+   * If not present {@code null} is returned.
+   */
+  public static HttpSession getActiveSession(String sessionId) {
+    try {
+      for (HttpSession session : activeHttpSessions) {
+        if (sessionId.equals(session.getAttribute("#AD_SESSION_ID"))) {
+          return session;
+        }
+      }
+    } catch (Exception e) {
+      log.error("Error getting active session from context", e);
+      // give up and return null
+    }
+    return null;
   }
 
   private void deactivateSession(String sessionId) {
     try {
-      sessionsInContext.remove(sessionId);
+      synchronized (sessionsInContext) {
+        sessionsInContext.remove(sessionId);
+      }
 
       // Do not use DAL here
       SessionLoginData.deactivate((ConnectionProvider) context.getAttribute("openbravoPool"),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/utility/OBLedgerUtils.java	Wed May 04 17:29:34 2016 +0200
@@ -0,0 +1,114 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2016 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.erpCommon.utility;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.hibernate.Query;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.financialmgmt.accounting.coa.AcctSchema;
+
+/**
+ * Utilities to get AcctSchema
+ */
+public class OBLedgerUtils {
+  private static Logger log4j = Logger.getLogger(OBLedgerUtils.class);
+
+  /**
+   * Returns the ledger id for the given organization id.
+   * 
+   * If the org id is empty, it returns null. If the given organization has no ledger, it tries to
+   * get its legal entity's ledger. If not found, it returns the organization client's ledger
+   * 
+   * @param orgId
+   *          Organization Id whose ledger is needed
+   * 
+   * @return String ledgerId ledger id for the given organization. Null if not found
+   */
+  public static String getOrgLedger(String orgId) {
+    try {
+      OBContext.setAdminMode(true);
+
+      if (StringUtils.isBlank(orgId)) {
+        // No organization
+        return null;
+      }
+      final Organization org = OBDal.getInstance().get(Organization.class, orgId);
+      if (org == null) {
+        // No organization
+        return null;
+      }
+      String acctSchemaId = getOrgLedgerRecursive(orgId);
+      if (!StringUtils.isEmpty(acctSchemaId)) {
+        // Get ledger of organization tree
+        return acctSchemaId;
+      }
+      String clientId = StringUtils.equals(orgId, "0") ? OBContext.getOBContext()
+          .getCurrentClient().getId() : org.getClient().getId();
+      // Get client base Ledger
+      return getClientLedger(clientId);
+
+    } catch (Exception e) {
+      log4j.error("Impossible to get ledger for organization id " + orgId, e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+
+    return null;
+  }
+
+  private static String getOrgLedgerRecursive(String orgId) {
+    try {
+      OBContext.setAdminMode(true);
+      StringBuffer where = new StringBuffer();
+      where.append(" select " + Organization.PROPERTY_GENERALLEDGER + ".id");
+      where.append(" from " + Organization.ENTITY_NAME);
+      where.append(" where ad_isorgincluded(:orgId, " + Organization.PROPERTY_ID + ", "
+          + Organization.PROPERTY_CLIENT + ".id) <> -1");
+      where.append(" and " + Organization.PROPERTY_GENERALLEDGER + " is not null");
+      where.append(" order by ad_isorgincluded(:orgId, " + Organization.PROPERTY_ID + ", "
+          + Organization.PROPERTY_CLIENT + ".id)");
+      Query qry = OBDal.getInstance().getSession().createQuery(where.toString());
+      qry.setParameter("orgId", orgId);
+      qry.setMaxResults(1);
+      return (String) qry.uniqueResult();
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  private static String getClientLedger(String clientId) {
+    try {
+      OBContext.setAdminMode(true);
+      StringBuffer where = new StringBuffer();
+      where.append(" select " + AcctSchema.PROPERTY_ID);
+      where.append(" from " + AcctSchema.ENTITY_NAME);
+      where.append(" where " + AcctSchema.PROPERTY_CLIENT + ".id = :clientId");
+      where.append(" order by " + AcctSchema.PROPERTY_NAME);
+      Query qry = OBDal.getInstance().getSession().createQuery(where.toString());
+      qry.setParameter("clientId", clientId);
+      qry.setMaxResults(1);
+      return (String) qry.uniqueResult();
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+}
--- a/src/org/openbravo/materialmgmt/ManageVariantsDS.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/materialmgmt/ManageVariantsDS.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2013-2014 Openbravo SLU
+ * All portions are Copyright (C) 2013-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  *************************************************************************
@@ -32,6 +32,7 @@
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.criterion.Restrictions;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
@@ -51,6 +52,8 @@
 
 public class ManageVariantsDS extends ReadOnlyDataSourceService {
   private static final int searchKeyLength = getSearchKeyColumnLength();
+  private static final String MANAGE_VARIANTS_TABLE_ID = "147D4D709FAC4AF0B611ABFED328FA12";
+
   private List<String> selectedIds = new ArrayList<String>();
   private HashMap<String, List<CharacteristicValue>> selectedChValues = new HashMap<String, List<CharacteristicValue>>();
   private String nameFilter;
@@ -58,6 +61,18 @@
   private Boolean variantCreated;
 
   @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    Entity entityManageVariants = ModelProvider.getInstance().getEntityByTableId(
+        MANAGE_VARIANTS_TABLE_ID);
+    try {
+      obContext.getEntityAccessChecker().checkReadableAccess(entityManageVariants);
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
+
+  @Override
   protected int getCount(Map<String, String> parameters) {
     return getData(parameters, 0, Integer.MAX_VALUE).size();
   }
--- a/src/org/openbravo/materialmgmt/ProductCharacteristicsDS.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/materialmgmt/ProductCharacteristicsDS.java	Wed May 04 17:29:34 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2013-2015 Openbravo SLU
+ * All portions are Copyright (C) 2013-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  *************************************************************************
@@ -35,6 +35,7 @@
 import org.hibernate.Hibernate;
 import org.hibernate.Query;
 import org.openbravo.base.exception.OBException;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.provider.OBProvider;
@@ -79,6 +80,8 @@
   final static int VAL_NAME = 3;
   final static int VAL_PARENT = 4;
 
+  private static final String PRODUCT_CHARACTERISTICS_TABLE_ID = "8E4A6598CA2747B6B0E7257C6F3DEB19";
+
   @Inject
   private DataSourceServiceProvider dataSourceServiceProvider;
 
@@ -114,6 +117,18 @@
     }
   }
 
+  @Override
+  public void checkFetchDatasourceAccess(Map<String, String> parameter) {
+    final OBContext obContext = OBContext.getOBContext();
+    try {
+      Entity entityToCheck = ModelProvider.getInstance().getEntityByTableId(
+          PRODUCT_CHARACTERISTICS_TABLE_ID);
+      obContext.getEntityAccessChecker().checkReadableAccess(entityToCheck);
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
+    }
+  }
+
   private JSONArray getAllNodes(Map<String, String> parameters, String dsIdentifier,
       String productPath, List<String> allNodes, Set<String> missingNodes, boolean addMissingNodes)
       throws JSONException {
--- a/src/org/openbravo/server/ServerControllerHandler.java	Wed May 04 13:23:26 2016 +0200
+++ b/src/org/openbravo/server/ServerControllerHandler.java	Wed May 04 17:29:34 2016 +0200
@@ -28,8 +28,7 @@
  * in a multi-tiered architecture
  * 
  * It has a default implementation where it is hardcoded that the current server is a central
- * server, but this functionality can be overwritten by extending the
- * AbstractServerControllerImplementation class
+ * server, but this functionality can be overwritten by extending the {@link ServerController} class
  */
 @ApplicationScoped
 public class ServerControllerHandler {
@@ -40,6 +39,9 @@
   // the ServerController that will be used according to its priority
   private ServerController serverControllerImplementation = null;
 
+  /**
+   * @return true if the current server has been configured to be a central server, false otherwise
+   */
   public boolean isThisACentralServer() {
     if (getServerControllerImplementation() != null) {
       return getServerControllerImplementation().isThisACentralServer();
@@ -48,6 +50,9 @@
     }
   }
 
+  /**
+   * @return true if the current server has been configured to be a store server, false otherwise
+   */
   public boolean isThisAStoreServer() {
     if (getServerControllerImplementation() != null) {
       return getServerControllerImplementation().isThisAStoreServer();