Commit Graph
17 Commits
Author SHA1 Message Date
Denis Ledoux 3752b3166e [REF] base: set USD as default currency for the main company
There are three rationales behind this change to set USD as default
currency and to enable it in the demo data, from the beginning.
With a demo database, before this revision:
1. On runbot, with all modules installed, it's already USD the default
   company currency. It's only when you install a module not depending
   on account that it's EUR the company currency by default (e.g. CRM)
2. in the base demo data,
   the company is set in the United States but with the currency EUR,
3. before installing account, the company currency is EUR,
   after installing account, the company currency is USD,
   this is due to the fact as the company is in the United States,
   the US Chart Of Account is installed, switching the company currency
   to USD.
4. when you install a demo database with a module not depending on
   account, you are left with a database without any active currency,
   and the monetary fields therefore do not show any currency.
   For instance, install only CRM with demo,
   you have no currency symbol before or after the expected revenue,
   which is not the best user friendly experience.
   On runbot you do not feel it because all modules are installed,
   therefore with account installed, which activated the USD currency.

Additional weird thing with point 2.:
- Unit tests in modules not dependent on account with the
  post-install tag had to handle this sudden change of currency change
  before and after installing account.
  For instance, when running their unit tests with only their module,
  but not account, the company currency is EUR,
  but when executing the same unit test with all modules installed,
  the company currency is USD.
  The unit tests had to handle this sudden change within the unit test,
  for instance by setting a 1.0 rate for their own company currency,
  which shouldn't be the case: the rate of your own currency should
  always be 1.0.

closes odoo/odoo#107113

