Most Powerful Open Source ERP

Guideline Form Proxification

[out-of-date] Please use individual guidelines.
  • Last Update:2017-03-27
  • Version:001
  • Language:en

This document provides patterns and rules for working with content layout forms used in ERP5, especially on the use on custom fields.

Table of Contents

Guideline for field library

This guideline provides an advice of how to make field library in your business template.

Field library is an ERP5 form which will not be accessed from users but used as a container of proxy fields used as template field by other fields contained in other real forms and reports. In other words, it is a collection of template fields of proxy fields commonly used in a business template.

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/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.

Rules

Create only 1 field library per business template

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

Exception

It is sometimes required to surcharge the behaviour of a field library. 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.

Example:

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

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

But, this other example should never happen:

erp5_project/Base_viewTradeFieldLibrary[my_view_mode_title]

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

No proxy field linking to an external field library are allowed

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

Here are some examples that should never happen:

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]
-> ...

Exceptions

Semantic field defined in a field library could link to Base_viewFieldLibrary

Example:

Base_viewPDMFieldLibrary[my_view_mode_title]

-> Base_viewFieldLibrary[my_view_mode_title]
  -> ...

Surcharged skin folder

It is sometimes required to surcharge the behaviour of a skin folder. In this case, it is required to create another skin folder (following the convention [surcharged_context]_[original_skin_folder_name]) and forms contained in this skin folder could link to the field library defined in the original BT5.

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]

But, this other example should never happen:

erp5_project/PurchaseOrder_view[my_title]

-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]

Technical template field should only be defined in Base_viewFieldLibrary

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

Here are some examples that should never happen:

Base_viewTradeFieldLibrary[my_listbox]
Base_viewTradeFieldLibrary[my_multi_list_field]

Technical template field name should follow the my_FIELD_CLASS_NAME convention

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

Here are some example that should never happen:

Base_viewFieldLibrary[listbox]
Base_viewFieldLibrary[your_string_field]

Instead, it should be:

Base_viewFieldLibrary[my_listbox]
Base_viewFieldLibrary[my_string_field]

Semantic template field should use proxy field class

All semantic template field defined in a field library should be proxy field (either of semantic or technical field).

The semantic field name needs to be associated with the technical context

Here some examples of technical context :

  • 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, we do not always display things in the same way, and we can have different technical configuration 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).

So we can have :

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]

Non-field library forms should only contain proxy field

Proxy field should share semantic if possible

Nothing particular for many fields, share semantic:

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]

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

If some specific semantic needed, use prefix consistent with those defined in glossary

Example:

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:

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 use prefix which are consistent with those defined in business_fields of the Glossary.

Sharing semantic as priority other sharing technical

SaleOrder_view[my_title]

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

should not be:

SaleOrder_view[my_title]

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

Exception

If a technical field is always used for the same purpose and if it is good enough to share for all usages, we don't need semantic field in Base_viewFieldLibrary and it is acceptable to link to the technical field directly outside from the default field library.

This is OK, because relation string field is always used for category:

SaleOrder_view[my_source_title]

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

this is bad, because list_field can be used for different purpose :

SaleOrder_view[my_incoterm]

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

the above one should be:

SaleOrder_view[my_incoterm]

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

Guideline

In each business field should have only one field library. Before we added many field libraries in a business template and it was hard to understand each form dependencies and was also hard to maintain.

Field library would be only one in your business template, then let's define naming rule. we follow the names of core field libraries.

Basic naming pattern is Base_view(???)FieldLibrary. (???) would be replaced with your business template name. For example:

  • For erp5_trade, the name is Base_viewTradeFieldLibrary.
  • For erp5_pdm, the name is Base_viewPDMFieldLibrary.

Structure of form and field library in a non-core business template would be following:

  • Normal form contains several fields which would be proxy field. Their template fields would be in field library of the same business template.
  • Field library contains several fields which would be mostly proxy field. Their template fields would be in field libraries of erp5_core(core field libraries).

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 my_reference, my_code and my_product_name in the field library. If multiple portal types ( A and B ) use a my_reference field and if they are semantically distinct, add 2 fields in the field library named my_A_reference and my_B_reference. Finally, those 2 fields will be proxy fields of a generic my_reference.

