IDEMPIERE-177

Complete Window Customization functionality
This commit is contained in:
Dirk Niemeyer 2012-04-04 11:29:44 -05:00
parent f319ae4266
commit 211d2f67b0
8 changed files with 600 additions and 1 deletions

View File

@ -0,0 +1,137 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2012 Dirk Niemeyer *
* Copyright (C) 2012 action 42 GmbH *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.model;
import java.util.Properties;
import org.adempiere.model.GridTabWrapper;
import org.compiere.util.Env;
/**
* Window Customization Callout
*
* @author Dirk Niemeyer, action42 GmbH
*/
public class CalloutWindowCustomization extends CalloutEngine
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Set fields to current values from DB for selected window.
* @param ctx context
* @param WindowNo window no
* @param mTab tab
* @param mField field
* @param value value
* @return null or error message
*/
public String window (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{
Integer AD_Window_ID = (Integer)value;
if (AD_Window_ID == null || AD_Window_ID.intValue() == 0)
return "";
I_AD_UserDef_Win ud_win = GridTabWrapper.create(mTab, I_AD_UserDef_Win.class);
MWindow window = new MWindow(Env.getCtx(),AD_Window_ID, null);
String lang = (String)mTab.getValue("AD_Language");
ud_win.setName(window.get_Translation("Name", lang));
ud_win.setDescription(window.get_Translation("Description", lang));
ud_win.setHelp(window.get_Translation("Help", lang));
// XXX what for?
ud_win.setIsDefault(window.isDefault());
// default from menu, actual from role
// XXX Read Only
// XXX User updateable
return NO_ERROR;
} // storeAttachmentOnFilesystem
/**
* Set fields to current values from DB for selected Tab
* @param ctx context
* @param WindowNo window no
* @param mTab tab
* @param mField field
* @param value value
* @return null or error message
*/
public String tab (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{
Integer p_AD_Tab_ID = (Integer)value;
if (p_AD_Tab_ID == null || p_AD_Tab_ID.intValue() == 0)
return "";
I_AD_UserDef_Tab ud_tab = GridTabWrapper.create(mTab, I_AD_UserDef_Tab.class);
MTab tab = new MTab(Env.getCtx(),p_AD_Tab_ID, null);
String lang = Env.getContext(ctx, WindowNo, "AD_Language");
ud_tab.setName(tab.get_Translation("Name", lang));
ud_tab.setDescription(tab.get_Translation("Description", lang));
ud_tab.setHelp(tab.get_Translation("Help", lang));
ud_tab.setIsSingleRow(tab.isSingleRow());
ud_tab.setIsReadOnly(tab.isReadOnly());
return NO_ERROR;
} // storeArchiveOnFileSystem
/**
* Set fields to current values from DB for selected Tab
* @param ctx context
* @param WindowNo window no
* @param mTab tab
* @param mField field
* @param value value
* @return null or error message
*/
public String field (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{
Integer p_AD_Field_ID = (Integer)value;
if (p_AD_Field_ID == null || p_AD_Field_ID.intValue() == 0)
return "";
I_AD_UserDef_Field ud_field = GridTabWrapper.create(mTab, I_AD_UserDef_Field.class);
MField field = new MField(Env.getCtx(),p_AD_Field_ID, null);
String lang = Env.getContext(ctx, WindowNo, "AD_Language");
ud_field.setName(field.get_Translation("Name", lang));
ud_field.setDescription(field.get_Translation("Description", lang));
ud_field.setHelp(field.get_Translation("Help", lang));
ud_field.setIsDisplayed(field.isDisplayed());
ud_field.setDisplayLength(field.getDisplayLength());
ud_field.setDisplayLogic(field.getDisplayLogic());
ud_field.setIsReadOnly(field.isReadOnly());
// XXX from column? set to true for starters
ud_field.setIsUpdateable(true);
ud_field.setSeqNo(field.getSeqNo());
ud_field.setIsSameLine(field.isSameLine());
ud_field.setSortNo(field.getSortNo().intValue());
return NO_ERROR;
} // storeArchiveOnFileSystem
} // CalloutClient

View File

@ -203,6 +203,36 @@ public class GridFieldVO implements Serializable
if (! client.isDisplayField(AD_Field_ID))
vo.IsDisplayed = false;
}
// FR IDEMPIERE-177
// Field Customization
if (vo.IsDisplayed) {
MUserDefField userDef = null;
userDef = MUserDefField.get(vo.ctx,AD_Field_ID, AD_Tab_ID, AD_Window_ID);
if (userDef != null)
{
vo.IsDisplayed = userDef.isDisplayed();
if (userDef.getName() != null)
vo.Header = userDef.getName();
if (userDef.getDescription() != null)
vo.Description = userDef.getDescription();
if (userDef.getHelp() != null)
vo.Help = userDef.getHelp();
vo.IsReadOnly = userDef.isReadOnly();
vo.IsSameLine = userDef.isSameLine();
vo.IsUpdateable = userDef.isUpdateable();
if (userDef.getDisplayLength() > 0)
vo.DisplayLength = userDef.getDisplayLength();
if (userDef.getDisplayLogic() != null)
vo.DisplayLogic = userDef.getDisplayLogic();
if (userDef.getDefaultValue() != null)
vo.DefaultValue = userDef.getDefaultValue();
if (userDef.getSortNo() > 0)
vo.SortNo = userDef.getSortNo();
// ToDo SeqNo
//if (userDef.getSeqNo() > 0)
// vo.SeqNo = userDef.getSeqNo();
}
}
//
vo.initFinish();
return vo;

View File

@ -101,7 +101,11 @@ public class GridTabVO implements Evaluatee, Serializable
{
vo.AD_Tab_ID = rs.getInt("AD_Tab_ID");
Env.setContext(vo.ctx, vo.WindowNo, vo.TabNo, GridTab.CTX_AD_Tab_ID, String.valueOf(vo.AD_Tab_ID));
// FR IDEMPIERE-177
MUserDefTab userDef = MUserDefTab.get(vo.ctx, vo.AD_Tab_ID, vo.AD_Window_ID);
vo.Name = rs.getString("Name");
if (userDef != null)
vo.Name = userDef.getName();
Env.setContext(vo.ctx, vo.WindowNo, vo.TabNo, GridTab.CTX_Name, vo.Name);
// Translation Tab **
@ -159,7 +163,12 @@ public class GridTabVO implements Evaluatee, Serializable
}
if (rs.getString("IsReadOnly").equals("Y"))
vo.IsReadOnly = true;
if (userDef != null)
vo.IsReadOnly = userDef.isReadOnly();
vo.ReadOnlyLogic = rs.getString("ReadOnlyLogic");
if (userDef != null)
vo.ReadOnlyLogic = userDef.get_ValueAsString("ReadOnlyLogic");
if (rs.getString("IsInsertRecord").equals("N"))
vo.IsInsertRecord = false;
@ -167,12 +176,20 @@ public class GridTabVO implements Evaluatee, Serializable
vo.Description = rs.getString("Description");
if (vo.Description == null)
vo.Description = "";
if (userDef != null && userDef.getDescription() != null)
vo.Description = userDef.getDescription();
vo.Help = rs.getString("Help");
if (vo.Help == null)
vo.Help = "";
if (userDef != null && userDef.getHelp() != null)
vo.Help = userDef.getHelp();
if (rs.getString("IsSingleRow").equals("Y"))
vo.IsSingleRow = true;
if (userDef != null)
vo.IsSingleRow = userDef.isSingleRow();
if (rs.getString("HasTree").equals("Y"))
vo.HasTree = true;

View File

@ -183,6 +183,20 @@ public class GridWindowVO implements Serializable
return null;
}
// FR IDEMPIERE-177
// User Customization
MUserDefWin userDef = MUserDefWin.getBestMatch(ctx, AD_Window_ID);
if (userDef != null)
{
if (userDef.getName() != null)
vo.Name = userDef.getName();
if (userDef.getDescription() != null)
vo.Description = userDef.getDescription();
if (userDef.getHelp() != null)
vo.Help = userDef.getHelp();
// ToDo userDef.isDefault, userDef.isReadOnly, userDef.isUserUpdateable
}
// Create Tabs
createTabs (vo);
if (vo.Tabs == null || vo.Tabs.size() == 0)

