INTRODUCTION TO MODEL DRIVEN ARCHITECTURE
This chapter describes Compiere's Model Driven Architecture and the Data Dictionary functionality in Compiere.
In most applications, developers must design code and test every screen. This can be very time consuming and lead to inconsistency across an application in terms of look and feel, as well as functionality. This can also make it difficult for users to learn new areas of a complex application like ERP. Compiere simplifies the task by using a more advanced concept of a central active data dictionary. Windows are generated at runtime from the data dictionary. Developers simply define the rules for how the window displays and in what conditions. This results in windows that only display data that the user needs to see for a given situation. For example, if a Sales order involves the customer taking the merchandise with them and paying you, there is no need to display fields like Shipping Rule, Invoice Rule or Payment Term. But, if a Sales Order involves you shipping merchandise to the customer and sending them a bill for payment at a later time, these fields are necessary. In addition to providing a consistent look and feel, it also enables data and fields to be displayed based on a user's security. In other applications this would require the definition of multiple windows.
THE DATA DICTIONARY
Compiere's data dictionary is an integral part of the application. It "knows" how to access data and how data is related. The data dictionary contains definitions of a data entity (type, validation, etc.), how it is displayed (label on screens reports, help, display sequence position relative to other fields), and the display rules. Security and access rules are also maintained here.
The data at runtime is context sensitive. For example: it "knows" that a counter sale does not have a payment term, so it does not display one. It also knows that there must be stock available even if the inventory record shows zero (because, for example, a material receipt has not been processed). However if the user changes the transaction type to a standard order, a payment term becomes a mandatory part of the transaction and the transaction recognizes the "out of stock" situation. Additionally, translations of the user interface as well as Business Partner documents is done in the data dictionary.
The Data Dictionary is user extensible and can include user specified rules and information. This enables authorized users to add new tables and new screens and additional fields to existing screens. All added items are automatically able to be listed and reported using the standard reporting functionality available throughout the application.
The Data Dictionary is comprised of six main entities
- Table & Column
- Window, Tab and Field
- Reports and Processes
Elements provide a central reference for all fields. Any field defined for any table in Compiere has a corresponding Element. This provides for consistent labeling of fields, display on reports, and help text. It also means that an element needs to be defined only once even though it may be used in hundreds of tables and multiple windows (e.g. Organization). The data from the Element (Name, Print Text, Description, and Comment) is automatically synchronized with the corresponding fields in both tables and windows.
Elements are defined in the Element window. This window can be accessed when logged in with a System Administrator role.
Each Element must have a DB Column Name. This is the reference that is used when linking an Element to a specific field in a table. A Name and Print Text are also required. The Name is the label that will be used on any window, form or parameter form where the element is referenced. The Print Text is the column heading that will print on reports. There may be instances where you will want a shorter Print Name to maximize report layout. For example, the Element ISVendor is a 1 position Boolean. For a report heading you may want to print 'Vend'.
The Description and Comment fields are not required. In most instances you will want to provide values for these fields. The Description field is the text that will display in 'bubble help' when you hover your cursor over a field. The Comment field will display as the online help (F1) for that field.
The Active check box indicates that this Element is active and can be referenced when defining columns of tables.
The Entity Type will default to User Defined for any records you add. You can change this to another Entity Type that you have defined. You should not use Compiere or Dictionary if you want your additions preserved when migrating.
The Element window also contains a Used in Column tab. This displays all of the columns where this Element is referenced. This can be helpful if you are considering changing an existing element as it will indicate what other entities your changes would affect.
TABLE AND COLUMN
Tables are the entity that Windows are built on. You can define a table and its associated columns directly in Compiere Application Dictionary by using the user interface and use this definition to create the corresponding database table or database view in the underlying database. Alternatively, you can create a database table or database view in the database first, and import its definition into Compiere Application Dictionary.
New tables can be created by opening the Table and Column window, while logged in with a System Administrator role.
Enter a DB Table Name. If you want to import the definition of an already created database table or database view in the database, make sure that the name provided here is the same.
If the underlying database object is a view, check the View checkbox.
You also must enter a Data Access Level (for automatic Roles) and a Transaction Type. The Transaction Type will indicate if an explicit Organization value (other than *) is or is not required when a record is saved to this table.
Other fields are optional. Some of these have a direct impact on the data dictionary functionality.
The Window and PO Window fields indicate which window will be the 'Zoom Target'.
The High Volume check box, if selected, will cause the window that references this table to initially display a query window. If the check box is deselected, it will return all active records.
To import an already created database table or database view from the database, select the 'Create Columns from Database' button or the 'Import this view from DB' button. To verify if a view definition is imported correctly, select the 'Create this view in DB' button to recreate the view in the database using the imported view definition.
Columns will display as fields in the windows that reference the table. Columns can either be entered in the Data Dictionary and then synchronized with the database or they can be created from the table already populated in the database. Generally, new tables and their respective columns are populated in the database via a tool (e.g. SQL Loader), but if you have one or two new columns to add it may be easier to create them in Compiere and then synchronize them with the database.
The values selected and data entered in the column will determine how and when the fields display in windows. There is further refinement that can be done in the Window definition, which will be covered in the next section.
The DB Columns Name is required (we suggest using the same name as the Element)
Select the Element that corresponds to this column. If you create the columns from the database and an Element with the same name does not exist, the process will create the Element.
Enter a Name. You can leave the Description and Comment blank as they will be synchronized with the Element when the record is saved.
Some of the other fields in Column which are used by the Data Dictionary include:
- Reference field determines how the field is accessed. For example, TableDir indicates that the table name can be determined by removing the _ID from the field name. A value of List will prompt for a Reference for the List (discussed later).
- Default Logic allows for defining rules which will populate the field when creating a new record. This logic can include variables based on selections made at login time or based on the user who logged in
- Mandatory Logic allows for defining the circumstances in which this column is required.
- Callout Code allow for the execution of code when the user tabs off of the field. This is a data entry consequence and should not be used for validation (which should occur before a user leaves the field). An example of a callout is in the Sales Order window. When the user enters a Business Partner, the callout that is executed updates other fields in the window such as Price List, Delivery Rule and Partner Addess.
- Identifier indicates what displays in the field or drop down list when a user selects it. For example, when the user selects a Partner Group, the Partner Group Name not the Partner Group ID displays. It is possible to have multiple Identifiers defined and the fields will display separated by an '_'.
- TableUID indicates if the column can be used by someone who has no access to the internal table unique identifier to uniquely identify a record in the table. For example, when a user wants to look for a specific Window, she doesn't know what the AD_Window_ID is. Instead, she will use the Window Name to uniquely identify a Window record. Similarly, when Compiere is migrating a Window record, it cannot use the AD_Window_ID to uniquely identify a Window record as AD_Window_ID is not guaranteed to refer to the same record in different systems. Instead, it will use the Window Name to see if the Window already exists in the target instance. If there is no record with the same Window Name, then Compiere will insert a new record with that Window Name. If there is already a record with the same Window Name, then Compiere will compare the attributes of the two records and update the ones in the target instance if there are differences. To mark a column as an external unique identifier, set the TableUID value to an integer greater than zero. Note that you may have to set more than one column to be the external unique identifiers for the table. For example, a Tab will have both the Parent Window and Tab Name as the external unique identifiers (Tab Names should be unique for a given Window, but may be duplicated across Windows). By definition, you should not mark the internal record ID as an external unique identifiers (i.e. AD_Window.AD_Window_ID and AD_Tab.AD_Tab_ID are NOT eligible to be external unique identifiers). Do note however, that AD_Tab.AD_Window_ID is eligible to be an external unique identifiers because it describes the Parent Window of the AD_Tab record.
- Selection Column indicates what fields display in the initial search window if Search is selected. All fields on a table are available in the Advanced Search tab.
The 'Synchronize Column' button should be selected if you are creating the columns in the database or if you have changed part of the table definition (e.g. the Constraint Name or increased the Field Length).
View Components contains the FROM, WHERE, GROUP BY and HAVING clauses of the SELECT statement definition of a database view. If your database view consists of multiple SELECT statements (joined together with a UNION), a View Component is needed for each SELECT statement.
View Columns contains the SELECT clause of the SELECT statement definition of a database view.
As an example, if your database view is created with the following statement:
CREATE VIEW someView ( someViewID, someViewName) AS SELECT someID, someName FROM someTable WHERE someAttribute = 'Y'
Then the following information will be stored in the various tabs of the 'Table and Column' window:
- The 'Table' Tab will store the view name someView and the fact that this Compiere table correspond to a database view.
- The 'Column' Tab will store the names and datatype of the someViewID and someViewName view columns.
- The 'View Component' Tab will store the FROM clause FROM someTable and the WHERE clause WHERE someAttribute = 'Y' of the view SELECT statement.
- The 'View Column' Tab will store the columns someID, someName in the SELECT clause of the view SELECT statement.
WINDOW, TAB AND FIELD
The Window, Tab & Field Window defines the presentation of tables and columns within each window. Each Tab in a Window refers to a single Table. The Fields in the Tab of a Window refers to the Columns in the Table.
The Window Tab defines each window in the system. The Name and Window Type are required. The Name is what displays in the window heading. It is also the Name that displays in the Menu. The system will synchronize the Window Name with the Menu entity.
The Window Type determines the behavior of the window when the user opens it. For example if the Window Type is Maintain, then all active records are retrieved. If the Window Type is Transaction then only those records that were created or updated today or that are not Completed will be displayed. (Note that all records can be retrieved using the Search facility). Generally, when dealing with transaction windows, e.g. Invoices, you do not want to retrieve invoices that are 2 years old, you want to see what was worked on today and what still needs further work.
The Window Access Tab defines the Roles which have access to this Window. This is generally defined in the Role Window.
The Tab Tab defines each Tab within a Window. Each Tab refers to a single table. All columns on the table can be displayed but generally a specific selection of fields is used. Note that the display and read only logic (along with the default logic defined for the Table/Column) is evaluated when loading the window.
In Tab, the required fields are Name, Table, Sequence and Tab Level. The Name indicates what displays in Help text and the Table will determine what fields are available for display as well as the table that will be updated when a record is added, deleted or modified in this window tab.
The Sequence determines the order the tabs will appear in the window. By default, the system will increment the Sequence by a value of 10 for each new tab added.
The Tab Level determines is the tab is a child record of a previous tab. A Tab Level of 0 indicates it is the starting Parent Tab. A Tab Level of 1 indicates it is a child of the Parent Tab (e.g. in the Product Window, BOM tab is a child of the Product Tab). A Tab Level of 2 indicates it is a child of the previous Tab Level 1 (e.g. BOM Component is a child of the BOM Tab).
Some of the other features of the Tab definition are:
- Process indicates that a process which can print a document will be enabled for this tab. This is what will control if the Print Button on the window is enabled (e.g. on Invoice window there is a process defined and the print button is enabled and on Product window there is no process defined and the print button is not enabled).
- Single Row layout, if selected indicates that when the window opens it will display in single record mode (swing only).
- Advanced, Accounting and Translation Tab check boxes indicate if the display of this tab will be controlled, along with security, by the settings defined in Preferences.
- Display and Read Only Logic allow the definition of business rules to control the display and update of a tab. For example, in the Product Window, the BOM tab is has Read Only Logic which prevents entry of data if the BOM check box is not selected.
The Field Tab defines the Fields displayed within a tab. Changes made to the Field Tab become visible after restart due to caching. If the Sequence is negative, the record are ordered descending. Note that the name, description and help is automatically synchronized if centrally maintained.
The Name and Column are required. The columns available for selection is based on the table defined for the Tab. The Name, Description and Comment will synchronize from the Columns definition (which has synchronized from the Element definition). If, in a specific window you want to use a different field label or have a different help definition, simply enter the desired content and de-select the Centrally Maintained check box. This will prevent the synchronization of this specific field from the Table/Column values.
Some other attributes of Fields which affect the display are:
- Displayed indicates if the field will be displayed. If a field is not needed in a specific implementation you can de-select this flag. Note that if the field is required you must first ensure there is a default value defined. Also, if a field is not displayed that may compromise the field layout..
- Read Only indicates that the field will be displayed but cannot be updated. For example, if you do not want users to update the Price List in a Sales Order set the field to Read Only. The Price List field is required, but there is a default (either from the Business Partner or Tenant Level).
- Sequence and Same Line determine where it displays in the Window.
- Default Focus indicates that when a new record is entered, the user's cursor will be on this field.
- Obscure allows you to obfuscate the field (e.g. show just the last 4 digits of a credit card number). This is how it will also print on reports. However, it is stored as clear text in the database. You can encrypt fields for display and in the database by selecting Encrypted.
Context allows the definition of alternate field labels for given windows. For example, the field Business Partner means different things to the user in different Contexts. In a Sales Order, the Business Partner is 'Customer', in a Purchase Order it is 'Vendor'. The Context window defines the different contexts for the system. Different field labels are then defined for the appropriate Elements and the Context is assigned to the desired Windows.
A number of Contexts are defined (for example, Sales, Purchasing and Request). You can add new Context records if necessary.
Next for the appropriate Element new Names, Print Text, Description and Comment are added. It is not necessary to define context values for all fields. The system will use the standard element definitions if no context is defined.
Lastly, select the appropriate Context for the Window (e.g. in Sales Order the Context is defined as Sales).
Reports and Processes
In Compiere, Reports and Processes are technically the same entity. Both can have a pre-process (e.g Parameter Selection) and both can have output (e.g. Report Viewer). To a user, however they are viewed as separate entities. For that reason, they are differentiated in the Menu by the icon.
To define a Report, open the Reports and Processes window.
The Name is the Name that will display in the Menu as well as in the report header.
The Description and Comment will display in the confirmation window that displays when the user clicks on the report icon in the menu. This is a good way to provide information on what the Report or Process is used for.
The Data Access Level is used for automatic generation of Role security.
Select the Report View check box to indicate that this is a Report. This will assign the Report Icon to this menu item as well as display the appropriate fields (e.g. Report View) for further defining the report.
Enter the remaining fields as appropriate. The only other field that is required is the Report View.
The Direct Print check box indicates that the report will print automatically when the report is executed.
If desired, you can enter a Print Format to use when this report is generated. If no print format is selected.
Select the Parameter tab to define the parameters for this Report. The fields available for selection are restricted to those fields in the selected Report View.
Parameters allow for default values, required or optional and ranges for values or dates.
Any Parameters that are used when generating the report are printed in the Report header.
As mentioned previously, Processes are defined in a similar manner to Reports.
As the Report View check box is not selected the Process icon will be used in the Menu. Also, the Report View, Print Format and Direct Print fields do not display (this is an example of display logic defined for the window).
Here you will enter a Classname and/or Procedure that is associated with the Process. You can also select Server Process if this should run only on the Server (as opposed to the client when using the Swing client).
The Workflow field is used when the Process you are defining is a process that is started by the selection of a button (e.g. the Complete button on a document).
Same as Reports, Processes can also have Parameters for the user to entered when executing the process.
Forms are complex windows that are hard coded. Generally they involve data from more than one table and may have a one to many or many to many relationship. Unlike other entities, forms are defines separately in the Swing client and HTML client.
The Classname is the code that is used to generate the form for the Swing client.
The Java Classname for the WebUI is the code that is used to generate the form for the HTML UI.
If defined, the jsp URL defines the URL that is used for running the java class for the HTML UI.
Reference is used in Column (of Table and Column) to control what displays in a field and how it displays. References can be one of three different Validation Type; DataType, List or Table Validation. The type selected is generally based on how the field is used and the level of control desired.
A Validation Type of DataType is used to define different field types (e.g. Button, Date Time, Number). Generally you will not need to create new References of a Validation Type of DataType.
Here is a list of standard data types supported in Compiere :
- Account : This is used for fields that store account combinations. An example of this is the Account Combination field on the GL Journal line.
- Amount : This is a number field with 4 decimals used to represent Amounts. An example of this is the Grand Total field on Sales Orders.
- Assignment : This is used for resource assignments. An example of this is the Resource Assignments field on the Sales Order line. This is currently only supported in the Java client (Swing UI).
- Binary : This is used to store Binary Data (Blobs). For example, this is used to store attachments in the AD_Attachment table
- Button : This is used to show field as a clickable button. This can be used to launch a process. An example of this is "Copy Lines" button on the Sales Order window.
- Costs+Prices : This is used to show numeric fields. It will be shown with minimum currency precision, or more.
- Date : This is used to show date fields (with no timestamp)
- Date+Time : This is used to show date fields with timestamps
- FileName : This is used to show a local file name. This is currently only supported in the Java client (Swing UI).
- ID : This is the primary key for each table. For example, the column C_Order_ID has a reference type of ID. For each record, Compiere will automatically generate a unique value for this column using an internal sequence.
- Image : This is used to allow users to add images to windows. This is currently only supported in the Java client (Swing UI).
- Integer : This is used to represent integer values.
- List : This is used to allow users to select from a drop down list box containing list of values.
- Location (Address) : This is used for fields that contain address information. For these fields, the user will be allowed to bring up a popup where they can enter street address information. There is also a link from this popup window to Google Maps.
- Locator (WH) : This is used to show a drop down list of appropriate locators from the warehouse.
- Memo : This is used for large text fields of upto 2000 characters.
- Number : This is used for any numeric fields.
- Printer Name : This is used to allow users to choose from a list of accessible printers. This is currently only supported in the Java client (Swing UI).
- Product Attribute : This is used to bring a dynamically generated popup based on at attributes that have been added for a given product. An example of this is the Product Attributes field on the Sales Order line.
- Quantity : This is used for quantity fields. An example of this is the Quantity field on the Sales Order line.
- Search : This is used to bring up a popup (search window) where the user can enter various criteria to search for the appropriate value. An example of this is the Product field on the Sales Order line.
- String : This is used for alphanumeric string fields.
- Table : This is used for foriegn key references to other entities in the system. It will be rendered as a drop down dialog box with the identifier columns from the referenced table. If you use this data type, you have to also specify the reference key. The reference key details the table being referenced. An example of this is the column Bill_BPartner_ID in the C_Order table (used to show the Bill To on the Sales Order window).
- Table Direct : This is similar to Table references in that it is used for foreign key references to other entities in the system. The main difference is that you do not have to specify the referenced table using the reference key. Instead, the table is automatically derived by deleting the "_ID" from the table name. For example, this is used for the column M_Warehouse_ID in the C_Order table (used to show the Warehouse on the Sales Order window). In this case, the referenced table is derived from the column name to be M_Warehouse (By deleting the "_ID" from the name "M_Warehouse_ID" to get M_Warehouse). This results in the user seeing a drop down list of all the valid warehouses.
- Text : This is used for Character String of upto 2000 characters.
- Text Long : This is used for Character String of more than 2000 characters.
- Time : This is used to represent Timestamps. An example of this is the "Slot Start" field in the "Resource Type" window.
- URL : This is used to represent URLs. The user will then be able to link to the URL using the magnifying glass icon on the field.
- Yes-No : This is use to represent fields with a drop down list containing the values "Yes", "No" and an empty string. If this column is made mandatory, this field will be rendered as a checkbox in the webUI.
A Reference Validation Type of Table Validation is used when you want to present the user with a list of values for their selection and that list is based off of a table that the user may or may not have the ability to add records to.
When you select a Validation Type of Table Validation, the Table Validation tab is enabled (this is an example of read only logic defined for a Tab in Window, Tab and Field).
Here you select the Table Name and the Key column for the Table. The Display column is what will display in the drop down list box.
Select the Display Value check box to display the field value in the drop down list box.
Select the Display Identifiers check box if the list should display all fields that are indicated as identifiers for the table.
If appropriate, enter a SQL WHERE and ORDER BY clause to control what displays in the list and in what order. This is used to prevent summary organizations from appearing in the organization drop down list box in documents.
A Reference Type of List is used where you want to present the user with a list of values from which to make a selection, but that list is defined in Reference (as opposed to being derived from a table). Lists are most often used in situations where there is some logic associated with the value selected, and therefore code is involved. In those situations you need to know what the possible values could be. Examples of this are the Shipping Rule in Sales Order. These values are restricted to the list defined in Reference and the value selected impacts the Generate Shipment process. Therefore it would not be appropriate to allow users to enter any value they want.
When a Validation Type of List Validation is selected, the List Validation tab is enabled. This allows the entry of the values that will be displayed to the user for selection.
The Search Key is used to control the order the values appear in the list, while the Name is what is presented to the user for selection.
Validation Rules are used to control what is displayed for selection to a user (similar to a SQL Where Claus in a Reference entry). However, these can be used for any field type in a Column. It is selected in the Dynamic Validation Rule in Table and Column. As indicated by the name, it is dynamically executed when selecting the list or look up.
In this example, the validation is being used to ensure that the selection presented to the user contains just Locations that are defined for the Business Partner selected that have the Ship to Address check box selected. This prevents the display of locations that are associated with other Business Partners or locations that are not indicated as Ship to Addresses.
This validation is dynamic because it is based on the value selected in another field (in this case Business Partner).
As with other Data Dictionary windows in Compiere, the Validation Rule has a Used in Column tab. This is helpful if you want to change a Validation Rule as you can see from this tab what other areas of the system.
The Data Dictionary in Compiere is a powerful development tool. Much of what is done in code in a traditional system can be accomplished in the Data Dictionary. This helps to provide consistency across the application (especially when multiple developers are involved) and stability in addition to fast, agile development.
The Compiere application is full of examples which displays how different features of the dictionary work. No matter what type of extension or customization you are working on, you can generally find an instance elsewhere in the application that works in a similar manner. We suggest you use these as a reference in your own development efforts.