[RM] Merge changes from pi-pne branch
authorIván Perdomo <ivan.perdomo@openbravo.com>
Tue, 22 Nov 2011 16:26:12 +0100
changeset 14691 b2e542a8e480
parent 14680 948297002882 (current diff)
parent 14690 22cd3a38b012 (diff)
child 14694 6e2e025bea3a
[RM] Merge changes from pi-pne branch
modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationComponentProvider.java
src-db/database/sourcedata/AD_COLUMN.xml
src-db/database/sourcedata/AD_ELEMENT.xml
src-db/database/sourcedata/AD_FIELD.xml
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationComponentProvider.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationComponentProvider.java	Tue Nov 22 16:26:12 2011 +0100
@@ -92,6 +92,8 @@
     globalResources.add(createStaticResource(
         "web/org.openbravo.client.application/js/form/ob-form-button.js", true));
     globalResources.add(createStaticResource(
+        "web/org.openbravo.client.application/js/form/formitem/ob-formitem-canvas.js", true));
+    globalResources.add(createStaticResource(
         "web/org.openbravo.client.application/js/form/formitem/ob-formitem-checkbox.js", true));
     globalResources.add(createStaticResource(
         "web/org.openbravo.client.application/js/form/formitem/ob-formitem-datechooser.js", true));
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationConstants.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationConstants.java	Tue Nov 22 16:26:12 2011 +0100
@@ -54,6 +54,9 @@
   // Identifier of the key holding the selected rows in a grid
   public static final String SELECTION_PROPERTY = "_selection";
 