View File

@ -509,7 +509,20 @@ public class MTree extends MTree_Base
MRole role = MRole.getDefault(getCtx(), false);
Boolean access = null;
if (X_AD_Menu.ACTION_Window.equals(actionColor))
access = role.getWindowAccess(AD_Window_ID);
{
access = role.getWindowAccess(AD_Window_ID);
// FR XXX
// Get Window Customization
MUserDefWin userDef = null;
userDef = MUserDefWin.getBestMatch(getCtx(), AD_Window_ID);
if (userDef != null)
{
if (userDef.getName() != null)
name = userDef.getName();
if (userDef.getDescription() != null)
description = userDef.getDescription();
}
}
else if (X_AD_Menu.ACTION_Process.equals(actionColor)
|| X_AD_Menu.ACTION_Report.equals(actionColor))
access = role.getProcessAccess(AD_Process_ID);

View File

@ -0,0 +1,113 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2012 Dirk Niemeyer *
* Copyright (C) 2012 action 42 GmbH *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.model;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
/**
*
* @author Dirk Niemeyer, action42 GmbH
* @version $Id$
*/
public class MUserDefField extends X_AD_UserDef_Field
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Standard constructor.
* You must implement this constructor for Adempiere Persistency
* @param ctx context
* @param ID the primary key ID
* @param trxName transaction
*/
public MUserDefField (Properties ctx, int ID, String trxName)
{
super (ctx, ID, trxName);
} // MyModelExample
/**
* Optional Load Constructor.
* You would use this constructor to load several business objects.
* <code>
* SELECT * FROM MyModelExample WHERE ...
* </code>
* @param ctx context
* @param rs result set
* @param trxName transaction
*/
public MUserDefField (Properties ctx, ResultSet rs, String trxName)
{
super (ctx, rs, trxName);
} // MyModelExample
public static MUserDefField get (Properties ctx, int AD_Field_ID, int AD_Tab_ID, int AD_Window_ID )
{
MUserDefWin userdefWin = MUserDefWin.getBestMatch(ctx, AD_Window_ID);
if (userdefWin == null)
return null;
MUserDefTab userdefTab = MUserDefTab.getMatch(ctx, AD_Tab_ID, userdefWin.getAD_UserDef_Win_ID());
if (userdefTab == null)
return null;
MUserDefField retValue = null;
StringBuffer sql = new StringBuffer("SELECT * "
+ " FROM AD_UserDef_Field f "
+ " WHERE f.AD_Field_ID=? AND f.IsActive='Y' "
+ " AND f.AD_UserDef_Tab_ID=? ");
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
// create statement
pstmt = DB.prepareStatement(sql.toString(), null);
pstmt.setInt(1, AD_Field_ID);
pstmt.setInt(2, userdefTab.getAD_UserDef_Tab_ID());
// get data
rs = pstmt.executeQuery();
if (rs.next())
{
retValue = new MUserDefField(ctx,rs,null);
}
}
catch (SQLException ex)
{
CLogger.get().log(Level.SEVERE, sql.toString(), ex);
return null;
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
return retValue;
}
} // MyModelExample

