Before, en_US was almost always the default in case of 'no language'.
Now, that should be superseded by lang=None;
yet still, en_US plays the role of source language.
In a multilanguage database where en_US was not installed,
writing a translation with lang=None would crash.
This could prevent module installation.
A test is added to cover that case.
In the case where we write a record with lang=None, the source is the
same as the record; in that case the cache contains the value for the
field.name under the context keys en_US and None, so we need to
invalidate the cache to avoid getting back the old value.
co-authored with mart-e
opw 2088487
opw 2083710
closesodoo/odoo#39130
X-original-commit: 1a5a999c2dd69c9a6a2dacb59e8bf45b09c6bc13
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
The default `compute_sudo=True` makes sense for recomputing stored
fields that are indirectly related to a business operation. This
ensures that the recomputation of the field does not break an operation
that is not aware of the fields to recompute.
However, computing non-stored fields in superuser mode is usually not
necessary. It even leads to unexpected values: counting a partner's
sales orders does not give the same result in superuser mode as in
normal mode. That is why non-stored fields are not computed in
superuser mode by default.
[FIX] account, delivery, event, hr_recruitment, point_of_sale, stock:
adapt the model definition to make all fields with the same compute
method have the same value for `compute_sudo`.
[FIX] sale: split the computation of `invoice_ids`, `invoice_count`
(non-stored) and `invoice_status` (stored), as no code is actually
shared.
closesodoo/odoo#39195
X-original-commit: 843fd38a97f02b49dc09d7f55919072d272fd80e
Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
This commits fixes user duplication.
Suppose there is a monetary field, with a currency_field that is a related.
When going through model's _create, we do:
`if field.type in ('one2many', 'many2many'):
self.env.cache.set(record, field, ())`
knowing that thse values are false, with the intent to clean them later:
`for record, field in cachetoclear`
However, when setting the scalar values, we go through:
`accessing cache_value = field.convert_to_cache(value, record)`
In the case of the monetary field, this depends on another field value
(the currency_field). If it is a related, we can access its value.
However, at this point, if we check any access rights, we might use the value
of a relational in cache for which the value is incorrectly set to False.
In the case of the user, this is what happens: it inherits its currency_id
from partner, as well as its debit_limit which depends on it.
When the access if checked, company_ids is set to False in cache.
So when going through the rule 'user rule', which checks that the company_ids
intersects with the env.companies.ids, the result is always False.
In some way this is essentially hiding the problem, but the true fix is
probably not feasible in stable.
opw 2086661closesodoo/odoo#39017
X-original-commit: aa05a9359b42317261c8e7ffcadbeb9fe74dcd58
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
This fixes a regression introduced by 291a0e99d137142bd24addd1054c1357ddd7125a.
closesodoo/odoo#39178
X-original-commit: 852ee32e3419c210a3844b0f943af8dd2bbdae88
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Before this commit, if `max_width` and `max_height` are 0, the image would not
be opened by Pillow at all (to gain a bit of CPU) however this was actually a
bad idea in this case because then we don't ensure the given value is actually a
valid image when we save it, only later at display we notice it and it crashes.
This optimization only made sense when `image_process` is called many times,
from the route displaying images every time a visitor is requesting an image,
for example. It doesn't really have an impact for one time operations such as
creating/writing.
So when size parameters are 0, which is the default, another parameter must be
passed to `image_process` to ensure image validity, and `verify_resolution` is
actually built for this, as it does the minimal amount of processing:
- loading the image
- making sure it is valid
- and ensuring the resolution is not completely crazy (`IMAGE_MAX_RESOLUTION`).
It doesn't alter the original image if no other operation was requested.
Pr: #38292
X-original-commit: e16c36bb4bfa3ae1739712c69c72849665a057dd
Binary fields are supposed to be saved as binary in cache, and not as string
which is also supported as an input value.
Pr: #38292
X-original-commit: 64e0d106adccd8132cbfeb6b60da74b3feaf05e1
The compute methods are always expecting the real value and not the bin_size.
The solution is to always compute with `bin_size=False`, and then manually
compute the `bin_size` and set it on the cache of `bin_size=True`.
PR: #38292
Co-authored-by Sébastien Theys <seb@odoo.com>
X-original-commit: 7744886d6141ca7971d91807d0444c707e10fdf8
Users sometimes define custom models on SQL views
e.g. @nseinlet
In such a case, Odoo should not attempt to create foreign keys
as it just cannot work on views.
This could prevent the migration of a database
with such a custom model using a view
when it attempted to fix the missing foreign keys
when updating the modules.
closesodoo/odoo#38988
X-original-commit: dfaea03de57394a9a188f499da664c57dd9adc29
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Remove individual m2m indexes and replace with a single mirrored
composite
This will help for logical replication strategies (postgresql BDR)
closesodoo/odoo#37963
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Issue: after many2one updates, the cache of the corresponding one2many
fields was inconsistent when the latter depends on `active_test`. One
of the values in cache was updated, while the other was left intact.
We simplify the cache by not making the field depend on context: the
cache value contains all the records in the relation (corresponding to
`active_test=False`). The value of the field is automatically filtered
by the `active` field when the value is accessed.
This makes it easier to maintain the cache value, guarantees its
consistency, and avoids queries to read the one2many field with
`active_test=False`, after having set it with `active_test=True`.
This makes sense because in `create` the "previous" value of a field is
obviously non-existent.
This avoids having to fetch pre-existing attachments when they are known to be
inexistent, which optimizes stored related binary that are computed post-insert.
Before this commit, flushing a model that uses the `image.mixin` would generate
twice as many queries as it should.
This is because `_compute_related` is not meant to be overridden. In the
override of `Image` we call `super()` then post process the records by
reassigning each record's relevant image field with `_image_process`.
The `super()` will assign the field of the records once which
will in turn trigger a `write` (and thus, will generate queries) then
after the `super()` call we reassign them which will re-trigger the same
`write` and the same queries.
With this commit, instead of overriding `_compute_related` we extract the
processing to a method that can be overridden, so that the `write` is called
simply once.
The result, obviously, is that queries related to the `write` are cut in half.
Related PR: #36683 & #36288
Co-authored-by: Adrian Torres <adt@odoo.com>
Co-authored-by: Sébastien Theys <seb@odoo.com>
This fixes an issue when a Model A with a `many2one_reference` is inherited in
Model B with `_inherits`, and another Model C defines a `one2many` having as
inverse the inherited `many2one_reference` in Model B.
Without this commit, the value of `model_field` is `False` by default for the
field in B, which would lead to incorrect queries when building
`get_domain_list` for the `one2many`.
TransientModel (wizards) can be annoying because if they have required
many2one fields, those fields will default to `ondelete='restrict'`,
preventing user to delete the comodel records without deleting the
transient model records first.
To improve such case, we default to `ondelete='cascade'` for required
many2one field on a TransientModel (unless specified otherwise)
closesodoo/odoo#36738
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This "bugprovement" resolve the old issue of writing on a translatable
field a falsy value.
Before this commit, only the translation value was removed. When no
translation is present (or when the value is not set), the value is
retrieved directly from the source field.
Before 18d9c2cab2, it was still possible to go around this issue by
removing manually all ir.translation entries and writing with a user
in en_US.
This is no longer possible as writing on a translatable field always
uses translations when in multi-language environment, without
exception of en_US.
When writing a falsy value on a field, the expected behaviour is to
reset the value and see that falsy value after saving, not the old
value stored on the source model.
Remove all translations and force to update the column.
Removing one individual translation is still possible in the
translation popup.
Task id: 2062415
closesodoo/odoo#37077
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
The value of that field can be given as a dict containing the fields of
the corresponding record.
Co-authored with Michael Mattiello <mcm@odoo.com>
closesodoo/odoo#36779
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This patch avoids to create new browse records for nothing,
(as creating new browse (__new__) is costly),
and to avoid to loop multiple times on the records
(with multiple different filtered, etc.)
This brings performance gain to __set__,
which is used when setting the value of a compute field
e.g. This improves the performances of
`env['product.product'].search_read([])`
closesodoo/odoo#36006
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Instead of using a filtered with `cache.get`,
use a dedicated method in the Cache class to get
the records having a different value in cache then asked.
This is mainly to avoid the creation of intermediate
`browse` of 1 record, when doing `for rec in self`
in `filtered`.
Creating browses is costly, and avoiding it leads
to performance gains.
The dedicated method `get_records_different_from`
loops on the record ids, instead of on browse records
Consider a model M that defines `display_name` as a computed stored
field, then an extension of M that introduces a mixin model A before
that definition in the MRO of M's class. The model A is expected to
have an automatic, non stored field `display_name`, while M must have
its non-automatic, stored field `display_name`.
closesodoo/odoo#36427
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Determine `model._rec_name` before the dependencies of the fields. The
compute method of the automatic field `display_name` uses a callable
depends that retrieves `model._rec_name`.
closesodoo/odoo#36484
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This prevents a bunch of queries that are useless when creating a
record. Indeed, right after a record has been created, no other record
has a many2one reference to it. In other words, inversing a many2one
field from the record just created always gives an empty recordset.
Those useless inversions generate about a dozen queries when creating a
`res.partner`, for instance.
This saves queries, but not much time.
closesodoo/odoo#36566
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
The ORM overrides the default defined programmatically on the field, and
set a default function that retrieves the value in `ir.property`.
closesodoo/odoo#36545
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Assigning `check_company=True` to a field will
- set a default domain filtering the companies
- allow to call `_check_company` on the records to ensure the domain is
respected
Setting `_check_company_auto = True` on a model will ensure
`_check_company` is called at create and write, enforcing the multi
company domain.
Joint work with Raphael Collet <rco@odoo.com>
task-1985992
When a translated field is set on new records, one should not update
translations in 'ir.translation'.
closesodoo/odoo#36138
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This is a performance optimization: modifying a regular record will not
trigger some recomputation on a transient record. Most transient
records are simply waiting to be garbage-collected, so there is no need
to keep their fields up-to-date.
closesodoo/odoo#35909
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
One cannot override the attribute `selection`, and list selections can only be
extended with `selection_add`.
Adapt the bad extensions to be consistent with the new warnings
closesodoo/odoo#35663
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
When extended with the selection_add parameter, a singleton (value,)
where `value` appears in the overriden selection, can be used.
The new values are inserted in an order that is consistent with the
overridden selection and this list.
selection = [('a', 'A'), ('b', 'B')]
selection_add = [('c', 'C'), ('b',)]
> result = [('a', 'A'), ('c', 'C'), ('b', 'B')]
Each model of the relation can define `ondelete` for its `column2` foreign key.
This way the behavior is similar to m2o where the target of the `ondelete` is
the `comodel` foreign key.
Some models were already defining `ondelete` 'restrict' on m2m fields and after
review it appears the behavior introduced in this commit is the expected
behavior for them.
The 'restrict' from product.product has to be removed however because the rest
of the code needs adaptation now that it is properly restricted. These changes
will be done on a separate PR.
closesodoo/odoo#35654
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
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.
closesodoo/odoo#35659
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
The selection values of a selection field are now stored in database in the
model ir.model.fields.selection
This will allow to have a modular approche on selections and each selection
is now linked to the module that declared it.
Previously to this change, the selections were linked to the field, meaning
uninstalling a module had no impact on the selections stored on database.
With this change, the selections will now be translated in the correct module
(having an external id) and the records having a used selection will now be
reset to null.
closesodoo/odoo#30228
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Co-authored-by: Raphaël Collet <rco@odoo.com>
This attribute is misleading as it is insufficient to correctly upgrade
the database. It only renames the column in the database, but other
operations are needed, like updating the corresponding `ir.model.fields`
record (and its xmlid). The default values and the translations are also
lost during the upgrade.
Moreover, this feature was misused. It was:
- left on fields during multiple versions.
- used on reports (SQL views). This would be ok if the feature was
complete, but, as is, it was useless.
- kept unchanged after a second renaming of the field (which can happen
versions later the first rename).
- used, even when the meaning of the field changed. i.e. the field
`archived` has been renamed to the classic `active`, but the value
in the database should be switched.
closesodoo/odoo#35439
Signed-off-by: Christophe Simonis <chs@odoo.com>
If a dependency was wrong in the triggers, it was hard to debug
Co-Authored-By: Olivier Dony <odo@odoo.com>
closesodoo/odoo#31958
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>