Most Powerful Open Source ERP

ERP5 Guideline Proxification Best Practice

Conventions for working with content layout forms used in ERP5, especially on the use on custom fields
  • Last Update:2017-04-04
  • Version:001
  • Language:en

Table of Contents

Introduction

This guideline provides rules and recommendations on how to use the field library and proxy fields in your business template. The field library is an ERP5 form not accessible by the user. It is a container of proxy (template) fields which can be used in other forms instead of recreating fields every time. Make sure to distinguish between three levels of form fields:

  • Core Template Form Fields
  • Business Template Specific Form Fields
  • Custom Form Fields

Why Field Library And Proxy Field?

Using proxy field is very useful for providing consistent UI and reducing code duplications.

For UI

For example, comment field is one of the very common fields in whole ERP5 system and it should be always the same size everywhere. Then we use proxy field, we can define the height and width only once to the template field in the core field library and the remaining is that all other comment fields just inherit the core template field. This way, we can make consistent UI easily. If we did not use proxy field, we had to set the same height and width for all comment fields one by one, this is very hard to maintain.

About field library, this is a kind of buffer between the core field library in erp5_core and the real fields to be displayed to users. We saw an example of comment field above, it was a common field globally. But sometimes we want to change an appearance of generic fields only in some business template. In such case, we cannot change the core template fields, because they are used globally. So we can change a field library of a target business template instead. Then we can customize some fields only in a business template and this does not affect UIs defined by other business templates.

For Code Reuse And Abstraction

Sometimes we can find similar patterns in ERP5. For example, when we use a RelationStringField, we often name it like "my_source_title" by following our naming convention. And from such names, we can find a pattern. The name suggests this field uses source category and searches document by title. And we can make a template field for RelationStringField and put a tales expression to parse field id and find category name and index property. Once we have such a template field which is an abstraction of a pattern we don't have to enter a category name and an index property name each time when adding RelationStringField, but just using a proxy field and inherit the template field is enough. We can omit entering various parameters and it is also useful for maintenance, future changes. Above is a very wide range example which can apply whole ERP5, but we can find many other small patterns in a specific context managed by single business template like Accounting, DMS. Therefore finding a pattern and making a template field is very practical use case of proxy field and field library.

Define Once And Applying To Many

Sometimes we have to enter the same information in multiple places. For example, a company has the same reference naming rule for Service and Product. In such case, we have to apply the same input validation functionality to Product_view.my_reference and Service_view.my_reference. Then we can say that both my_reference in Product_view and Service_view are the same in reality. In such case, we should make a template field in field library and reuse the field to inherit from proxy fields in both Product_view nd Service_view. And in this way even if the input validation rule was changed, we only have to update the template field and no need to touch proxy fields.

Recommendation

#

Field Library Fields Should Be Semantically Unified

Each field of field library should be unified semantically. For example, if our business template has these three fields my_reference, my_code and my_product_name, add those three fields to the field library. If multiple portal types (A and B) use a my_reference field and if they are semantically distinct, add two fields in the field library named my_A_reference and my_B_reference. Finally, those two fields should be proxy fields of a generic my_reference.

#

Proxy Fields Should Share Semantics

If no semantic field (business/product specific) is found, it means that the proxy field will link to a technical field (which is only defined in Base_viewFieldLibrary) directly.

If semantic fields exists, they should share semantics as much as possible

Good Example:

SaleOrder_view[my_total_price]

-> Base_viewTradeFieldLibrary[my_view_mode_total_price]
  -> Base_viewFieldLibrary[my_view_mode_money_quantity]
    -> Base_viewFieldLibrary[my_float_field]

SaleOrder_view[my_title]

-> Base_viewTradeFieldLibrary[my_view_mode_title]
  -> Base_viewFieldLibrary[my_view_mode_title]
    -> Base_viewFieldLibrary[my_string_field]
#

Semantic Field Should Be Used In Favor Of Technical Field