View File

@ -0,0 +1,115 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2012 Dirk Niemeyer *
* Copyright (C) 2012 action 42 GmbH *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.model;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
/**
*
* @author Dirk Niemeyer, action 42 GmbH
* @version $Id$
*/
public class MUserDefTab extends X_AD_UserDef_Tab
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Standard constructor.
* You must implement this constructor for Adempiere Persistency
* @param ctx context
* @param ID the primary key ID
* @param trxName transaction
*/
public MUserDefTab (Properties ctx, int ID, String trxName)
{
super (ctx, ID, trxName);
} // MyModelExample
/**
* Optional Load Constructor.
* You would use this constructor to load several business objects.
* <code>
* SELECT * FROM MyModelExample WHERE ...
* </code>
* @param ctx context
* @param rs result set
* @param trxName transaction
*/
public MUserDefTab (Properties ctx, ResultSet rs, String trxName)
{
super (ctx, rs, trxName);
} // MyModelExample
public static MUserDefTab getMatch (Properties ctx, int AD_Tab_ID, int AD_UserDefWin_ID )
{
MUserDefTab retValue = null;
StringBuffer sql = new StringBuffer("SELECT * "
+ " FROM AD_UserDef_Tab "
+ " WHERE AD_UserDef_Win_ID=? AND IsActive='Y' "
+ " AND AD_Tab_ID=? ");
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
// create statement
pstmt = DB.prepareStatement(sql.toString(), null);
pstmt.setInt(1, AD_UserDefWin_ID);
pstmt.setInt(2, AD_Tab_ID);
// get data
rs = pstmt.executeQuery();
if (rs.next())
{
retValue = new MUserDefTab(ctx,rs,null);
}
}
catch (SQLException ex)
{
CLogger.get().log(Level.SEVERE, sql.toString(), ex);
return null;
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
return retValue;
}
public static MUserDefTab get (Properties ctx, int AD_Tab_ID, int AD_Window_ID) {
MUserDefWin userdefWin = MUserDefWin.getBestMatch(ctx, AD_Window_ID);
if (userdefWin == null)
return null;
return getMatch(ctx, AD_Tab_ID, userdefWin.getAD_UserDef_Win_ID());
}
} // MyModelExample

