Daily updates from Odoo
Friday, August 18, 2023
3 changes · master
Code cleanup and technical improvements
This update standardizes how text is prepared for translation across many Odoo Enterprise screens. It helps ensure labels and titles in the interface are correctly picked up for translation, improving consistency for users working in different languages.
Original PR description
In this commit, all usages of env._t() are replaced by _t(). In templates files, env._t() didn't work because terms used in attributes where not extracted into the translation files. Only string are exported from .xml files to translation files. So, to make it works, we set a variable that is then used in attributes. For example : ``` <t t-set="string_to_translate">String to translate</t> <Dialog title="string_to_translate>...</Dialog> ``` task-3292454 PR Community : https://github.com/odoo/odoo/pull/131390
Knowledge articles now render embedded views and links directly in the browser instead of depending on server-side rendering. This simplifies the underlying Knowledge setup while keeping existing embedded content compatible, which should make the feature easier to maintain and more responsive for users.
Original PR description
This commit allows to do all the rendering for Embedded views in frontend, without relying on an rpc call and backend rendering. This cleans up the knowledge_article model and centralizes templates used as Behavior blueprints in `knowledge_editor.xml` Since [1], favorites for embedded views are saved in the HTML arch of the body, and do not create real `ir.filters` records. This means that we can now use xml ids for embedded views without interfering on the original view in its original module. XmlId of the action window now becomes the default stored information to refer to it in an embed, but act_window objects are still supported. [1]: https://github.com/odoo/enterprise/commit/cc7afb66f09e11329fc2721d8bf33e2de66b1a36 Task-3284243
This update standardizes how Odoo decides when fields and sections are required, read-only, or hidden in business screens. It makes accounting and related views easier to maintain and validates screen definitions more accurately, reducing future configuration errors.
Original PR description
Goal abstract =================== * Simplify the way to define modifiers (*required*, *readonly*, *invisible*, *column_invisible*); * Use python expression in view to define modifiers; * Clean python…
Goal abstract
===================
* Simplify the way to define modifiers (*required*, *readonly*, *invisible*, *column_invisible*);
* Use python expression in view to define modifiers;
* Clean python field and remove some keys;
* More accurate validation of xml views.
Operation before change
===================
Problem before the changes: it was difficult to be able to create a view
using modifiers. There were different ways to describe these modifiers
and each way interacted with the others. Here are the different ways
they existed to describe a modifier:
* the *required*, *readonly* and *invisible* attributes could have
values of *True*, *False*, 1, 0 or a python expression to use the
context.
(eg: `<page invisible="not context.get('show_me')"/>` )
* the *attrs* attribute define a dict. The key of this dict was
*required*, *readonly* and *invisible* and the values are the domain or
a string representing a domain to be evaluate as python expression.
This python expressions was evaluated by the javascript with view fields
and other contextual values such as: context, uid, parent, active_id,
active_ids, active_model, allowed_company_ids, current_company_id.
(eg: `<field name="total" attrs="{'invisible': [('name', '=', 'red')], 'required': "[('tag_id', 'in', uid)]"}"/>`)
* the *states* attribute in the view was a comma separated list of the
state. This list was combined with the *invisible* attribute.
(eg: `<page states="draft,done">`)
* the key on python field is used as default value (including *invisible*).
(eg: `fields.Boolean(invisible=True)`)
* the *states* key on python field was dictionary with state as
key and list of tuple. This structure was combined with *readonly* view
attribute.
(eg: `fields.Boolean(readonly=True, states={'draft': [('readonly', False)], 'done': [('readonly', False)]})`)
After combining this different ways (with a post-processing in python then an
evaluation in JavaScript), the resulting domains of the different attributes
*required*, *readonly* and *invisible* are evaluated (in JavaScript) with the
values of the fields available in the view. The *invisible* attributes is splitted
into two use: *invisible* and *column_invisible*.
Goal
====
Simplify the way to define modifiers (*required*, *readonly*, *invisible*,
*column_invisible*).
Users will be able to define modifiers in the view using python expressions.
These will be evaluated using the values of the fields available in the view,
as well as various contextual values (*context*, *uid*, *parent*, *active_id*,
*active_ids*, *active_model*, *allowed_company_ids*, *current_company_id*).
This evaluation will be done by JavaScript (py.js library). Its expressions
don't need to be evaluated by python. Unlike before, views no longer
have post-processing to modify them.
Example
=======
```xml
<field name="field_a"
readonly="not context.get('show_a')"
attrs="{'readonly': [('field_b', '!=', False), ('field_c', '=', parent.c)]}"/>
<field name="field_b"
states="draft"/>
```
will be replaced by
```xml
<field name="field_a"
readonly="not context.get('show_a') or field_b and field_c == parent.c"/>
<field name="field_b"
invisible="state != 'draft'"/>
```
Some inherited views will be modified differently in order to maintain
the previous behavior:
```xml
<field name="field_a"
readonly="not context.get('show_a')"
attrs="{'invisible': [('field_b', '!=', False)]}">
```
```xml
<field name="field_a" position="attributes">
<attribute name="attrs">{'readonly': [('field_c', '=', False)], 'invisible': [('field_d', '!=', '3')]}<attribute>
</field>
```
will be replaced by
```xml
<field name="field_a"
readonly="not context.get('show_a')"
invisible="field_b">
```
```xml
<field name="field_a" position="attributes">
<attribute name="readonly" add="(not field_c)" separator=" or "/>
<attribute name="invisible">field_d != 3<attribute>
</field>
```
Validation
========
A stricter control is made on the level of the attributes (modifiers and domain)
The domains, and python expressions are parsed and every name of dynamic values are extracted. The field names used in the expressions must be present in the view.
The use of the previous attributes *attr* and *states* triggers an
error (these no longer exist after the application of the migration script)
https://github.com/odoo/odoo/pull/104741
https://github.com/odoo/upgrade/pull/4884
https://github.com/odoo/documentation/pull/3523
task-2495504