Related: odoo/enterprise#34613
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2022-12-13 11:47:49 +01:00
ef00294e71 [IMP] core: store translated fields as JSONB columns
Translated fields no longer use the model ir.translation.  Instead they store
all their values as JSON, and store them into JSONB columns in the model's
table.  The field's column value is either NULL or a JSON dict mapping language
codes to text (the field's value in the corresponding language), and must
contain an entry for key 'en_US' (as it is used as a fallback for all other
languages).  Empty text is allowed in translation values, but not NULL.

Here are examples for a field with translate=True:

    NULL
    {"en_US": "Foo"}
    {"en_US": "Foo", "fr_FR": "Bar", "nl_NL": "Baz"}
    {"en_US": "Foo", "fr_FR": "", "nl_NL": "Baz"}

Like before, writing False to the field makes it NULL, i.e., False in all
languages.  However, writing "" to the field makes its value empty in the
current language, but does not discard the values in the other languages.

Here are examples for a field with translate=xml_translate:

    NULL
    {"en_US": "<div>Foo<p>Bar</p></div>", "fr_FR": "<div>Fou<p>Barre</p></div>"}

Change for callable(translate) fields: one can now write any value in any
language on such a field.  The new value will be adapted in all languages, based
on the mapping of terms between languages in the old values.  Basically the
structure of the value must remain the same in all languages, like before.

Reading a translated field is now both simpler and faster than the former
implementation.  We fetch the value of the field in the current language by
coalescing its value with the 'en_US' value of the field:

    SELECT id, COALESCE(name->>'fr_FR', name->>'en_US') AS name ...

The raw cache of the field contains either None or a dict which is conceptually
a subset of the JSON value in database (except for missing languages).  For the
sake of simplicity, most cache operations deal with the dict and return the text
value in the current language.

Trigram indexes have been adapted to the new storing strategy, and should enable
to search in any language.  Before this change, only the source value of the
field ('en_US') could be indexed.

Computed stored translated fields are not supported by the framework, because of
the complexity of the computation itself: the field would need to be computed in
all active languages.  We chose to not provide any hook to compute a field in
all languages at once, and the framework always invokes a compute method once to
recompute it.

Code translations are no longer stored into the database.  They become static,
and are extracted from the PO files when needed.  The worker simply uses a cache
with extracted code translations for performance.  This is reasonable, since
fr_FR code translations for all modules takes around 2MB of memory, and the
cache can be shared among all registries in the worker.  Changing code
translations requires to update the corresponding PO file and reloading the
worker(s).

Performance summary:
 (+) reading 'model' translated fields is faster
 (+) reading 'model_terms' translated fields is much faster (no need to inject
     translations into the source value)
 (+) searching translated fields with operator 'ilike' is much faster when the
     field is indexed with 'trigram'
 (+) updating translated fields requires less ORM flushing
 (-) importing translations from PO files is 2x slower

Some extra fixes:
 - make field 'name' of ir.actions.actions translated; because of the PG
   inheritance, this is necessary to make the column definition consistent in
   all models that inherit from ir.actions.actions.
 - add some backend API for the web/website client for editing translations
 - move methods get_field_string() to model ir.model.fields
 - move _load_module_terms to model ir.module.module
 - adapt tests in test_impex, test_new_api
 - because env.lang is injected into SQL queries, its returned value is
   now guaranteed to correspond to a valid active language or None
 - remove wizard to insert missing translations (no longer makes sense)

task-id: 2081307

Co-authored-by: Fabien Pinckaers <fp@openerp.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
2022-09-15 22:37:50 +02:00
Vincent Schippefilt 9a5d575406 [IMP] base: unused fields in ir_module_dependency
The table ir_module_dependency was created manually with tracking fields,
but the CRUD was done manually, without the ORM.
Removing the fields that are always null will not have any impact
whatsoever but we should still do it to be correct.

closes odoo/odoo#89268

Related: odoo/upgrade#3455
Signed-off-by: Rémy Voet <ryv@odoo.com>
2022-06-16 18:31:56 +02:00
Fabien Pinckaers e045e76e35 [IMP] base: reduce new DB size by ordering columns
Postgres is aligning columns to 4 or 8 bytes, depending on their type.
So, consecutive fixed-length columns of differing size will be padded
with empty bytes due to the alignment requirements.

Before this patch, columns where created in their definition order. Now,
they are ordered based on their size, in order to minimize the padding.

As an example, before each row uses 36 bytes (+24b header):

       attname   |  typname  | typlen
    -------------+-----------+--------
     id          | int4      |      4
     create_uid  | int4      |      4
     create_date | timestamp |      8
     write_uid   | int4      |      4    -> 4 bytes padding
     write_date  | timestamp |      8
     active      | bool      |      1    -> 3 bytes padding

After each row uses 32 bytes (4 bytes saved per row):

       attname   |  typname  | typlen
    -------------+-----------+--------
     id          | int4      |      4
     create_uid  | int4      |      4
     write_uid   | int4      |      4
     active      | bool      |      1    -> 3 bytes padding
     create_date | timestamp |      8
     write_date  | timestamp |      8

This saving scheme applies to all rows in all tables. We save between 4
and 8 bytes per row just on the usual create_uid, create_date,
write_uid, write_date.

closes odoo/odoo#87896

Signed-off-by: Raphael Collet <rco@odoo.com>
2022-04-05 17:17:27 +02:00
Vincent Schippefilt e5523f06ce [FIX] base: unique module name declared twice
before this commit, there was 2 unique indexes on module name
after this commit, only 1 unique index remains (the one declared in base/ir_module.py) to keep the error message

closes odoo/odoo#85116

Signed-off-by: Raphael Collet <rco@odoo.com>
2022-02-22 15:20:13 +00:00
Ivan Yelizariev f0eb701360 [FIX] base_data.sql: remove obsolete field size
those field sizes were deleted from orm definition in 2014 https://github.com/odoo/odoo/commit/026e38b48f3963aed08bba4e76a0a796d662f6a4

STEPS:
* set manifest's summary attribute to a long string
* create empty database

BEFORE: error

```
2020-12-28 10:44:51,325 1 ERROR ? odoo.sql_db: bad query: UPDATE ir_module_module SET state='installed' WHERE state IN ('to remove', 'to upgrade')
ERROR: relation "ir_module_module" does not exist
LINE 1: UPDATE ir_module_module SET state='installed' WHERE state IN...
               ^

2020-12-28 10:44:51,325 1 ERROR ? odoo.modules.registry: Failed to load registry
Traceback (most recent call last):
  File "/opt/odoo/custom/src/odoo/odoo/modules/registry.py", line 86, in new
    odoo.modules.load_modules(registry._db, force_demo, status, update_module)
  File "/opt/odoo/custom/src/odoo/odoo/modules/loading.py", line 338, in load_modules
    odoo.modules.db.initialize(cr)
  File "/opt/odoo/custom/src/odoo/odoo/modules/db.py", line 63, in initialize
    info['sequence'], info['summary']))
  File "/opt/odoo/custom/src/odoo/odoo/sql_db.py", line 173, in wrapper
    return f(self, *args, **kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/sql_db.py", line 250, in execute
    res = self._obj.execute(query, params)
psycopg2.DataError: value too long for type character varying(256)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/odoo/custom/src/odoo/odoo/modules/registry.py", line 88, in new
    odoo.modules.reset_modules_state(db_name)
  File "/opt/odoo/custom/src/odoo/odoo/modules/loading.py", line 558, in reset_modules_state
    "UPDATE ir_module_module SET state='installed' WHERE state IN ('to remove', 'to upgrade')"
  File "/opt/odoo/custom/src/odoo/odoo/sql_db.py", line 173, in wrapper
    return f(self, *args, **kwargs)
  File "/opt/odoo/custom/src/odoo/odoo/sql_db.py", line 250, in execute
    res = self._obj.execute(query, params)
psycopg2.ProgrammingError: relation "ir_module_module" does not exist
LINE 1: UPDATE ir_module_module SET state='installed' WHERE state IN...
```

AFTER: database successfully created

---

opw-2415057

closes odoo/odoo#63912

X-original-commit: 2a44e233deffd17460e0e9a8f8225602a28c24a6
Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
2020-12-30 11:50:07 +00:00
Xavier Morel 148f3dabc9 [IMP] base: make ir.model.data use access fields
Apparently some "core objects" used to have a pair of
fields (date_init, date_update) which predate the current access
fields (hopefully anyway, the genesis of both is lost to time so we
can only speculate).

odoo/odoo#34988 removed them on constrains & relations and left them
on ir.model.data, but they do seem redundant with the regular access
fields which *are* enabled on ir.model.data.

* removes the date_init/date_update fields
* converts the one bit of code which did set those to set
  create_date/write_date
* add a default value on the columns, to ensure create_date is
  properly set even from SQL queries
* use create_date/write_date in the view
* adds setting those columns to a bunch of raw SQL queries which were
  missing them (also updates the queries some to merge the literal
  values into the queries as it seems unnecessary to interpolate
  e.g. a boolean literal)

Builds on and closes odoo/odoo#50516 as that's why I started looking
into it, and that fix is in this branch as well.

closes odoo/odoo#50661

Related: odoo/upgrade#1213
Related: odoo/enterprise#10772
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-05-27 06:16:01 +00:00
Raphael Collet 9920f20e4c [IMP] models: ORM speedup
This branch is the combination of several optimizations in the ORM:

* store field values once in the cache: the cache reflects more
faithfully the database, only fields that explicitly depend on the
context have an extra indirection in the cache;

* delay recomputations by default: use method `recompute` to explicitly
flush out pending recomputations;

* delay updates in method `write`: updates are stored in a data
structure that can be flushed efficiently to the database with method
`flush` (which also flush out recomputations);

* make method `modified` take advantage of inverse fields to inverse
dependencies;

* filter records by evaluating a domain on records in Python;

* a computed field with `readonly=False` behaves like a normal field
with an onchange method;

* computed fields are computed in superuser mode by default.

Work done by Toufik Ben Jaa, Raphael Collet, Denis Ledoux and Fabien
Pinckaers.

closes odoo/odoo#35659

Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
2019-08-20 12:43:59 +00:00
Xavier Morel 2cc7f0dd49 [IMP] core: allow auto_install restriction on a subset of dependencies
Currently, auto_install is triggered when all dependencies get
installed, but there are cases where one would want such trigger on
only a subset thereof.

e.g. we want `website_sale_dashboard` to auto-install when
`website_sale` is installed. Currently, it requires `web_dashboard` to
also be auto-installed otherwise `website_sale_dashboard` would "wait"
for both dependencies to be explicitly installed before the
auto-install triggers. That's despite `web_dashboard` not being very
useful on its own. More generally this is an issue with technical
modules which need to be marked as auto_install so as not to block
e.g. bridge modules from automatically installing.

This change allows setting `auto_install` to a subset of `depends`:

* if auto_install is set to `False`, the module does not get
automatically installed (no change in semantics)
* if auto_install is set to `True`, the module gets automatically
installed if and only if all its dependencies are installed (also no
change in semantics)
* if auto_install is set to a list of dependencies, the module will be
installed when all *these* dependencies are installed, other
dependencies (excluded from auto_install) will be installed
alongside as a consequence
* auto_install can be set to an empty list, in this case the module
will always be automatically installed regardless of its
dependencies (and will force their installation).

So after this change, `web_dashboard`'s auto_install can be set to
`False` (such that it's not installed if no module defining dashboards
is installed) and `website_sale_dashboard`'s manifest can be edited
to:

'auto_install': ['website_sale']

possibilities:

# no automatic installation
'depends': ['a', 'b'],
'auto_install': False

# automatic installation if both a and b are installed
'depends': ['a', 'b'],
'auto_install': True

# automatic installation if both a and b are installed (explicit)
'depends': ['a', 'b'],
'auto_install': ['a', 'b']

# automatic installation if b is installed, a will get forcefully
# installed if it isn't yet
'depends': ['a', 'b'],
'auto_install': ['b']

# always automatically installed, will cause the installation of
# its dependencies even if they're not marked explicitly
'depends': ['a', 'b'],
'auto_install': []

Task 1851328

closes odoo/odoo#29431

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2019-05-07 11:44:26 +00:00
Christophe Simonis b81c2bce84 [MERGE] forward port branch saas-11.4 up to 3c108977c1 2018-10-22 16:59:51 +02:00
Christophe Simonis 0fcb28c97b [MERGE] forward port branch saas-11.3 up to d82a907728 2018-10-19 14:32:09 +02:00
Christophe Simonis f2ada1560e [MERGE] forward port branch 11.0 up to 22a13073f0 2018-10-19 12:25:17 +02:00
Raphael Collet 2f7c03d9ca [IMP] base: add regular user admin as uid 2
User 1 simply becomes a technical user (inactive, no password).
2018-08-23 21:38:57 +02:00
Fabien Pinckaers 7c8ab8a574 [IMP] base: improve kanban of modules, cards not clickable (top-right menu)
[NEW] base: show enterprise module, with an 'upgrade' button
[IMP] *: some modules renaming, and improved copywriting of manifest
[IMP] *: utm on links to odoo.com
2018-08-06 00:29:51 +02:00
xmo-odoo a06066b920 [IMP] merge auth_crypt into base
* store hashed passwords in the `password` column but gate it behind a
  computed field
* make the password field essentially write-only (SQL aside)
* add a "plaintext" hash type so it's possible to set the password in
  SQL directly & be able to login & have it automatically updated

Task 34211
2018-05-24 14:43:31 +02:00
Martin Trigaux b661881e35 [IMP] base: set a create_date on first records
create_date is not required but may be assumed as always set such as in
base.partner.merge comparison
The administrator had no create_date set

Avoid errors in merge wizard if one of the record has no create_date

Fixes #22730
2018-03-12 14:31:05 +01:00
Thibault Delavallée ca1a207aa3 [MOV] base: move base.sql to data/base_data.sql 2017-11-27 11:13:39 +01:00