It is always better to proxy a field from a semantic field library (if you work in Trade, first proxy from TradeFieldLibrary before proxying a base field.

Good Example:

SaleOrder_view[my_title]

-> Base_viewTradeFieldLibrary[my_view_mode_title]
  -> Base_viewFieldLibrary[my_view_mode_title]
    -> Base_viewFieldLibrary[my_string_field]

Bad Example:

SaleOrder_view[my_title]

-> Base_viewTradeFieldLibrary[my_view_mode_title]
    -> Base_viewFieldLibrary[my_string_field]

The only exception is if a technical field is generally used for the same purpose and if it is good enough to share for all use cases. Only then we don't need the semantic field in Base_viewFieldLibrary and it is acceptable to link to the technical field directly outside from the default field library.

For example, the following is OK (not "good"), because relation string field is always used for category:

Good Example:

SaleOrder_view[my_source_title]

-> Base_viewTradeFieldLibrary[my_view_mode_source_title]
  -> Base_viewFieldLibrary[my_relation_field]

Bad Example:

SaleOrder_view[my_incoterm]

-> Base_viewTradeFieldLibrary[my_view_mode_incoterm]
    -> Base_viewFieldLibrary[my_list_field]

This is bad, because list_field can be used for different purpose. It would be better to do:

SaleOrder_view[my_incoterm]

-> Base_viewTradeFieldLibrary[my_view_mode_incoterm]
  -> Base_viewFieldLibrary[my_view_mode_category]
    -> Base_viewFieldLibrary[my_list_field]

Rule

#

A Business Template Has Only One Field Library

A business template represents one business field of a larger application. As the field libraries are used to share semantic configuration of forms, there should be only one field library per business template (even if this one contains multiple skin folders).

The only exeption is for surcharging the behaviour of a field library which is sometimes required. In this case, it is required to create another skin folder (following the convention [surcharged_context]_[original_skin_folder_name]) and an empty field library could be created to surcharge the original one.

Good Example:

# In the erp5_project BT5: 
erp5_project_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

Bad Example:

erp5_project/Base_viewTradeFieldLibrary[my_view_mode_title]

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
#

A Form Field Proxies From A Business Template Field

Normal forms contain multiple fields which should be proxy fields. Their template fields should be from the field library of the same business template. You should not proxy from a different business template nor directly from the Base_viewFieldLibrary.

#

A Proxy Field Never Links To An External Field Library

All proxy fields defined in a BT5 should link to the Field Library defined in this bt5.

Good Example:

Base_viewPDMFieldLibrary[my_view_mode_title]

-> Base_viewFieldLibrary[my_view_mode_title]
  -> ...

Bad Example:

ApparelComponent_view[my_title]

-> Base_viewApparelFieldLibrary[my_view_mode_title]
  -> Base_viewPDMFieldLibrary[my_view_mode_title]
    -> ...

ApparelComponent_view[my_title]

-> Base_viewPDMFieldLibrary[my_view_mode_title]
-> ...
  
erp5_project/PurchaseOrder_view[my_title]

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

The only exeption is for surcharging the behaviour of a field library which is sometimes required. In this case, it is required to create another skin folder (following the convention [surcharged_context]_[original_skin_folder_name]) and an empty field library could be created to surcharge the original one.

Semantic field defined in a field library could link to Base_viewFieldLibrary.

Good Example::

In the erp5_project BT5: erp5_project_trade/PurchaseOrder_view[my_title]

-> erp5_project_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
  -> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
#

Business Library Fields Proxy From Core Fields

Business field libraries contain several fields which would be mostly proxy fields. Their template fields would be in field libraries of erp5_core (core field libraries).

#

Only Use Proxy Fields In Non Field Library Forms

To prevent excessive customizations.

#

Semantic Field Is Named Using My Prefix, Technical Context And Semantic Name

All semantic template field defined in a field library should be proxy fields (either of a semantic or a technical field). Some technical contexts may be:

  • A form in view mode
  • A form in list mode
  • A form in dialog mode
  • A form in report mode

The technical context is important, because we do not always display things in the same way and there can be different technical configurations depending on the technical context. This naming should be used for all non-technical fields in field libraries:

my_[technical_context_name][semantic_name]

with technical_context_name having such values:

  • list_mode
  • view_mode
  • dialog_mode
  • report_mode
  • core_mode (if we wish to define fields in library that are independant of the technical context).

Good Example:

OrderModule_viewOrderReport[your_order]

-> Base_viewTradeFieldLibrary[my_report_mode_order]
  -> Base_viewFieldLibrary[my_report_mode_category]
    -> Base_viewFieldLibrary[my_core_mode_category]
      -> Base_viewFieldLibrary[my_list_field]

OrderModule_viewOrderReportDialog[your_at_date]

-> Base_viewTradeFieldLibrary[my_dialog_mode_at_date]
  -> Base_viewFieldLibrary[my_dialog_mode_at_date]
    -> Base_viewFieldLibrary[my_date_time_field

SaleOrder_view[my_title]

-> Base_viewTradeFieldLibrary[my_view_mode_title]
  -> Base_viewFieldLibrary[my_view_mode_title]
    -> Base_viewFieldLibrary[my_core_mode_title]
      -> Base_viewFieldLibrary[my_string_field]

Base_viewStockReportBySite[your_site_title]

-> Base_viewTradeFieldLibrary[my_report_mode_title]
  -> Base_viewFieldLibrary[my_report_mode_title]
    -> Base_viewFieldLibrary[my_core_mode_title]
      -> Base_viewFieldLibrary[my_string_field]

SaleOrder_view[my_source_section]

-> Base_viewTradeFieldLibrary[my_view_mode_sale_source_section]
  -> Base_viewFieldLibrary[my_list_field]

SaleOrder_view[listbox]

-> Base_viewTradeFieldLibrary[my_view_mode_listbox]
  -> Base_viewFieldLibrary[my_view_mode_listbox]
    -> Base_viewFieldLibrary[my_listbox]
#

Technical Template Fields Are Defined In Base_viewFieldLibrary

As the technical fields have no semantic it is useless to duplicate them in each field library. Therefore only Base_viewFieldLibrary should contain technical field library. This will ease maintenance (no need to update all field libraries if a new technical field are created).

Bad Example:

Base_viewTradeFieldLibrary[my_listbox]
Base_viewTradeFieldLibrary[my_multi_list_field]
#

Use Base_view Prefix Followed By Business Filed and FieldLibrary For Field Library Title

The basic naming pattern is Base_view[Business Field]FieldLibrary. Replace the placeholder with your business template name.

Good Example:

erp5_trade:
  -> Base_viewTradeFieldLibrary
  
  erp5_pdm
  -> Base_viewPDMFieldLibrary
#

Use Glossary Defined Prefix For Specific Semantics

for Arrow there is a specific semantic for trade, sometimes there is the point of view of the seller, sometimes from the buyer (and even sometimes it's only internal movement, I didn't worked on it yet). So here for every field about source/destination, I use 2 different names with "sale" or "purchase" inside:

Good Example:

SaleOrder_view[my_source_section]

-> Base_viewTradeFieldLibrary[my_sale_source_section]
-> Base_viewFieldLibrary[my_list_field]

PurchaseOrder_view[my_destination_section]

-> Base_viewTradeFieldLibrary[my_purchase_destination_section]
-> Base_viewFieldLibrary[my_list_field]

Please try as much as possible to utilize prefix which are consistent with those defined in business_fields of the Glossary.

#

Use My Prefix and Class Name For Template Field Name

This is a convention to prevent creating multiple technical template fields (for example for view, dialog, report) related to the same field class.

Good Example:

Base_viewFieldLibrary[my_listbox]
Base_viewFieldLibrary[my_string_field]

Bad Example:

Base_viewFieldLibrary[listbox]
Base_viewFieldLibrary[your_string_field]