A procedure of making field library is following:

  • Add normal fields and forms to your business template.
  • Add only one field library in your business template.
  • Unify existing fields semantically and make their template fields to your field library. Those template fields should be proxy field of core field libraries.
  • Find fields which match common type defined in erp5_core.Base_viewFieldLibrary(my_view_mode_title for example) and add template fields to the field library of your business template.

Utilities

There are some utility scripts in erp5_forge/erp5_toolbox skin folder.

  • SkinsTool_getDeadProxyFieldList: This is useful to find dead proxy fields if you have existing customized forms in your custom business template and have to merge the recent field library changes.
  • Base_checkSkinFolderForms: This is useful to check that proxification did not modify behaviour of the forms.

Use Cases

Questions

Q:
The appearance of list fields must be different possibly for region, role, function etc.?

A:
As field library are organized semantically, there will be category specific template fields like my_region, my_role, my_function in a local field library. In this way you can unify many my_region fields in your business template to one and can customize as you want.

Q:
source_title is a different field with different UI possibly between ticket and event (ie. This means source_title field for ticket probably uses proxy field of another skin than crm)?

A:
You must add my_event_source_title and my_ticket_source_title as a special template field and this template field should inherit a normal source_title.proxy order will be following:

(Ticket is a special case)

Ticket_view.my_source_title
Base_viewCRMFieldLibrary.my_ticket_source_title
Base_viewCRMFieldLibrary.my_relation_field
Base_viewFieldLibrary.my_relation_field
(Event is a normal case)

Event_view.my_source_title
Base_viewCRMFieldLibrary.my_relation_field
Base_viewFieldLibrary.my_relation_field

In this way we can handle both special case and normal case in one local field library and because everything is in one local field library, it is easy to understand proxy field dependencies.

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

Q:
What about localised form boxes (ex.. Japanese address is not same as French and FormBox must be used)

A:
I think there is nothing special about proxifying formbox. FormBox job is just choosing an appropriate erp5 form to embed by user language. Probably we define a naming rule for it and prepare a template field and enter a clever tales expression to extract required values to make it work, just like RelationStringField.

Q:
What about fields with a lot of many specific semantic (ex. Resources in a purchase order line should be of category use/component whereas resources in a sale order line should be of category use/product)

A:
I think preparing a template field per specific semantic is enough. In above example, add my_purchase_resource as a template field and use it from proxy fields of PurchaseOrderLine and PurchaseOrderCell.Then Add my_sale_resource as another template field and use it from another proxy fields.

Q:
If it's only used in one form, is it useful to have proxy field ? it's same amount of work to maintain customized field library than to maintain customized form.

A:
Good point. Having a proxy field is useful, because almost all fields should follow user's preference and proxy field is the most useful way to realize it. But I don't think it is useful to have dedicated proxy field for each field. That's why the current field library provides very few template fields and basically proxy is made per data type. But there is another opinion. Because we cannot assume future customisation requirement, and if we want to customise such minor fields which is used only once in standard business template, then we have to make a proxy field from scratch and it is boring. So that all fields should be replaced with proxy field. This is another opinion and we consider to realize this idea now.

Q:
Why some fields in the form displayed to the user might be not proxy fields ? Isn't it better to make ALL of them proxy field ? I can understand exceptions for project's specific forms, but it might be better to do no exception on generic business templates.

A:
Yes, all fields in generic business templates should be proxy fields. If you find a non-proxy field, it is a mistake, a bug.

Q:
Why is it better to use proxy fields in generic business templates ?

A:
It allows easier customization in customer projects and help having consistent user interface.

Missing

  • a tool to rename proxy fields
  • a tool to merge proxy fields
  • naming conventions for proxied listbox fields in the field library
  • naming conventions for proxy fields (ex. my_source_title)

Related Articles