Reason for following error is the Lookup info not initialized and cached properly when mobileui is opened prior to zkwebui
Steps to reproduce the following error:
1. After deploying this mobile plugin, restart idempiere server.
2. You should login to mobile first by http://localhost:8080/mobile
3. Go to Business Partner window and select a Business Partner.
4. You will be able to see following name resolution issue due to table lookupinfo cached against system administrator role regardless of your current role.
5. Now you login to zkweb by http://localhost:8080/web.
6. Go to Business Window and select a Business Partner.
5. You will also see the same error in zkwebui as well due to the lookupinfo was wrongly cached from mobile ui.
Lookup info cached at current logged-in client, user and role level. These caches are shared by both zkwebui and mobile ui.
Problem with mobile interface is that it has two Env.context instances for single logged in user (Actually it should be a single env context just like zkwebui) which are:
Env Context Instance 1: #AD_User_ID = 100 (Super User) and #AD_Role_ID = 102 (GardenWorld Admin Role)
Env Context Instance 2: #AD_User_ID = 0 (System User) and #AD_Role_ID = 0 (System Administrator)
While lookupinfo is cached at very first time, accessSQL (role based security conditions) is added from the role instance which was instantiated wrongly from Env Context Instance 2 which has no records selected due to system administrator role regardless of current logged-in role is GardenWorld Admin Role.
Fix for this bug at MRole.java:
public static MRole getDefault (Properties ctx, boolean reload)
{
int AD_Role_ID = Env.getContextAsInt(ctx, "#AD_Role_ID");
int AD_User_ID = Env.getContextAsInt(ctx, "#AD_User_ID");
// if (!Ini.isClient()) // none for Server
// AD_User_ID = 0;
MRole defaultRole = getDefaultRole();
if (reload || defaultRole == null)
{
defaultRole = get (ctx, AD_Role_ID, AD_User_ID, reload);
setDefaultRole(defaultRole);
}
else if ((defaultRole.getAD_Role_ID() != AD_Role_ID
|| defaultRole.getAD_User_ID() != AD_User_ID)
// added by syed to fix context initialization from mobile web
// on 06th June 2016./ more info: https://groups.google.com/forum/#!topic/idempiere/CnoQcimR4HM
&& (AD_Role_ID != 0 || AD_User_ID !=0))
{
defaultRole = get (ctx, AD_Role_ID, AD_User_ID, reload);
setDefaultRole(defaultRole);
}
return defaultRole;
} // getDefault
Above highlighted piece of code by-passes defaultRole initialization if the Role ID and User ID are ZERO. Now lookupinfo initialized for Table, Table Direct & Search reference types properly just like zkweb.
Here is the output after applying above fix:
NOTE:
This fix is not necessary if you are not using mobileui.
In Sales Order window, Payment Rule is not shown as a Dropdown because of its new data type which is Payment
From:sy...@syvasoft.com Sent:June 10, 2016 12:58 Reply-to:idem...@googlegroups.com Subject:[idempiere] Re: Table Direct and Table Reference fields are not working properly in iDempiere Mobile UI (org.idempiere.iuimobile_3.0.2.201505161249.jar) |
/**
* Get Field
* @param lookup lookup
* @param data data
* @return field
*/
public Element getField (Lookup lookup, Object data)
{
m_lookup=lookup;
String dataValue = (data == null) ? "" : data.toString();
//
if (m_displayType == DisplayType.Search
|| m_displayType == DisplayType.Location
|| m_displayType == DisplayType.Account
|| m_displayType == DisplayType.PAttribute)
{
if ( m_readOnly )
{
return getDiv(lookup.getDisplay(data));
}
String dataDisplay = "";
if (lookup != null && data != null)
dataDisplay = lookup.getDisplay(data);
return getPopupField (dataDisplay, dataValue);
}
if (DisplayType.isLookup(m_displayType)
|| m_displayType == DisplayType.Locator
// By Syed on 15th June,2016
// added Payment data type to show as dropdown
|| m_displayType == DisplayType.Payment ) {
if ( m_readOnly )
{
return getDiv(lookup.getDisplay(data));
}
return getSelectField(lookup, dataValue);
}
if (m_displayType == DisplayType.YesNo){
return getCheckField (dataValue);}
if (m_displayType == DisplayType.Button){
return getButtonField ();
}
//Modified by Rob Klein 4/29/07
if (DisplayType.isDate(m_displayType))
{
return getPopupDateField(data);
}
else if (DisplayType.isNumeric(m_displayType)){
return getNumberField(data);
}
if (m_displayType == DisplayType.Text || m_displayType == DisplayType.TextLong){
if ( m_readOnly )
{
return getDiv(dataValue);
}
return getTextField (dataValue, 10);
}
else if (m_displayType == DisplayType.Memo){
if ( m_readOnly )
{
return getDiv(dataValue);
}
return getTextField (dataValue, 10);
}
//other
//if (m_displayType == DisplayType.PAttribute){
// return getPopupField(dataDisplay, dataValue);}
if (m_displayType == DisplayType.Assignment){
return getAssignmentField(data);}
return getStringField(dataValue);
} // getField