Create an attachment with an URL to a static file that does not exists,
e.g. '/web/static/idontexist.png'. Inside your browser try to access
that file, open <localhost:8069/web/static/idontexist.png>. The browser
fails with a "Too Many Redirections" error.
When a path is not found, nor in the static files, nor in the
controllers, `_serve_fallback` kicks in and attempt to find a resource
outside of the router that matches the URL. In case it finds an
attachment with a matching URL, it'll deliver it.
In this specific case, it finds our attachment and return a redirection
to it's URL, which is the same URL as the request hence it loops back.
Don't deliver URL attachments via `_serve_fallback`, only deliver stored
files.
closesodoo/odoo#156323
X-original-commit: d2bea592db6a66d531b83437d42b273606f629f1
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Reduce the log size in case of failure of a screencast frames
Avoid a race condition while removing tree.
closesodoo/odoo#156341
X-original-commit: 97dc741929eb9497f9b44c110607254f0a873698
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Fix race-condition when a directory is created by two processes (python's os.py
handles it for all directories, but not for the last one). Happens sometimes
when generating assets for the first time (CSS, JS); one of the two times might
crash.
sentry-4417110945
closesodoo/odoo#156232
Signed-off-by: Fabien Pinckaers (fp) <fp@odoo.com>
When QWeb templates became cached and compiled in [1], the list of
default cache key elements did not contain `inherit_branding_auto`
(but it included the old `inherit_branding`).
Because of this the cache was shared between restricted editors and
public users, which could lead to problems such as missing the branding
on edited fields.
Steps to reproduce:
- Use a single browser instance and do not log any user out.
- Start with `website_sale`.
- Make "demo" user a restricted editor and a sales administrator.
- Connect on 127.0.0.1 as "demo" and go to a product website page.
- Go to 127.0.0.2 as a visitor and go to the same product page.
=> The product name field of the visitor page was branded.
If you swap the last two steps, the "demo" user's page lacks the
branding.
[1]: https://github.com/odoo/odoo/commit/7ede9bcb2de9d52994b3a6fcb84edc3f81d60284
task-3482439
closesodoo/odoo#156146
X-original-commit: 821888023db462d522c5d6de84fcab80a81c2713
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
In case of exception of type KeyError during the formatting with Babel
instead to raise a Traceback, we first retry with the en_US locale.
Babel fixes each week new bug of formatting like the one in the test,
but we cannot bump our default babel version since it is not in the
stable Ubuntu 22 so it is a best effort fix that will not hide all bugs
but is better that nothing.
https://github.com/python-babel/babel/pull/827closesodoo/odoo#155909
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Add a hook to prepare attachment values needed for attachments creation
during the pdf report generation
closesodoo/odoo#155518
X-original-commit: 9dd56a625f2b613a68746a80ee552bffbeb87455
Signed-off-by: Laurent Smet (las) <las@odoo.com>
In case where display_name is null, the widget contact crash
- AttributeError: 'bool' object has no attribute 'split'
On odoo.com we have around 3K of partner that have name with null value.
So calling so widget Contact on linked res.users will crash since the
display name is False
closesodoo/odoo#155735
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Phone codes for the Democratic Republic of the Congo (CD) and The
Republic of the Congo (CG) are the wrong way around, and ought to be
reversed.
This commit is based on a commit that was not merged in v14.0 in this
closesodoo/odoo#155680
Pr: https://github.com/odoo/odoo/pull/133287
X-original-commit: 230914dfce7de121ad81444d953a828620177eae
Signed-off-by: Habib Ayob (ayh) <ayh@odoo.com>
Starshipit is the leading provider of integrated
and automated fulfilment solutions for online businesses
integrating with the main carriers used in Australia and
New Zealand, such as Australia Post, DHL, Aramex, CouriersPlease and more
This PR will add support to integrate with starshipit directly in Odoo,
providing rates and shipping for users who need it.
Task ID # 3041982
closesodoo/odoo#135839
Related: odoo/enterprise#47569
Related: odoo/documentation#7798
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
for model_terms translated fields, for sake of typo fixing feature
if a term is removed after write its translations might be reused by another
close term which has totally different meaning
this fix removes the typo fixing if the matched closest term exists before write
closesodoo/odoo#155476
X-original-commit: 38ec36e9b5dde0c02a4ff47714b1056e0db76812
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
The pot file of the base module hasn't been updated in some time.
This commit takes care of that.
closesodoo/odoo#155375
Related: odoo/enterprise#57503
Signed-off-by: Brice Bartoletti (bib) <bib@odoo.com>
It is necessary to force the definition of a namespace in the string type,
as it may come from an external context.
See odoo/odoo@13af401bc2
opw-3767015
Signed-off-by: Christophe Matthieu (chm) <chm@odoo.com>
In some scenarios, it is necessary to evaluate the representation
of fields as a string (which triggers issues if this is not the case).
closesodoo/odoo#155299
X-original-commit: e89b47f44548170abff088427149337411fcc47b
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Signed-off-by: Thomas Lefebvre (thle) <thle@odoo.com>
When the user creates a new record having a property field, the system
fetches the property definition of the parent record to retrieve the
field's default values (see: `_add_default_values`). If the user lacks
read access on the parent record, the user gets an access error when
retrieving the property definition of the parent record.
To prevent this error, we will perform a sudo call on the parent record
before reading the property definition of the parent record. This allow
the user to create a new record, even if they do not have access to the
parent record.
task-3594814
closesodoo/odoo#155178
X-original-commit: 6f0fb8579d8230f91b7eefc5d29f8d61390dacc4
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
Signed-off-by: Julien Banken (jbn) <jbn@odoo.com>
Before this PR, after having imported a module, a warning appears in the
log, because it tries to update the graph which does not make sense for
an imported module.
This commit makes sure the warning is skipped if the module was
imported.
closesodoo/odoo#155096
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
When installing a new module, the access of the Default Template User
is propagated to any existing employee (introduced at
aefb05eb497a8a16a). This can be problematic in companies that don't
want all their employees to become manager by default. Allow to
disable this behaviour in a settings.
This is the version of the patch targetting stable version that is not
configurable through the interface, manually creating an ICP
base_setup.default_user_rights_minimal=True as the way to change the
behaviour.
Closesodoo/odoo#149224
Task-id 3685856
closesodoo/odoo#154816
X-original-commit: 70f66f147bb0c133be6ae3fd2b11438afe2366a5
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Use read_group with groupby=['id'] raise a Exception:
```
File "/home/odoo/Documents/dev/odoo/odoo/models.py", line 2386, in _read_group_format_result
m2x_records = self.env[field.comodel_name].browse(ids).union()
File "/home/odoo/Documents/dev/odoo/odoo/api.py", line 521, in __getitem__
return self.registry[model_name](self, (), ())
File "/home/odoo/Documents/dev/odoo/odoo/modules/registry.py", line 190, in __getitem__
return self.models[model_name]
KeyError: None
```
Even if it doesn't make lot of sense to do that (mostly equivalent to
search), it is preferable to manage the case correctly.
closesodoo/odoo#154799
X-original-commit: 75a259365989d469972c0616dba22a56bf218bb5
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Consider models A and B such that B inherits from A (with _inherits),
and a form view of A with a one2many field that inverses the many2one
"delegate" field from B to A. When adding a new record in the one2many,
onchange() crashes while trying to update the cache of an empty parent
record.
The situation is caused by how onchange() initializes the new record of
model B, and the fact that the form provides a value for the delegate
field. The new record is actually initialized with an empty value for
the delegate field, which causes the code to crash. The fix simply
consists in updating the parent record only if is nonempty.
opw-3744514
closesodoo/odoo#154735
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
Make the set() of module sorted, aka a list.
We can be pretty sure that nobody relied on the order of this set before
since it was completely underterministic. Therefor this change should
not break anything and make the testing on runbot more consistant.
This is mainly following the issue with the sql-injection testing
failing randomly with the order of the modules.
closesodoo/odoo#154324
X-original-commit: bbe33a1260ab3bfe97caa1197adbf00c661ddfb4
Signed-off-by: Vranckx Florian (flvr) <flvr@odoo.com>
Adds the possibility to give formatLang() a 'rounding_mode' (any Decimal rounding mode)
and an amount_rounding ('decimals', 'units', 'thousands', 'millions' and 'lakhs').
'amount_rounding' will display the amount in the given unit. For example, 10456 in 'thousands' will be 10.
task-3626894
closesodoo/odoo#151314
Related: odoo/enterprise#55218
Signed-off-by: John Laterre (jol) <jol@odoo.com>
Currently an empty section is not considered empty text.
As the web editor sometimes uses them, it is relevant to consider
them when asking whether some html will appear empty.
Currently, even completely removing the website description of an
exhibitor in website_event_exhibitor from the backend does not make
the 'missing description' tooltip appear in the front-end
task-3607615
closesodoo/odoo#154097
X-original-commit: 7dc376d4d2d2b4000de0da7573c30e4508f32318
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
Signed-off-by: Renaud Thiry (reth) <reth@odoo.com>
In previous versions the max size of a domain was bounded by psycopg
memory limits. With the new SQL formatting mechanism the limit is bound
by the maximum recursion limit in Python side. The purpose of this patch
is to restore previous behavior.
In 16.0:
```
>>> def make_dom(N):
... return [*('|' for x in range(N-1)), *(('login', '=', 'admin') for x in range(N))]
...
>>> u.search(make_dom(9984))
res.users(2,)
>>> u.search(make_dom(9985))
Traceback (most recent call last):
File "<input>", line 1, in <module>
u.search(make_dom(9985))
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 1520, in search
return res if count else self.browse(res)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 5140, in browse
if not ids:
File "/home/odoo/src/odoo/16.0/odoo/tools/query.py", line 217, in __bool__
return bool(self._result)
File "/home/odoo/src/odoo/16.0/odoo/tools/func.py", line 28, in __get__
value = self.fget(obj)
File "/home/odoo/src/odoo/16.0/odoo/tools/query.py", line 210, in _result
self._cr.execute(query_str, params)
File "/home/odoo/src/odoo/16.0/odoo/sql_db.py", line 321, in execute
res = self._obj.execute(query, params)
psycopg2.errors.SyntaxError: memory exhausted at or near ""login""
LINE 1: ...((("res_users"."login" = 'admin') OR ("res_users"."login" = ...
```
in 17.0 without this patch
```
>>> u.search(make_dom(1480))
res.users(2,)
>>> u.search(make_dom(1481))
<shortened output ...>
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 85, in code
child = stack[-1].send(child)
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 86, in <genexpr>
if isinstance(child, SQL):
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 85, in code
child = stack[-1].send(child)
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 86, in <genexpr>
if isinstance(child, SQL):
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 85, in code
child = stack[-1].send(child)
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 86, in <genexpr>
if isinstance(child, SQL):
File "/home/odoo/src/odoo/17.0/odoo/tools/sql.py", line 85, in code
child = stack[-1].send(child)
RecursionError: maximum recursion depth exceeded
```
This issue was observed in upgrades in multiple instances. Example: MRP
produces an OR domain with 2K terms for warehouse sub-locations that
fail.
closesodoo/odoo#153394
Signed-off-by: Raphael Collet <rco@odoo.com>
Issue:
------
Since this commit[^1], a user who is not in the `Administration/Access Rights`
group cannot modify certain fields available to him on his user profile
(`livechat_username` and `livechat_lang_ids`).
Solution:
---------
As it is possible for a user to write to these fields, it is necessary
to put them in `SELF_READABLE_FIELDS` in order to obtain sudo rights
when writing if the environment user corresponds to the user
to whom we want to write the new values.
opw-3717266
[^1]: 78f6b83b34closesodoo/odoo#152425
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
The version of werkzeug installed can vary from one deployment
to another, as we recommend to use the operating system package,
and the version can therefore change according to the operating
system version.
e.g. the werkzeug version installed using
`apt install python3-werkzeug` varies between
Ubuntu 18.04, 20.04, 22.04, 23.10, ...
We want to keep under control the attributes
developers use on werkzeug.wrappers.Request,
to avoid compatibility issues from one
version to another.
Therefore, this revision aims
to subclass werkzeug.wrappers.Request to limit
the attributes which can be used.
task-3734305
Part-of: odoo/odoo#78857
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
To reproduce:
- Put your fiscal year to the 30th of December (yes it's unlikely)
- Create an asset
- Compute depreciations
=> they are created for the 31th of December
It comes from the `get_fiscal_year` in `date_utils` which considers it as the case of the 28th of February
opw-3704466
closesodoo/odoo#153528
X-original-commit: cd0bb178441790e7e33c0d1c01b7ade82d4ab8c0
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Steps to reproduce
------------------
* create the following hierarchy of companies:
```
Company
└── Branch A
└── Branch B
```
* delete `Branch A`
From then on, whatever you do will result in a Bad Request response.
opw-3662711
closesodoo/odoo#153264
X-original-commit: da803db384ec809a9c68dd379bf3c03f00d5a731
Signed-off-by: Séna Serge Nshimiyimana (sesn) <sesn@odoo.com>
If translation of '__export__' module record's source and translated value in
'en_US' language is different. In that case, record's value of en_US lang is
translated value. Also in most of the case export module records are set as
noupdate false due to this while upgrading the database to version 16 from lower
version, the record's value is changed to their source value for 'en_US' lang.
To avoid this problem of updating a record's value, this PR will not considering
'__export__' module records for translation updates. Hence,'__export__' module's
records translation remain same as per original database.
Task : 3626386
closesodoo/odoo#148757
X-original-commit: 29341902bd6b6b7ff84eede2651251f6d2ce2faa
Signed-off-by: Raphael Collet <rco@odoo.com>
According to https://docs.python.org/3.7/library/xmlrpc.client.html :
When passing strings, characters special to XML such as <, >, and & will be
automatically escaped. However, it’s the caller’s responsibility to ensure that
the string is free of characters that aren’t allowed in XML, such as the
control characters with ASCII values between 0 and 31 (except, of course, tab,
newline and carriage return); failing to do this will result in an XML-RPC
request that isn’t well-formed XML.
This commit implements the removal of control characters from strings. As we
convert binary data to a string and return it, the resulting string should not
contain forbidden characters neither. The modification of dump_unicode function
now fulfills this requirement and can be applied to dump_bytes, contributing
to a more consistent behavior overall.
steps to reproduce:
- create a product with an ASCII control character in its name (ex: \x03)
- read the product name using XMLRPC
before this commit:
- client can't parse the response, an error is raised
after this commit:
- we make sure the string is free of those characters
opw-3617458
closesodoo/odoo#153084
X-original-commit: 3fa92ff58daef0dd2464beadeafef208871deca6
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Nicolas Danhier (nda) <nda@odoo.com>
ba1a550#diff-36973ac6e1f20b32a00fbcdc1f811c923bbb44ca15a0e068018e904ff565644fR97
The previous PR added some constraints on what can be used on the
context of views. The key word 'force-email' is no longer relevant and
will be removed from the context before reaching the next view/python
code.
This commit's purpose is to remove the force_email that were forgotten.
In order to still open the simplified partner form view, the ref of the
view is given in the context instead. While at it, we also fix the
create option given on the partner_ids field that was inconsistent.
affected version 17.0 - master
task - 3538000
https://www.odoo.com/web#id=3538000&menu_id=4720&cids=1&action=333&active_id=4105&model=project.task&view_type=form
Please enter the commit message for your changes. Lines starting
closesodoo/odoo#149806
Related: odoo/enterprise#54549
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
DeepL translated "false" as "ложный" (the adjective form), but
we expect it to be "ложь" (noun form) when importing xml. This
fix will ensure that the string is correctly converted into a boolean.
I have recorded this as a separate commit for posterity and so it isn't
accidentally changed again in the future.
closesodoo/odoo#152285
Related: odoo/enterprise#55637
Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
For a first iteration, Russian translations were done using DeepL using
1 large .pot file of all the standard modules to translate (e.g. no
localizations, no test modules, etc). Unfortunately for some reason
doing a msgmerge with the existing ru.po files didn't seem to work, so
old "Translators" metadata at top of files were lost (maybe they will be
re-added during next Transifex sync?)
Part-of: odoo/odoo#152285
Add support for `HALF-EVEN` and `HALF-DOWN` as value
for `rounding_method` argument of `float_round()`.
closesodoo/odoo#152227
Signed-off-by: Raphael Collet <rco@odoo.com>
Prevent an infinite loop when the cycle in the parents does not contain
the starting id: `3->2->1->2->1...`
Example:
```
>>> m=self.env['ir.module.category']
>>> c1,c2,c3 = map(m.browse,[1,2,3])
>>> c2.parent_id = False
>>> c3.parent_id = False
>>> c1.parent_id = c2
>>> (c3|c2).parent_id = c1 # this never ends
```
With current patch the call to `_check_recursion` successfully detects
the new cycle.
closesodoo/odoo#152080
X-original-commit: e7c6445dd1896bb182b44af768814f297027d3a4
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
The root of the issue:
The external identifiers are not guaranteed to be unique on their `name`
alone, the unique constraint is on the `name` and on the `module` fields.
Before this commit:
If a user or third party app were for example to create an external identifier
"project.autovacuum_job" and point it to an `ir.cron` record,
then that `ir.cron` would also be kept activated, which could cause
major issue if it makes calls to external systems, sends mail, etc...
After this commit:
All the crons are deactivated by the neutralisation, except for
the autovacuum
closesodoo/odoo#152535
X-original-commit: 0cc89a026d05b37714864e7ebb695e77ef2d1e7d
Signed-off-by: Jérémy Kersten <jke@odoo.com>
Signed-off-by: Alexandre Moens (mao) <mao@odoo.com>
`Model_get_actions_record(**kwargs)` helps building `ir.actions.act_window`
actions based on a certain model on very simple cases.
It opens a form if there's just one record, a list,form if there's more than one.
Given keyword arguments will overwrite those in the action.
This change serves as a base for the `actionable_errors` widget,
where it's used extensively to remove boilerplate code.
Part-of: odoo/odoo#142596
Slot params are dynamic content, similar to props, and are not
translated.
There is no point in adding untranslated content to the .pot files; so
this commit prevents the content of slot params from being exported for
translation.
Task-3718993.
closesodoo/odoo#152606
X-original-commit: b839faf09be259ffdccf9d872e646e4ebe4a8bcb
Signed-off-by: Géry Debongnie <ged@odoo.com>
Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
In Ecuador, the ZIP code is not a required field to create invoices.
Customers usually don't even know their ZIP code as the street number,
city and state (province) are mostly used for delivery (and not the
ZIP code).
task-3585823
Part-of: odoo/odoo#142730
When the user passes a wrong domain in the record rule, the system allows users
to save that record without checking whether the new domain is correct or
incorrect.
steps to reproduce:
- create an ir.rule on res.users and write a domain with a typo
before this commit:
- users can't log into odoo
after this commit:
- an error is raised to prevent saving a bad domain
opw-3653746
X-original-commit: dc8dfc246d3de9d447a360f15f41f2388ac8d638
Part-of: odoo/odoo#151992
Since https://github.com/odoo/odoo/pull/1432[FIX] base/models: Prevent incorrect behavior in `_read_group_format_result`
To reproduce the problem, you need to ensure that a read_group returns several groups,
with the first element being a group with no value if you choose to group on a many2many (see test).
Here's an example to reproduce in website_sale:
- Install `website_sale` without demo-data
- Go to `eCommerce/Products`
- Create a new product
- Go to `Sales` tab in the product form view
- Set a new `eCommerce shop/Categories` like `Sales`
- Save
- Return to `eCommerce/Products`
- Remove default filters
- Group by `Website Product Categories`
- There are two group: `None` and Sales`
- Click on None
- Traceback
In this case, the orderby is website_sequence:sum ASC,
and will therefore return as first group None containing `Delivery Product`
and as second group `Sales` containing the newly created product.
What happens is that `read_group` will build `rows_dict` thanks to `_read_group`.
https://github.com/odoo/odoo/blob/cb67b4e1472ae6689e943ade1e27cb43e8d87025/odoo/models.py#L2724
this `rows_dict` will be ordered according to `orderby`and then passed as an argument to the `_read_group_format_result` function
https://github.com/odoo/odoo/blob/cb67b4e1472ae6689e943ade1e27cb43e8d87025/odoo/models.py#L2759
For each row, this function will convert `row[group]` (group in this case is the many2many field)
into a tuple containing (id, displayname) in case the value (`row[group]`)
is found which will be used to build the domain `[(field_name, =, value)]`.
So, for example, replacing
```py
rows_dict = [
groupbyField': odoo.model(1),
groupbyField': odoo.model(4),
]
```
with
```py
rows_dict = [
groupbyField': (1, 'First record'),
groupbyField': (4, 'Fourth record'),
]
```
https://github.com/odoo/odoo/blob/cb67b4e1472ae6689e943ade1e27cb43e8d87025/odoo/models.py#L2460-L2462
If the value is False, we'll use the 'not in' operator instead.
To do this, we need to retrieve the ids of all the other groups to
include in this one all the records that aren't in any group,
either by retrieving the id if it's a model,
or by retrieving the first element of the tuple if it's already been modified,
or by directly retrieving the value of the field if it's not a many2x.
Except that if the first element is directly a group without a value,
it won't be able to retrieve the values of the other groups,
because the condition for checking that it's a `BaseModel` instance contained a typo
https://github.com/odoo/odoo/blob/cb67b4e1472ae6689e943ade1e27cb43e8d87025/odoo/models.py#L2465-L2467closesodoo/odoo#151497
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
This is a backport, with the original commit occurring in master:
e80f5e3.
The motivation for backporting these states is that they're useful in
the upcoming eTIMS OSCU integration for Kenya, which targets version
17.0.
Added Kenyan states as per https://www.iso.org/obp/ui/#iso:code:3166:KE
Task ID: 3665315
closesodoo/odoo#152256
Signed-off-by: Josse Colpaert <jco@odoo.com>
The expression record.id relies on a Python descriptor that has some
overhead, which is small but not negligible when used in a low-level
method of the ORM. We simply factor out this expression in order to
evaluate it once for the method.
closesodoo/odoo#149624
Signed-off-by: Raphael Collet <rco@odoo.com>
In e0297bdac4, the creation of a new
record always patches the inverse fields of relational fields in order
to make the cache of those inverse fields consistent.
For instance, when creating a new record like
user = model.new({'group_ids': [Command.link(group.id)]})
The inverse of field 'group_ids' on the new record having 'group' as
origin is patched so that its value includes record. A side effect of
this mechanism is that it fetches group.user_ids in order to patch the
value of new_group.user_ids, where 'new_group' is the new record having
'group' as origin.
The side effect described above is problematic when that inverse field
has huge cardinality, like hundreds of thousands of records, and this
performance overhead is unacceptable when the inverse field is actually
not used at all.
We address this performance issue by patching the value of x2many fields
only when they are used. If the value of the field is not in cache yet,
the patch is applied once a value is put in cache. If the field is not
used, the patch is simply never applied.
Part-of: odoo/odoo#149624