+  // Identifier of the parameter key holding all rows in the grid
+  public static final String ALL_ROWS_PARAM = "_allRows";
+
   // Identifier of the key holding the value of the button clicked
   public static final String BUTTON_VALUE = "_buttonValue";
 
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationUtils.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/ApplicationUtils.java	Tue Nov 22 16:26:12 2011 +0100
@@ -216,6 +216,9 @@
    * @return true in case it is button, false if not
    */
   public static boolean isUIButton(Field field) {
+    if (field.getColumn() == null) {
+      return false;
+    }
     return "28".equals(field.getColumn().getReference().getId());
   }
 }
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/DynamicExpressionParser.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/DynamicExpressionParser.java	Tue Nov 22 16:26:12 2011 +0100
@@ -197,6 +197,9 @@
     ApplicationDictionaryCachedStructures cachedStructures = WeldUtils
         .getInstanceFromStaticBeanManager(ApplicationDictionaryCachedStructures.class);
     for (Field field : cachedStructures.getFieldsOfTab(tab.getId())) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       if (token.equalsIgnoreCase(field.getColumn().getDBColumnName())) {
         fieldsInExpression.add(field);
         final String fieldName = KernelUtils.getInstance().getPropertyFromColumn(field.getColumn())
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-field.js.ftl	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-field.js.ftl	Tue Nov 22 16:26:12 2011 +0100
@@ -68,6 +68,9 @@
 </@compress>
     <#if field.standardField>
 <@compress single_line=true>
+        <#if field.clientClass != ''>
+            clientClass: '${field.clientClass?string}',
+        </#if>
         <#if field.columnName != ''>
             columnName: '${field.columnName?string}',
         </#if>
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-personalization-form.js.ftl	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-personalization-form.js.ftl	Tue Nov 22 16:26:12 2011 +0100
@@ -25,6 +25,9 @@
         name: '${field.name?js_string}',
         title: '${field.label?js_string}',
         type: '${field.type}',
+        <#if field.type = "text">
+            editorType: 'OBTextItem',
+        </#if>
         colSpan: ${field.colSpan},
         rowSpan: ${field.rowSpan},
         startRow: ${field.startRow?string},
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/ApplicationDictionaryCachedStructures.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/ApplicationDictionaryCachedStructures.java	Tue Nov 22 16:26:12 2011 +0100
@@ -74,6 +74,9 @@
     Tab tab = OBDal.getInstance().get(Tab.class, tabId);
     List<Field> fields = tab.getADFieldList();
     for (Field f : fields) {
+      if (f.getColumn() == null) {
+        continue;
+      }
       Hibernate.initialize(f.getColumn());
       initializeColumn(f.getColumn());
     }
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java	Tue Nov 22 16:26:12 2011 +0100
@@ -342,6 +342,10 @@
       if (mode.equals("NEW") || mode.equals("EDIT") || mode.equals("CHANGE")) {
         JSONObject jsonColumnValues = new JSONObject();
         for (Field field : getADFieldList(tab.getId())) {
+          if (field.getColumn() == null) {
+            continue;
+          }
+
           jsonColumnValues.put(
               field.getColumn().getDBColumnName(),
               columnValues.get("inp"
@@ -362,6 +366,9 @@
 
         final Map<String, String> sessionAttributesMap = new HashMap<String, String>();
         for (Field field : getADFieldList(tab.getId())) {
+          if (field.getColumn() == null) {
+            continue;
+          }
           if (field.getColumn().getCallout() != null) {
             final String columnName = "inp"
                 + Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName());
@@ -446,6 +453,9 @@
     }
     HashMap<String, Field> columnsOfFields = new HashMap<String, Field>();
     for (Field field : getADFieldList(tab.getId())) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       columnsOfFields.put(field.getColumn().getDBColumnName(), field);
     }
     List<String> changedCols = new ArrayList<String>();
@@ -570,6 +580,9 @@
     }
 
     for (Field field : getADFieldList(tab.getId())) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       String columnId = field.getColumn().getId();
       UIDefinition uiDef = UIDefinitionController.getInstance().getUIDefinition(columnId);
       // We need to fire callouts if the field is a combo
@@ -622,6 +635,9 @@
     }
     HashMap<String, Field> columnsOfFields = new HashMap<String, Field>();
     for (Field field : getADFieldList(tab.getId())) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       for (String col : columnsToComputeAgain) {
         if (col.equalsIgnoreCase(field.getColumn().getDBColumnName())) {
           columnsOfFields.put(col, field);
@@ -708,6 +724,9 @@
     if (mode.equals("EDIT")) {
       // In EDIT mode we initialize them from the database
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         setValueOfColumnInRequest(row, field.getColumn().getDBColumnName());
       }
     }
@@ -715,6 +734,9 @@
     if (mode.equals("EDIT") || mode.equals("CHANGE") || mode.equals("SETSESSION")) {
       // In CHANGE and SETSESSION we get them from the request
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         final Property prop = KernelUtils.getInstance().getPropertyFromColumn(field.getColumn());
         String inpColName = "inp"
             + Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName());
@@ -769,6 +791,10 @@
   }
 
   private boolean referencedEntityIsParent(BaseOBObject parentRecord, Field field) {
+    if (field.getColumn() == null) {
+      return false;
+    }
+
     Entity parentEntity = parentRecord.getEntity();
     Entity entity = ModelProvider.getInstance().getEntityByTableId(
         field.getTab().getTable().getId());
@@ -785,6 +811,9 @@
     List<String> columnsWithValidation = new ArrayList<String>();
     HashMap<String, String> validations = new HashMap<String, String>();
     for (Field field : fields) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       String columnName = field.getColumn().getDBColumnName();
       columns.add(columnName.toUpperCase());
       String validation = getValidation(field);
@@ -809,6 +838,9 @@
       // every column in the tab, instead firing reloads just for the dependant columns
       String changedCol = "";
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         String colName = field.getColumn().getDBColumnName();
         if (changedColumn.equalsIgnoreCase("inp" + Sqlc.TransformaNombreColumna(colName))) {
           sortedColumns.add(colName);
@@ -825,12 +857,18 @@
     } else {
       // Add client and org first to compute dependencies correctly
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         String colName = field.getColumn().getDBColumnName();
         if (colName.equalsIgnoreCase("Ad_Client_Id")) {
           sortedColumns.add(colName);
         }
       }
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         String colName = field.getColumn().getDBColumnName();
         if (colName.equalsIgnoreCase("Ad_Org_Id")) {
           sortedColumns.add(colName);
@@ -839,6 +877,9 @@
       // we add the columns not included in the sortedColumns
       // (the ones which don't have validations)
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         String colName = field.getColumn().getDBColumnName();
         if (!columnsWithValidation.contains(field.getColumn().getDBColumnName())
             && !sortedColumns.contains(colName) && !colName.equalsIgnoreCase("documentno")) {
@@ -855,6 +896,9 @@
     }
     if (!mode.equalsIgnoreCase("CHANGE")) {
       for (Field field : fields) {
+        if (field.getColumn() == null) {
+          continue;
+        }
         String colName = field.getColumn().getDBColumnName();
         if (colName.equalsIgnoreCase("documentno")) {
           sortedColumns.add(colName);
@@ -882,6 +926,9 @@
     // require a combo reload because they are used in a validation, or there is a callout
     // associated with them)
     for (Field field : fields) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       String column = field.getColumn().getDBColumnName();
       if (columnsInValidation.get(column) != null && columnsInValidation.get(column).size() > 0) {
         for (String colInVal : columnsInValidation.get(column)) {
@@ -959,6 +1006,10 @@
   }
 
   private void setRequestContextParameter(Field field, JSONObject jsonObj) {
+    if (field.getColumn() == null) {
+      return;
+    }
+
     try {
       String fieldId = "inp" + Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName());
       RequestContext.get().setRequestParameter(
@@ -974,6 +1025,9 @@
   private HashMap<String, Field> buildInpField(List<Field> fields) {
     HashMap<String, Field> inpFields = new HashMap<String, Field>();
     for (Field field : fields) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       inpFields.put("inp" + Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName()),
           field);
     }
@@ -1378,6 +1432,10 @@
   }
 
   private String getValidation(Field field) {
+    if (field.getColumn() == null) {
+      return "";
+    }
+
     Column c = field.getColumn();
     String val = "";
     if (c.getValidation() != null && c.getValidation().getValidationCode() != null) {
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/OBViewFieldHandler.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/OBViewFieldHandler.java	Tue Nov 22 16:26:12 2011 +0100
@@ -127,8 +127,9 @@
 
     // Processing dynamic expression (read-only logic)
     for (Field f : adFields) {
-      if (f.getColumn().getReadOnlyLogic() == null || f.getColumn().getReadOnlyLogic().equals("")
-          || !f.isActive() || !f.getColumn().isActive()) {
+      if (f.getColumn() == null || f.getColumn().getReadOnlyLogic() == null
+          || f.getColumn().getReadOnlyLogic().equals("") || !f.isActive()
+          || !f.getColumn().isActive()) {
         continue;
       }
 
@@ -148,6 +149,9 @@
     // Processing audit fields: if there's field for audit, don't put it in the "more info" section
     boolean hasCreatedField = false, hasCreatedByField = false, hasUpdatedField = false, hasUpdatedByField = false;
     for (Field f : adFields) {
+      if (f.getColumn() == null) {
+        continue;
+      }
       String dbColName = f.getColumn().getDBColumnName().toLowerCase();
       if (!dbColName.startsWith("created") && !dbColName.startsWith("updated")) {
         continue;
@@ -188,8 +192,9 @@
     int colNum = 1;
     for (Field field : adFields) {
 
-      if (field.getColumn() == null || !field.isActive()
+      if ((field.getColumn() == null && field.getClientclass() == null) || !field.isActive()
           || !(field.isDisplayed() || field.isShowInGridView())
+          || (field.getColumn() != null && !field.getColumn().isActive())
           || ApplicationUtils.isUIButton(field)) {
         ignoredFields.add(field);
         continue;
@@ -200,47 +205,90 @@
         continue;
       }
 
-      final Property property = KernelUtils.getInstance().getPropertyFromColumn(field.getColumn(),
-          false);
+      if (field.getColumn() == null) {
+        final OBClientClassField viewField = new OBClientClassField();
 
-      final OBViewField viewField = new OBViewField();
-      viewField.setField(field);
-      viewField.setProperty(property);
-      viewField.setRedrawOnChange(fieldsInDynamicExpression.contains(field));
-      viewField.setShowIf(displayLogicMap.get(field) != null ? displayLogicMap.get(field) : "");
-      viewField.setReadOnlyIf(readOnlyLogicMap.get(field) != null ? readOnlyLogicMap.get(field)
-          : "");
-      // Positioning some fields in odd-columns
-      if (colNum % 2 == 0 && (field.isStartinoddcolumn() || viewField.getColSpan() == 2)) {
-        final OBViewFieldSpacer spacer = new OBViewFieldSpacer();
-        fields.add(spacer);
-        colNum++;
+        viewField.setField(field);
+        viewField.setRedrawOnChange(fieldsInDynamicExpression.contains(field));
+        viewField.setShowIf(displayLogicMap.get(field) != null ? displayLogicMap.get(field) : "");
+        viewField.setReadOnlyIf(readOnlyLogicMap.get(field) != null ? readOnlyLogicMap.get(field)
+            : "");
+        // Positioning some fields in odd-columns
+        if (colNum % 2 == 0 && (field.isStartinoddcolumn() || viewField.getColSpan() == 2)) {
+          final OBViewFieldSpacer spacer = new OBViewFieldSpacer();
+          fields.add(spacer);
+          colNum++;
+          if (colNum > 4) {
+            colNum = 1;
+          }
+        }
+
+        // change in fieldgroup
+        if (field.getFieldGroup() != null && field.getFieldGroup() != currentADFieldGroup) {
+          // start of a fieldgroup use it
+          final OBViewFieldGroup viewFieldGroup = new OBViewFieldGroup();
+          fields.add(viewFieldGroup);
+          viewFieldGroup.setFieldGroup(field.getFieldGroup());
+
+          currentFieldGroup = viewFieldGroup;
+          currentADFieldGroup = field.getFieldGroup();
+          colNum = 1;
+        }
+
+        fields.add(viewField);
+
+        if (currentFieldGroup != null) {
+          currentFieldGroup.addChild(viewField);
+        }
+
+        colNum += viewField.getColSpan();
         if (colNum > 4) {
           colNum = 1;
         }
-      }
+      } else {
+        final OBViewField viewField = new OBViewField();
 
-      // change in fieldgroup
-      if (field.getFieldGroup() != null && field.getFieldGroup() != currentADFieldGroup) {
-        // start of a fieldgroup use it
-        final OBViewFieldGroup viewFieldGroup = new OBViewFieldGroup();
-        fields.add(viewFieldGroup);
-        viewFieldGroup.setFieldGroup(field.getFieldGroup());
+        final Property property = KernelUtils.getInstance().getPropertyFromColumn(
+            field.getColumn(), false);
+        viewField.setProperty(property);
 
-        currentFieldGroup = viewFieldGroup;
-        currentADFieldGroup = field.getFieldGroup();
-        colNum = 1;
-      }
+        viewField.setField(field);
+        viewField.setRedrawOnChange(fieldsInDynamicExpression.contains(field));
+        viewField.setShowIf(displayLogicMap.get(field) != null ? displayLogicMap.get(field) : "");
+        viewField.setReadOnlyIf(readOnlyLogicMap.get(field) != null ? readOnlyLogicMap.get(field)
+            : "");
+        // Positioning some fields in odd-columns
+        if (colNum % 2 == 0 && (field.isStartinoddcolumn() || viewField.getColSpan() == 2)) {
+          final OBViewFieldSpacer spacer = new OBViewFieldSpacer();
+          fields.add(spacer);
+          colNum++;
+          if (colNum > 4) {
+            colNum = 1;
+          }
+        }
 
-      fields.add(viewField);
+        // change in fieldgroup
+        if (field.getFieldGroup() != null && field.getFieldGroup() != currentADFieldGroup) {
+          // start of a fieldgroup use it
+          final OBViewFieldGroup viewFieldGroup = new OBViewFieldGroup();
+          fields.add(viewFieldGroup);
+          viewFieldGroup.setFieldGroup(field.getFieldGroup());
 
-      if (currentFieldGroup != null) {
-        currentFieldGroup.addChild(viewField);
-      }
+          currentFieldGroup = viewFieldGroup;
+          currentADFieldGroup = field.getFieldGroup();
+          colNum = 1;
+        }
 
-      colNum += viewField.getColSpan();
-      if (colNum > 4) {
-        colNum = 1;
+        fields.add(viewField);
+
+        if (currentFieldGroup != null) {
+          currentFieldGroup.addChild(viewField);
+        }
+
+        colNum += viewField.getColSpan();
+        if (colNum > 4) {
+          colNum = 1;
+        }
       }
     }
 
@@ -292,6 +340,9 @@
       if (viewDef instanceof OBViewField && viewDef.getIsGridProperty()) {
         ((OBViewField) viewDef).setGridSort(sort++);
       }
+      if (viewDef instanceof OBClientClassField && viewDef.getIsGridProperty()) {
+        ((OBClientClassField) viewDef).setGridSort(sort++);
+      }
     }
 
     return fields;
@@ -349,6 +400,8 @@
 
     public boolean getShowStartRow();
 
+    public String getClientClass();
+
     public boolean getShowEndRow();
 
     public boolean getHasChildren();
@@ -525,6 +578,10 @@
       return true;
     }
 
+    public String getClientClass() {
+      return "";
+    }
+
     public boolean isShowInitiallyInGrid() {
       return false;
     }
@@ -633,6 +690,245 @@
 
   }
 
+  public class OBClientClassField implements OBViewFieldDefinition {
+    private Field field;
+    private String label;
+    private boolean redrawOnChange = false;
+    private String showIf = "";
+    private String readOnlyIf = "";
+    private int gridSort = 0;
+
+    public String getOnChangeFunction() {
+      return field.getOnChangeFunction();
+    }
+
+    public boolean getShowColSpan() {
+      return getColSpan() != 1;
+    }
+
+    public boolean getShowStartRow() {
+      return getStartRow();
+    }
+
+    public boolean getShowEndRow() {
+      return getEndRow();
+    }
+
+    public boolean getHasChildren() {
+      return false;
+    }
+
+    public Long getGridPosition() {
+      return field.getGridPosition();
+    }
+
+    public String getClientClass() {
+      return field.getClientclass() == null ? "" : field.getClientclass();
+    }
+
+    public Long getSequenceNumber() {
+      return field.getSequenceNumber();
+    }
+
+    public String getCellAlign() {
+      return "left";
+    }
+
+    public boolean getAutoExpand() {
+      return false;
+    }
+
+    public boolean getIsAuditField() {
+      return false;
+    }
+
+    public String getGridFieldProperties() {
+      return ", canSort: false, canFilter: false";
+    }
+
+    public String getFilterEditorProperties() {
+      return "";
+    }
+
+    public String getGridEditorFieldProperties() {
+      return "";
+    }
+
+    /**
+     * @deprecated use {@link #setRedrawOnChange(boolean)}
+     */
+    @Deprecated
+    public void setReadrawOnChange(boolean value) {
+      this.setRedrawOnChange(value);
+    }
+
+    public boolean getIsGridProperty() {
+      return true;
+    }
+
+    public boolean getSessionProperty() {
+      return false;
+    }
+
+    public boolean getReadOnly() {
+      return getParentProperty() || field.isReadOnly();
+    }
+
+    public boolean getUpdatable() {
+      return true;
+    }
+
+    public boolean getPersonalizable() {
+      return true;
+    }
+
+    public boolean getParentProperty() {
+      return false;
+    }
+
+    public boolean isSearchField() {
+      return false;
+    }
+
+    public boolean isFirstFocusedField() {
+      return false;
+    }
+
+    public String getType() {
+      return "text";
+    }
+
+    public boolean getHasDefaultValue() {
+      return field.getColumn() != null && field.getColumn().getDefaultValue() != null;
+    }
+
+    public String getFieldProperties() {
+      return "editorType: 'OBClientClassCanvasItem', filterEditorType: 'TextItem', ";
+    }
+
+    public String getName() {
+      return field.getName();
+    }
+
+    public String getColumnName() {
+      return "";
+    }
+
+    public String getInpColumnName() {
+      return "";
+    }
+
+    public String getReferencedKeyColumnName() {
+      return "";
+    }
+
+    public String getTargetEntity() {
+      return "";
+    }
+
+    public String getLabel() {
+      // compute the label
+      if (label == null) {
+        label = OBViewUtil.getLabel(field);
+      }
+      return label;
+    }
+
+    public void setLabel(String label) {
+      this.label = label;
+    }
+
+    public Field getField() {
+      return field;
+    }
+
+    public void setField(Field field) {
+      this.field = field;
+    }
+
+    public boolean getStandardField() {
+      return true;
+    }
+
+    public boolean getRequired() {
+      return false;
+    }
+
+    public Integer getLength() {
+      return field.getDisplayedLength() != null ? field.getDisplayedLength().intValue() : 0;
+    }
+
+    public boolean getForeignKeyField() {
+      return false;
+    }
+
+    public String getDataSourceId() {
+      return "";
+    }
+
+    public long getColSpan() {
+      if (field.getObuiappColspan() != null) {
+        return field.getObuiappColspan();
+      }
+      return field.getDisplayedLength() > ONE_COLUMN_MAX_LENGTH || getRowSpan() == 2 ? 2 : 1;
+    }
+
+    public boolean getEndRow() {
+      return false;
+    }
+
+    public long getRowSpan() {
+      if (field.getObuiappRowspan() != null) {
+        return field.getObuiappRowspan();
+      }
+      return 1;
+    }
+
+    public boolean getStartRow() {
+      return field.isStartnewline();
+    }
+
+    public void setRedrawOnChange(boolean redrawOnChange) {
+      this.redrawOnChange = redrawOnChange;
+    }
+
+    public boolean getRedrawOnChange() {
+      return redrawOnChange;
+    }
+
+    public void setShowIf(String showIf) {
+      this.showIf = showIf;
+    }
+
+    public String getShowIf() {
+      return showIf;
+    }
+
+    public void setReadOnlyIf(String readOnlyExpression) {
+      this.readOnlyIf = readOnlyExpression;
+    }
+
+    public String getReadOnlyIf() {
+      return readOnlyIf;
+    }
+
+    public boolean isDisplayed() {
+      return field.isDisplayed() != null && field.isDisplayed();
+    }
+
+    public boolean isShowInitiallyInGrid() {
+      return field.isShowInGridView();
+    }
+
+    public int getGridSort() {
+      return gridSort;
+    }
+
+    public void setGridSort(int gridSort) {
+      this.gridSort = gridSort;
+    }
+  }
+
   public class OBViewField implements OBViewFieldDefinition {
     private Field field;
     private Property property;
@@ -644,6 +940,10 @@
     private String readOnlyIf = "";
     private int gridSort = 0;
 
+    public String getClientClass() {
+      return field.getClientclass() == null ? "" : field.getClientclass();
+    }
+
     public String getOnChangeFunction() {
       return field.getOnChangeFunction();
     }
@@ -720,6 +1020,9 @@
       if (!field.isActive()) {
         return false;
       }
+      if (field.getColumn() == null) {
+        return true;
+      }
       final Property prop = KernelUtils.getInstance().getPropertyFromColumn(field.getColumn());
       if (prop.isParent() && getWindowEntities().contains(prop.getTargetEntity().getName())) {
         return false;
@@ -775,7 +1078,7 @@
     }
 
     public boolean getHasDefaultValue() {
-      return field.getColumn().getDefaultValue() != null;
+      return field.getColumn() != null && field.getColumn().getDefaultValue() != null;
     }
 
     public String getFieldProperties() {
@@ -799,6 +1102,9 @@
       if (uiDefinition != null) {
         return uiDefinition;
       }
+      if (field.getColumn() == null) {
+        return null;
+      }
       uiDefinition = UIDefinitionController.getInstance().getUIDefinition(property.getColumnId());
       return uiDefinition;
     }
@@ -982,6 +1288,10 @@
       return null;
     }
 
+    public String getClientClass() {
+      return "";
+    }
+
     public boolean getShowColSpan() {
       return getColSpan() != 4;
     }
@@ -1420,6 +1730,10 @@
       return getColSpan() != 1;
     }
 
+    public String getClientClass() {
+      return "";
+    }
+
     public boolean getShowStartRow() {
       return getStartRow();
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-canvas.js	Tue Nov 22 16:26:12 2011 +0100
@@ -0,0 +1,50 @@
+/*
+ *************************************************************************
+ * 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) 2011 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+// == OBClientClassCanvasItem ==
+// Extends CanvasItem, support usage of Canvas in a grid/form editor
+// and in the grid itself
+isc.ClassFactory.defineClass('OBClientClassCanvasItem', isc.CanvasItem);
+
+isc.OBClientClassCanvasItem.addProperties({
+  autoDestroy: true,
+
+  createCanvas: function() {
+    var canvas = isc.ClassFactory.newInstance(this.clientClass, {canvasItem: this});
+    if (canvas.noTitle) {
+      this.showTitle = false;
+    }
+    
+    if (this.form.itemChanged && canvas.onItemChanged) {
+      canvas.observe(this.form, 'itemChanged', 'observer.onItemChanged(observed)');
+    }
+    
+    if (!canvas) {
+      return isc.Label.create({contents:'Invalid Type ' + this.clientClass, width: 1, height: 1, overflow: 'visible', autoDraw: false});
+    }
+    return canvas;
+  },
+  
+  redrawing: function() {
+    if (this.canvas.redrawingItem) {
+      this.canvas.redrawingItem();
+    }
+    this.Super('redrawing', arguments);
+  }
+});
\ No newline at end of file
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-fk.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-fk.js	Tue Nov 22 16:26:12 2011 +0100
@@ -25,7 +25,7 @@
 
 isc.OBFKItem.addProperties({
   operator: 'iContains',
-    
+  
   // set the identifier field also, that's what gets displayed in the grid
   changed: function (form, item, value) {
     if (!this._pickedValue && value) {
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Tue Nov 22 16:26:12 2011 +0100
@@ -25,7 +25,11 @@
 
   dragTrackerMode: 'none',
   
-  recordComponentPoolingMode: 'recycle',
+  // recycle gives better performance but also results
+  // in strange results that not all record components are
+  // drawn when scrolling very fast
+  recordComponentPoolingMode: 'viewport',
+  
   showRecordComponentsByCell: true,
   recordComponentPosition: 'within',
   poolComponentsPerColumn: true,
@@ -667,3 +671,6 @@
     this.owner.doAction();
   }
 });
+
+isc.ClassFactory.defineClass('OBGridFormButton', isc.OBFormButton);
+isc.OBGridFormButton.addProperties({});
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Tue Nov 22 16:26:12 2011 +0100
@@ -377,6 +377,10 @@
     isc.addProperties(this.editFormDefaults, props);
   },
   
+  getCellVAlign: function() {
+    return 'center';
+  },
+  
   getCellAlign: function(record, rowNum, colNum){
     if (rowNum === this.getEditRow()) {
       return 'center';
@@ -1631,7 +1635,7 @@
   // +++++++++++++++++ functions for grid editing +++++++++++++++++
 
   startEditing: function (rowNum, colNum, suppressFocus, eCe, suppressWarning) {
-    var i, ret, length = this.getFields().length;
+    var i, ret, fld, length = this.getFields().length;
     // if a row is set and not a col then check if we should focus in the
     // first error field
     if ((rowNum || rowNum === 0) && (!colNum && colNum !== 0) && this.rowHasErrors(rowNum))  {
@@ -1654,10 +1658,28 @@
       }    
     }
 
+    this.recomputeCanvasComponents(rowNum);
+    
     ret = this.Super('startEditing', [rowNum, colNum, suppressFocus, eCe, suppressWarning]);
+    
     return ret;
   },
 
+  // recompute recordcomponents
+  recomputeCanvasComponents: function(rowNum) {
+    var i, fld, length = this.getFields().length;
+    
+    // remove client record components in edit mode
+    for (i = 0; i < length; i++) {
+      fld = this.getFields()[i];
+      if (fld.clientClass) {
+        this.refreshRecordComponent(rowNum, i);
+      }
+    }
+    
+    this.refreshRow(rowNum);
+  },
+  
   startEditingNew: function(rowNum){
     // several cases:
     // - no current rows, add at position 0
@@ -1779,6 +1801,7 @@
     this.view.toolBar.updateButtonState(true);
     this.view.messageBar.hide();
     this.view.refreshParentRecord();
+    this.recomputeCanvasComponents(rowNum);
   },
 
   undoEditSelectedRows: function(){
@@ -1890,7 +1913,9 @@
       }
       
       this.view.standardWindow.cleanUpAutoSaveProperties();
-      
+
+      this.recomputeCanvasComponents(rowNum);
+   
       // update after removing the error msg
       this.view.updateTabTitle();
     }
@@ -2389,6 +2414,8 @@
   // +++++++++++++++++ functions for the edit-link column +++++++++++++++++
   
   createRecordComponent: function(record, colNum){
+    var fld = this.getFields()[colNum], canvas,
+      rowNum = this.getRecordIndex(record), isEditRecord = rowNum === this.getEditRow();
     if (this.isEditLinkColumn(colNum)) {
       var layout = isc.OBGridButtonsComponent.create({
         record: record,
@@ -2400,18 +2427,38 @@
       record.editColumnLayout = layout;
       return layout;
     }
+    if (fld.clientClass && !isEditRecord) {
+      canvas = isc.ClassFactory.newInstance(fld.clientClass, {grid: this, rowNum: rowNum, record: record, colNum: colNum});
+      if (canvas) {
+        if (canvas.setRecord) {
+          canvas.setRecord(record);
+        }
+        return canvas;
+      }
+    }
   },
   
   updateRecordComponent: function(record, colNum, component, recordChanged){
-    // clear the previous record pointer
-    if (recordChanged && component.record.editColumnLayout === component) {
-      component.record.editColumnLayout = null;
+    var rowNum = this.getRecordIndex(record), isEditRecord = rowNum === this.getEditRow();
+    if (component.editButton) {
+      if (recordChanged && component.record.editColumnLayout === component) {
+        component.record.editColumnLayout = null;
+      }
+      component.record = record;
+      record.editColumnLayout = component;
+      component.editButton.setErrorState(record[isc.OBViewGrid.ERROR_MESSAGE_PROP]);
+      component.editButton.setErrorMessage(record[isc.OBViewGrid.ERROR_MESSAGE_PROP]);
+      component.showEditOpen();
+    } if (isEditRecord) {
+      return null;
+    } else {
+      if (component.setRecord) {
+        component.setRecord(record);
+      } else {
+        component.record = record;
+      }
+      component.rowNum = rowNum;
     }
-    component.record = record;
-    record.editColumnLayout = component;
-    component.editButton.setErrorState(record[isc.OBViewGrid.ERROR_MESSAGE_PROP]);
-    component.editButton.setErrorMessage(record[isc.OBViewGrid.ERROR_MESSAGE_PROP]);
-    component.showEditOpen();
     return component;
   },
   
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js	Tue Nov 22 16:26:12 2011 +0100
@@ -1334,7 +1334,11 @@
         callBackFunction();
       }
     };
-    
+
+    if(this.viewForm && this.viewForm.contextInfo) {
+      this.viewForm.contextInfo = null;
+    }
+
     this.getDataSource().fetchData(criteria, callback);
     this.refreshParentRecord(callBackFunction);
   },
@@ -1857,12 +1861,18 @@
       fld.originalShowIf = fld.showIf;
       fld.showIf = function(item, value, form, values) {
         var currentValues = values || form.view.getCurrentValues(),
-        context = form.getCachedContextInfo();
+          context = form.getCachedContextInfo(), 
+          originalShowIfValue = false;
 
         OB.Utilities.fixNull250(currentValues);
         
-        return !this.hiddenInForm && context && 
-          this.originalShowIf(item, value, form, currentValues, context);
+        try {
+          originalShowIfValue = this.originalShowIf(item, value, form, currentValues, context);
+        } catch(_exception) {
+          isc.warn(_exception + ' ' + _exception.message + ' ' + _exception.stack);
+        }
+        
+        return !this.hiddenInForm && context && originalShowIfValue;
       };
     }
     if (fld.type === 'OBAuditSectionItem') {
@@ -1954,7 +1964,8 @@
       }
 
       // correct some stuff coming from the form fields
-      if (!fld.displayed) {
+      if (fld.displayed === false) {
+        fld.canEdit = false;
         fld.visible = true;
         fld.alwaysTakeSpace = true;
       }
@@ -1978,7 +1989,7 @@
       }
       
       type = isc.SimpleType.getType(fld.type);
-      if (type.editorType) {
+      if (type.editorType && !fld.editorType) {
         fld.editorType = type.editorType;
       }
       
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-window.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-window.js	Tue Nov 22 16:26:12 2011 +0100
@@ -102,17 +102,57 @@
         className = '_',
         tabSet = OB.MainView.TabSet;
     
-    if(params.windowId) {
+    if (params.windowId) {
       className = className + params.windowId;
       if(len === 3) {
         // debug mode, we have added _timestamp
         className = className + '_' + parts[2];
       }
-      this.runningProcess = isc[className].create(isc.addProperties({}, params, {parentWindow: this}));
-      tabSet.updateTab(tabSet.getSelectedTab(), this.runningProcess);
+
+      if (isc[className]) {
+        this.runningProcess = isc[className].create(isc.addProperties({}, params, {parentWindow: this}));
+        tabSet.updateTab(tabSet.getSelectedTab(), this.runningProcess);
+      }
     }
   },
-  
+
+  refresh: function () {
+    var currentView = this.activeView, afterRefresh;
+
+    afterRefresh = function () {
+      // Refresh context view
+      //contextView.getTabMessage();
+      currentView.toolBar.refreshCustomButtons();
+//
+//      if (contextView !== currentView && currentView.state === isc.OBStandardView.STATE_TOP_MAX) {
+//        // Executing an action defined in parent tab, current tab is maximized,
+//        // let's set half for each in order to see the message
+//        contextView.setHalfSplit();
+//      }
+
+      // Refresh in order to show possible new records
+      currentView.refresh(null, false, true);
+    };
+
+    if(!currentView) {
+      return;
+    }
+
+    if (currentView.parentView) {
+      currentView.parentView.setChildsToRefresh();
+    } else {
+      currentView.setChildsToRefresh();
+    }
+
+    if (currentView.viewGrid.getSelectedRecord()) {
+      // There is a record selected, refresh it and its parent
+      currentView.refreshCurrentRecord(afterRefresh);
+    } else {
+      // No record selected, refresh parent
+      currentView.refreshParentRecord(afterRefresh);
+    }
+  },
+
   readWindowSettings: function() {
     var standardWindow = this;
     
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-tab.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-tab.js	Tue Nov 22 16:26:12 2011 +0100
@@ -300,8 +300,8 @@
       previousPane.destroy();
     }
 
-    if(refresh && pane.activeView && pane.activeView.refresh) {
-      this.fireOnPause('refreshRecordInView', {target: pane.activeView, methodName: 'refresh'}, 90);
+    if(refresh && pane.refresh) {
+      this.fireOnPause('refreshRecordInView', {target: pane, methodName: 'refresh'}, 120);
     }
   }
 });
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-view.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-view.js	Tue Nov 22 16:26:12 2011 +0100
@@ -148,8 +148,8 @@
 
   closeClick: function () {
     var tabSet = OB.MainView.TabSet;
+    this.Super('closeClick', arguments);
     tabSet.updateTab(tabSet.getSelectedTab(), this.parentWindow, true);
-    this.Super('closeClick', arguments);
   },
 
   _addIconField: function () {
@@ -196,6 +196,7 @@
         len = selection.length;
 
     allProperties._selection = [];
+    allProperties._allRows = [];
     allProperties._buttonValue = btnValue || 'DONE';
 
     for (i = 0; i < len; i++) {
@@ -203,6 +204,13 @@
       allProperties._selection.push(tmp);
     }
 
+    len = (grid.data.allRows && grid.data.allRows.length) || 0;
+
+    for (i = 0; i < len; i++) {
+      tmp = isc.addProperties({}, grid.data.allRows[i], grid.getEditedRecord(grid.data.allRows[i]));
+      allProperties._allRows.push(tmp);
+    }
+
     OB.RemoteCallManager.call(this.actionHandler, allProperties, {
       processId: this.processId,
       windowId: this.windowId
--- a/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-form-styles.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-form-styles.js	Tue Nov 22 16:26:12 2011 +0100
@@ -62,6 +62,8 @@
 
 isc.OBEncryptedItem.addProperties(isc.addProperties({}, OB.Styles.OBFormField.DefaultTextItem));
 
+isc.OBClientClassCanvasItem.addProperties(isc.addProperties({}, OB.Styles.OBFormField.DefaultTextItem));
+
 isc.OBTextAreaItem.addProperties(isc.addProperties({}, OB.Styles.OBFormField.DefaultTextItem));
 isc.OBTextAreaItem.addProperties({
   height: 66
--- a/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-grid-styles.css	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-grid-styles.css	Tue Nov 22 16:26:12 2011 +0100
@@ -80,6 +80,7 @@
   vertical-align: middle;
   border-right: 1px solid #cdd7bb;
   border-bottom: 1px solid #cdd7bb;
+  
 /*  margin: 0px; */
   padding: 0px 4px 0px 4px;
 }
@@ -367,4 +368,59 @@
   background-color: #FFFFFF;
 }
 
-/******************************/
\ No newline at end of file
+/******************************/
+
+.OBGridFormButton,
+.OBGridFormButtonOver,
+.OBGridFormButtonFocused,
+.OBGridFormButtonFocusedOver,
+.OBGridFormButtonDown,
+.OBGridFormButtonFocusedDown,
+.OBGridFormButtonSelected,
+.OBGridFormButtonSelectedFocused,
+.OBGridFormButtonSelectedDown,
+.OBGridFormButtonSelectedFocusedDown,
+.OBGridFormButtonSelectedOver,
+.OBGridFormButtonSelectedFocusedOver,
+.OBGridFormButtonDisabled,
+.OBGridFormButtonSelectedDisabled {
+  padding: 2px 5px 2px 5px;
+  font-family:'lucida sans',sans-serif; 
+  font-size:12px;
+  background-image:url(./images/form/textButton-bg-normal.png);
+  color:#000000;
+  background-position:right top;
+  background-repeat: no-repeat;
+  cursor: pointer;
+  border: 2px solid #efefef;
+}
+
+.OBGridFormButtonDisabled,
+.OBGridFormButtonSelectedDisabled {
+  border:2px solid #d0d1cd;
+  background-image: url(./images/form/textButton-bg-disabled.png);
+  font-weight:normal;
+  color:#777;
+}
+
+.OBGridFormButtonFocused,
+.OBGridFormButtonFocusedOver,
+.OBGridFormButtonSelectedFocused,
+.OBGridFormButtonSelectedFocusedOver,
+.OBGridFormButtonSelectedFocusedDown {
+  border:2px solid #fa962f;
+}
+
+.OBGridFormButtonOver,
+.OBGridFormButtonFocusedOver,
+.OBGridFormButtonSelectedFocused,
+.OBGridFormButtonSelectedFocusedOver {
+  background-image: url(./images/form/textButton-bg-hover.png);
+}
+
+.OBGridFormButtonDown,
+.OBGridFormButtonFocusedDown,
+.OBGridFormButtonSelectedDown,
+.OBGridFormButtonSelectedFocusedDown {
+  background-image: url(./images/form/textButton-bg-down.png);
+}
--- a/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-grid-styles.js	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.userinterface.smartclient/openbravo/skins/Default/org.openbravo.client.application/ob-grid-styles.js	Tue Nov 22 16:26:12 2011 +0100
@@ -197,4 +197,13 @@
   bodyStyleName: 'OBAlertGridBody'
 });
 
-/******************************/
\ No newline at end of file
+/******************************/
+
+isc.OBGridFormButton.addProperties({
+  baseStyle: 'OBGridFormButton',
+  titleStyle: 'OBFormButtonTitle',
+
+  width: 1,
+  height: 21,
+  overflow: 'visible'
+});
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/UIDefinition.java	Tue Nov 22 16:11:14 2011 +0100
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/UIDefinition.java	Tue Nov 22 16:26:12 2011 +0100
@@ -495,6 +495,9 @@
   private FieldProvider generateTabData(List<Field> fields, Field currentField, String currentValue) {
     HashMap<String, Object> noinpDataMap = new HashMap<String, Object>();
     for (Field field : fields) {
+      if (field.getColumn() == null) {
+        continue;
+      }
       String oldKey = "inp" + Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName());
       Object value;
       if (currentField.getId().equals(field.getId())) {
--- a/src-db/database/model/tables/AD_FIELD.xml	Tue Nov 22 16:11:14 2011 +0100
+++ b/src-db/database/model/tables/AD_FIELD.xml	Tue Nov 22 16:26:12 2011 +0100
@@ -129,6 +129,10 @@
         <default/>
         <onCreateDefault/>
       </column>
+      <column name="CLIENTCLASS" primaryKey="false" required="false" type="NVARCHAR" size="255" autoIncrement="false">
+        <default/>
+        <onCreateDefault/>
+      </column>
       <foreign-key foreignTable="AD_COLUMN" name="AD_COLUMN_FIELD">
         <reference local="AD_COLUMN_ID" foreign="AD_COLUMN_ID"/>
       </foreign-key>
--- a/src-db/database/model/triggers/AD_FIELD_MOD_TRG.xml	Tue Nov 22 16:11:14 2011 +0100
+++ b/src-db/database/model/triggers/AD_FIELD_MOD_TRG.xml	Tue Nov 22 16:26:12 2011 +0100
@@ -83,6 +83,7 @@
         COALESCE(:NEW.IsEncrypted , '.') != COALESCE(:OLD.IsEncrypted , '.') OR
         COALESCE(:NEW.ShowInRelation , '.') != COALESCE(:OLD.ShowInRelation , '.') OR
         COALESCE(:NEW.OnChangeFunction , '.') != COALESCE(:OLD.OnChangeFunction , '.') OR
+        COALESCE(:NEW.ClientClass , '.') != COALESCE(:OLD.ClientClass , '.') OR
         COALESCE(:NEW.Isfirstfocusedfield , '.') != COALESCE(:OLD.Isfirstfocusedfield , '.') OR
         COALESCE(:NEW.AD_Module_ID , '.') != COALESCE(:OLD.AD_Module_ID , '.') OR
         1=2) THEN
--- a/src-db/database/sourcedata/AD_COLUMN.xml	Tue Nov 22 16:11:14 2011 +0100
+++ b/src-db/database/sourcedata/AD_COLUMN.xml	Tue Nov 22 16:26:12 2011 +0100
@@ -1851,7 +1851,7 @@
 <!--174-->  <FIELDLENGTH><![CDATA[22]]></FIELDLENGTH>
 <!--174-->  <ISKEY><![CDATA[N]]></ISKEY>
 <!--174-->  <ISPARENT><![CDATA[N]]></ISPARENT>
-<!--174-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--174-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
 <!--174-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
 <!--174-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
 <!--174-->  <ISTRANSLATED><![CDATA[N]]></ISTRANSLATED>
@@ -264668,6 +264668,38 @@
 <!--99E6DCF9068E43C7A699FEAECF28DD5C-->  <IMAGESIZEVALUESACTION><![CDATA[N]]></IMAGESIZEVALUESACTION>
 <!--99E6DCF9068E43C7A699FEAECF28DD5C--></AD_COLUMN>
 
+<!--9AB3980C9BB144A48043EBC87DBA57D6--><AD_COLUMN>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_COLUMN_ID><![CDATA[9AB3980C9BB144A48043EBC87DBA57D6]]></AD_COLUMN_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <NAME><![CDATA[Clientclass]]></NAME>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <COLUMNNAME><![CDATA[Clientclass]]></COLUMNNAME>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_TABLE_ID><![CDATA[107]]></AD_TABLE_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_REFERENCE_ID><![CDATA[10]]></AD_REFERENCE_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <FIELDLENGTH><![CDATA[255]]></FIELDLENGTH>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISKEY><![CDATA[N]]></ISKEY>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISPARENT><![CDATA[N]]></ISPARENT>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <SEQNO><![CDATA[111]]></SEQNO>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISTRANSLATED><![CDATA[N]]></ISTRANSLATED>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISSELECTIONCOLUMN><![CDATA[N]]></ISSELECTIONCOLUMN>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_ELEMENT_ID><![CDATA[3269E9900D0C45BB9CDA1BF2975242ED]]></AD_ELEMENT_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISSESSIONATTR><![CDATA[N]]></ISSESSIONATTR>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISSECONDARYKEY><![CDATA[N]]></ISSECONDARYKEY>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISDESENCRYPTABLE><![CDATA[N]]></ISDESENCRYPTABLE>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <DEVELOPMENTSTATUS><![CDATA[RE]]></DEVELOPMENTSTATUS>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <POSITION><![CDATA[33]]></POSITION>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISTRANSIENT><![CDATA[N]]></ISTRANSIENT>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <ISAUTOSAVE><![CDATA[Y]]></ISAUTOSAVE>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <VALIDATEONNEW><![CDATA[Y]]></VALIDATEONNEW>
+<!--9AB3980C9BB144A48043EBC87DBA57D6-->  <IMAGESIZEVALUESACTION><![CDATA[N]]></IMAGESIZEVALUESACTION>
+<!--9AB3980C9BB144A48043EBC87DBA57D6--></AD_COLUMN>
+
 <!--9BAEEE4845E238D8E040007F01002420--><AD_COLUMN>
 <!--9BAEEE4845E238D8E040007F01002420-->  <AD_COLUMN_ID><![CDATA[9BAEEE4845E238D8E040007F01002420]]></AD_COLUMN_ID>
 <!--9BAEEE4845E238D8E040007F01002420-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_ELEMENT.xml	Tue Nov 22 16:11:14 2011 +0100
+++ b/src-db/database/sourcedata/AD_ELEMENT.xml	Tue Nov 22 16:26:12 2011 +0100
@@ -20944,6 +20944,18 @@
 <!--3214384084114F38B297AD4448B6D3F6-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
 <!--3214384084114F38B297AD4448B6D3F6--></AD_ELEMENT>
 
+<!--3269E9900D0C45BB9CDA1BF2975242ED--><AD_ELEMENT>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <AD_ELEMENT_ID><![CDATA[3269E9900D0C45BB9CDA1BF2975242ED]]></AD_ELEMENT_ID>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <COLUMNNAME><![CDATA[Clientclass]]></COLUMNNAME>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <NAME><![CDATA[Clientclass]]></NAME>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <PRINTNAME><![CDATA[Clientclass]]></PRINTNAME>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--3269E9900D0C45BB9CDA1BF2975242ED-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
+<!--3269E9900D0C45BB9CDA1BF2975242ED--></AD_ELEMENT>
+
 <!--33D4F4DEADD74C48A55C08A9DCEB41B2--><AD_ELEMENT>
 <!--33D4F4DEADD74C48A55C08A9DCEB41B2-->  <AD_ELEMENT_ID><![CDATA[33D4F4DEADD74C48A55C08A9DCEB41B2]]></AD_ELEMENT_ID>
 <!--33D4F4DEADD74C48A55C08A9DCEB41B2-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_FIELD.xml	Tue Nov 22 16:11:14 2011 +0100
+++ b/src-db/database/sourcedata/AD_FIELD.xml	Tue Nov 22 16:26:12 2011 +0100
@@ -168718,6 +168718,31 @@
 <!--430290B286B648EB8F50EA27D7A7EFFA-->  <ISSHOWNINSTATUSBAR><![CDATA[N]]></ISSHOWNINSTATUSBAR>
 <!--430290B286B648EB8F50EA27D7A7EFFA--></AD_FIELD>
 
+<!--43098FDD29A24542BD7AB5E00AAE5AB5--><AD_FIELD>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_FIELD_ID><![CDATA[43098FDD29A24542BD7AB5E00AAE5AB5]]></AD_FIELD_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <NAME><![CDATA[Clientclass]]></NAME>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_TAB_ID><![CDATA[107]]></AD_TAB_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_COLUMN_ID><![CDATA[9AB3980C9BB144A48043EBC87DBA57D6]]></AD_COLUMN_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <DISPLAYLOGIC><![CDATA[@ad_column_id@='']]></DISPLAYLOGIC>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <DISPLAYLENGTH><![CDATA[255]]></DISPLAYLENGTH>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <SEQNO><![CDATA[35]]></SEQNO>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <SHOWINRELATION><![CDATA[Y]]></SHOWINRELATION>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISFIRSTFOCUSEDFIELD><![CDATA[N]]></ISFIRSTFOCUSEDFIELD>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <STARTINODDCOLUMN><![CDATA[N]]></STARTINODDCOLUMN>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <STARTNEWLINE><![CDATA[N]]></STARTNEWLINE>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5-->  <ISSHOWNINSTATUSBAR><![CDATA[N]]></ISSHOWNINSTATUSBAR>
+<!--43098FDD29A24542BD7AB5E00AAE5AB5--></AD_FIELD>
+
 <!--43807E6C74554F88A2DEF38789D718E2--><AD_FIELD>
 <!--43807E6C74554F88A2DEF38789D718E2-->  <AD_FIELD_ID><![CDATA[43807E6C74554F88A2DEF38789D718E2]]></AD_FIELD_ID>
 <!--43807E6C74554F88A2DEF38789D718E2-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>