View File

@ -0,0 +1,160 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2012 Dirk Niemeyer *
* Copyright (C) 2012 action 42 GmbH *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.model;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
/**
*
* @author Dirk Niemeyer, action42 GmbH
* @version $Id$
*/
public class MUserDefWin extends X_AD_UserDef_Win
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Standard constructor.
* You must implement this constructor for Adempiere Persistency
* @param ctx context
* @param ID the primary key ID
* @param trxName transaction
*/
public MUserDefWin (Properties ctx, int ID, String trxName)
{
super (ctx, ID, trxName);
} // MyModelExample
/**
* Optional Load Constructor.
* You would use this constructor to load several business objects.
* <code>
* SELECT * FROM MyModelExample WHERE ...
* </code>
* @param ctx context
* @param rs result set
* @param trxName transaction
*/
public MUserDefWin (Properties ctx, ResultSet rs, String trxName)
{
super (ctx, rs, trxName);
} // MyModelExample
private static MUserDefWin[] getAll (Properties ctx, int window_ID )
{
List<MUserDefWin> list = new ArrayList<MUserDefWin>();
StringBuffer sql = new StringBuffer("SELECT * "
+ " FROM AD_UserDef_Win w "
+ " WHERE w.AD_Window_ID=? AND w.IsActive='Y' "
+ " AND w.AD_Language=? "
+ " AND w.AD_Client_ID=? ");
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
// create statement
pstmt = DB.prepareStatement(sql.toString(), null);
pstmt.setInt(1, window_ID);
pstmt.setString(2, Env.getAD_Language(ctx));
pstmt.setInt(3, Env.getAD_Client_ID(ctx));
// get data
rs = pstmt.executeQuery();
while (rs.next())
{
MUserDefWin userDef = new MUserDefWin(Env.getCtx(),rs,null);
list.add(userDef);
}
}
catch (SQLException ex)
{
CLogger.get().log(Level.SEVERE, sql.toString(), ex);
return null;
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
if (list.size() == 0)
return null;
return list.toArray(new MUserDefWin[list.size()]);
}
public static MUserDefWin getBestMatch (Properties ctx, int window_ID)
{
// parameters
final int AD_Org_ID = Env.getAD_Org_ID(ctx);
//final int anyOrg = 0;
final int AD_Role_ID = Env.getAD_Role_ID(ctx);
//final String anyRole = "NULL";
final int AD_User_ID = Env.getAD_User_ID(ctx);
//final String anyUser = "NULL";
// candidates
MUserDefWin[] candidates = getAll(ctx, window_ID);
if (candidates == null)
return null;
final int size = candidates.length;
int[] weight = new int[size];
// this user + this role + this org => weight = 7
// this user + this role + any org => weight = 6
// this user + any role + this org => weight = 5
// this user + any role + any org => weight = 4
// any user + this role + this org => weight = 3
// any user + this role + any org => weight = 2
// any user + any role + this org => weight = 1
// any user + any role + any org => weight = 0
for (int i=0; i < size; i++)
{
weight[i] = 0;
if (candidates[i].getAD_User_ID() == AD_User_ID)
weight[i] = weight[i] + 4;
if (candidates[i].getAD_Role_ID() == AD_Role_ID)
weight[i] = weight[i] + 2;
if (candidates[i].getAD_Org_ID() == AD_Org_ID)
weight[i] = weight[i] + 1;
// others are implicit
}
int maximum = weight[0]; // start with the first value
int maxindex = 0;
for (int j=0; j<weight.length; j++) {
if (weight[j] > maximum) {
maximum = weight[j]; // new maximum
maxindex = j;
}
}
return candidates[maxindex];
}
} // MUserDefWin