Commit Graph
7400 Commits
Author SHA1 Message Date
Daniel Kosky (dako) f9c209d356 [FIX] base: RDC/Congo phone codes
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

closes odoo/odoo#155680

Pr: https://github.com/odoo/odoo/pull/133287
X-original-commit: 230914dfce7de121ad81444d953a828620177eae
Signed-off-by: Habib Ayob (ayh) <ayh@odoo.com>
2024-02-27 22:35:24 +00:00
Nicolas Viseur (vin) 9e6afbd114 [ADD] Starshipit as a delivery provider
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

closes odoo/odoo#135839

Related: odoo/enterprise#47569
Related: odoo/documentation#7798
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
2024-02-27 17:40:49 +00:00
Chong Wang (cwg) 8ccde3f101 [FIX] core: fix translation typo fixing
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

closes odoo/odoo#155476

X-original-commit: 38ec36e9b5dde0c02a4ff47714b1056e0db76812
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
2024-02-26 23:09:37 +00:00
Ricardo Gomes Rodrigues 50d8450b6e [FIX] base: update pot
The pot file of the base module hasn't been updated in some time.
This commit takes care of that.

closes odoo/odoo#155375

Related: odoo/enterprise#57503
Signed-off-by: Brice Bartoletti (bib) <bib@odoo.com>
2024-02-26 21:23:01 +00:00
Thomas Lefebvre (thle) 66ea20b16d [FIX] base: force xmlns definition to string
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>
2024-02-15 17:59:55 +00:00
Thomas Lefebvre (thle) c6c2486e59 [FIX] core: evaluate representation of field as a string
In some scenarios, it is necessary to evaluate the representation
of fields as a string (which triggers issues if this is not the case).

closes odoo/odoo#155299

X-original-commit: e89b47f44548170abff088427149337411fcc47b
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Signed-off-by: Thomas Lefebvre (thle) <thle@odoo.com>
2024-02-26 06:24:25 +00:00
Odoo Translation Bot 4f4ca50e8d [I18N] Update translation terms from Transifex 2024-02-25 00:13:04 +01:00
Julien Banken 1324bc72bb [FIX] base: allow fetching property field definition on unacessible parent record
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

closes odoo/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>
2024-02-23 16:43:35 +00:00
vava-odoo a37b0171dd [FIX] core: no warning in Graph for imported modules
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.

closes odoo/odoo#155096

Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
2024-02-23 13:10:06 +00:00
Martin Trigaux 04587e1916 [IMP] base_setup: enable disabling default user rights propagation
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.

Closes odoo/odoo#149224
Task-id 3685856

closes odoo/odoo#154816

X-original-commit: 70f66f147bb0c133be6ae3fd2b11438afe2366a5
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2024-02-21 11:28:00 +00:00
Rémy Voet (ryv) 86dd313d10 [FIX] core: fix read_group with groupby=['id']
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.

closes odoo/odoo#154799

X-original-commit: 75a259365989d469972c0616dba22a56bf218bb5
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
2024-02-21 09:41:26 +00:00
Raphael ColletandLucas Perais 15bfff301c [FIX] web: onchange() does not handle _inherits parent field in one2many
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

closes odoo/odoo#154735

Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
2024-02-20 14:57:35 +00:00
Odoo Translation Bot 1cf48deef9 [I18N] Update translation terms from Transifex 2024-02-18 00:12:23 +01:00
flvr-odoo f6212e4554 [FIX] base : make the module list sorted
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.

closes odoo/odoo#154324

X-original-commit: bbe33a1260ab3bfe97caa1197adbf00c661ddfb4
Signed-off-by: Vranckx Florian (flvr) <flvr@odoo.com>
2024-02-16 13:51:53 +00:00
Ruben Gomes (rugo) b54df52774 [IMP] odoo.tools: add rounding_mode and amount_rounding to formatLang
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

closes odoo/odoo#151314

Related: odoo/enterprise#55218
Signed-off-by: John Laterre (jol) <jol@odoo.com>
2024-02-16 12:12:41 +00:00
Ruben Gomes (rugo) a454456148 [REF] odoo.tools: clean up formatLang
Simplify and clean up formatLang code (in preparation for improvement).

Part-of: odoo/odoo#151314
2024-02-16 12:12:41 +00:00
Renaud Thiry ffda905ba7 [FIX] mail: consider empty "section" nodes to be empty html
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

closes odoo/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>
2024-02-15 07:54:50 +00:00
Stanislas Sobieski ac572d1e76 [FIX] mail: setup system example email in base to avoid overwrite at mail install
closes odoo/odoo#153529

X-original-commit: bd4eedc3fbefb75381b2b6457e5145edac2be031
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Stanislas Sobieski (sts) <sts@odoo.com>
2024-02-12 20:24:13 +00:00
Alvaro Fuentes f3eb6f395a [FIX] core: ensure SQL formatter can handle large domains
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.

closes odoo/odoo#153394

Signed-off-by: Raphael Collet <rco@odoo.com>
2024-02-12 20:24:08 +00:00
Thomas Lefebvre (thle) 90853ef0ab [FIX] im_livechat: add self writable fields for user
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]: 78f6b83b34

closes odoo/odoo#152425

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-02-12 20:24:03 +00:00
Denis Ledoux b23cb16487 [FIX] core: restrict httprequest attributes
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>
2023-12-07 12:53:19 +00:00
Odoo Translation Bot dd40867949 [I18N] Update translation terms from Transifex 2024-02-11 00:14:17 +01:00
Gauthier Wala (gawa) c017f44f4f [FIX] tools: fiscal year of 30/12 is taken as 31
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

closes odoo/odoo#153528

X-original-commit: cd0bb178441790e7e33c0d1c01b7ade82d4ab8c0
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
2024-02-10 17:43:14 +00:00
sesn-odoo b499ab0540 [FIX] base: prevent deleting a company if it has children
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

closes odoo/odoo#153264

X-original-commit: da803db384ec809a9c68dd379bf3c03f00d5a731
Signed-off-by: Séna Serge Nshimiyimana (sesn) <sesn@odoo.com>
2024-02-09 11:57:29 +00:00
Nikhil Kajavadra 2f5fd750d4 [FIX] tools: avoid updating translation of '__export__' module
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

closes odoo/odoo#148757

X-original-commit: 29341902bd6b6b7ff84eede2651251f6d2ce2faa
Signed-off-by: Raphael Collet <rco@odoo.com>
2024-02-08 15:07:54 +00:00
nda f67db6fe1e [FIX] core: remove control characters from strings for xmlrpc
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

closes odoo/odoo#153084

X-original-commit: 3fa92ff58daef0dd2464beadeafef208871deca6
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Nicolas Danhier (nda) <nda@odoo.com>
2024-02-07 18:34:24 +00:00
damr cc6ecce5f0 [FIX] base,*: remove force_email from the context in views
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

closes odoo/odoo#149806

Related: odoo/enterprise#54549
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
2024-02-07 12:48:50 +00:00
Tiffany Chang (tic) 22c5940706 [I18N] base: use expected "false" for Russian
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.

closes odoo/odoo#152285

Related: odoo/enterprise#55637
Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
2024-02-06 18:49:02 +00:00
Tiffany Chang (tic) 94c58407f6 [I18N] *: add in Russian translations
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
2024-02-06 18:49:02 +00:00
Ruben Gomes (rugo) e538c584ec [IMP] odoo.tools: add HALF-EVEN and HALF-DOWN to float_round
Add support for `HALF-EVEN` and `HALF-DOWN` as value
for `rounding_method` argument of `float_round()`.

closes odoo/odoo#152227

Signed-off-by: Raphael Collet <rco@odoo.com>
2024-02-05 13:48:29 +00:00
Alvaro Fuentes b5e74f47c9 [FIX] core: fix recursion check
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.

closes odoo/odoo#152080

X-original-commit: e7c6445dd1896bb182b44af768814f297027d3a4
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2024-02-05 08:34:51 +00:00
Moens Alexandre 3d54c3265c [FIX] base: neutralize keep only autovacuum_job
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

closes odoo/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>
2024-02-04 08:19:21 +00:00
Odoo Translation Bot c95419af44 [I18N] Update translation terms from Transifex 2024-02-04 00:11:05 +01:00
Paolo Gatti (pgi) bc7d654583 [IMP] base: Helper to build actions on every model
`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
2024-02-03 19:38:00 +00:00
Louis (wil) 8d0a400d86 [FIX] tools: do not export slot params for translation
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.

closes odoo/odoo#152606

X-original-commit: b839faf09be259ffdccf9d872e646e4ebe4a8bcb
Signed-off-by: Géry Debongnie <ged@odoo.com>
Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
2024-02-03 11:02:11 +00:00
Sven Fuehr ecbf5bdddb [FIX] base: make ZIP not required for ecuador
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
2024-02-03 02:06:43 +00:00
nda 8b89fc1083 [FIX] base: check ir.rule domain is valid
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
2024-02-01 16:25:41 +00:00
Achraf 29eb854e89 [FIX] base/models: Fix typos in _read_group_format_result
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-L2467

closes odoo/odoo#151497

Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
2024-02-01 16:25:38 +00:00
SaddemAmine aba526f065 [IMP] base: added Kenyan states
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

closes odoo/odoo#152256

Signed-off-by: Josse Colpaert <jco@odoo.com>
2024-02-01 14:30:07 +00:00
Raphael Collet b00d135599 [FIX] core: optimization of Cache.set() to avoid multiple record.id
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.

closes odoo/odoo#149624

Signed-off-by: Raphael Collet <rco@odoo.com>
2024-02-01 09:49:50 +00:00
Rémy Voet (ryv) 65a2c2ebc8 [FIX] core: new record shouldn't force fetching inverse x2many fields
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
2024-02-01 09:49:50 +00:00
Jairo Llopisandxmo-odoo 18b4902a19 [FIX] base: allow browsing form view of missing module
Before this patch, if you once had one module available and, later, remove it, you'd be getting an exception when browsing its form view and trying to get its icon image.

Now it gets the base module icon image, just like it should.

@moduon MT-1524

closes odoo/odoo#151870

X-original-commit: 4543f45e0066814d5722acfcac3c8bc8d09b8cb1
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Co-authored-by: xmo-odoo <xmo@odoo.com>
2024-01-31 18:59:10 +00:00
Aaron Bohy 332268c724 [FIX] web,test_assetsbundle: correctly display scss error
Before this commit, when there was an error while compiling scss,
information was added in the compiled css bundle s.t. the client
is aware there was an issue and can indicate it to the end user.

In particular, a dialog was shown with a static message, and
with what should have been the python stack trace. However, the
stack trace was missing.

In addition, a banner should have been displayed in the bottom left
corner the screen, telling that a former version of the bundle was
used as the new one is in error. This banner wasn't displayed
either.

Finaly, forwarporting odoo/odoo#149230 automatically closed the
dialog, as we close all dialogs when executing an action (in this
case the first action when the webclient starts). As a consequence,
the dialog was no longer displayed either.

To sum things up, before this commit, 1) there's no longer a dialog,
even if there were, 2) the dialog doesn't contain the stack trace,
and 3) there's no banner.

To fix 1), we simply display a notification instead. Opening a
dialog for this simply doesn't fit with odoo/odoo#149230, and a
sticky, danger, notification is totally fine for this.
A notification being smaller than a dialog, it says to open the
console to see the stack trace instead of inlining it.

2) has been inadvertendly introduced by [1]: quotes in the error
were doubly escaped (\\"), meaning that they weren't escaped at
all, so the js couldn't properly read the value

And the source of error for 3) was that the last line of the css
bundle (the sourcemap comment line) wasn't valid. It started with
`//*`. As a consequence, the remaining of the file wasn't processed,
and that's exactly where the assets bundle error handling code
inserted the error information.

[1] 64bbef5bc1

closes odoo/odoo#149543

Related: odoo/enterprise#55257
Signed-off-by: Francois Georis (fge) <fge@odoo.com>
Signed-off-by: Samuel Degueldre (sad) <sad@odoo.com>
2024-01-31 01:31:53 +00:00
Alvaro Fuentes ce3aac8672 [FIX] core: propagate update of modifiers attributes from base terms
When we update an inline translated element (like `<span>`) for the base
language `en_US` we should update the modifiers attributes for all
languages.

For example when updating from (16.0)
https://github.com/odoo/odoo/blob/7ecd9413/odoo/addons/base/views/ir_ui_view_views.xml#L127-L129
https://github.com/odoo/odoo/blob/7ecd9413/odoo/addons/base/i18n/fr.po#L7233-L7235
to (17.0)
https://github.com/odoo/odoo/blob/b1461d28/odoo/addons/base/views/ir_ui_view_views.xml#L126-L128
https://github.com/odoo/odoo/blob/b1461d28/odoo/addons/base/i18n/fr.po#L12087-L12089

The base term, `en_US`, is updated since the text matches but the
attributes of the translated terms, `fr_FR` for example, are not
updated. Later when the PO file is loaded in non-overwrite mode the
translated terms for `fr_FR` is not updated. This causes all sort of
issues during an upgrade for inline-translated terms -- like `<span>`.
More so since the recent change that converts domain-based attributes
into inline Python expressions.

In this patch we propagate modifiers attributes from inline-translated
items in the new base term into all translated terms when the base term
is updated. In that way we ensure the attributes are correct in all
languages even if later the loading of their corresponding PO file
doesn't update the term.

For a detailed example, let's see what happens when loading the view
above during an upgrade 16->17, right at the first load of the XML file
at https://github.com/odoo/odoo/blob/b1461d28/odoo/fields.py#L1864
```
(Pdb) p old_term
'<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">This view has no previous version.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">This view is not coming from a file.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">You need two views to compare.</span>'
(Pdb) p closest_term
'<span invisible="reset_mode != \'soft\'">This view has no previous version.</span>\n                        <span invisible="reset_mode != \'hard\'">This view is not coming from a file.</span>\n                        <span invisible="reset_mode != \'other_view\'">You need two views to compare.</span>'
(Pdb) p translation_dictionary[old_term]
defaultdict(<class 'dict'>, {'fr_FR': '<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">Cette vue n\'a pas de version antérieure.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">Cette vue ne provient pas d\'un fichier.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">Vous avez besoin de deux vues pour comparer.</span>'})
```
As we can see the new term will get an updated value for its `invisible`
attribute, while also removing `attrs`. The translated terms will be
still keep the old modifier though.
Now later when the fr_FR.po file is loaded we reach this point
https://github.com/odoo/odoo/blob/b1461d28/odoo/tools/translate.py#L1442
```
(Pdb) p term_en
'<span invisible="reset_mode != \'soft\'">This view has no previous version.</span>\n                        <span invisible="reset_mode != \'hard\'">This view is not coming from a file.</span>\n                        <span invisible="reset_mode != \'other_view\'">You need two views to compare.</span>'
(Pdb) p translation_dictionary[term_en]
defaultdict(<function DeepDefaultDict at 0x7fc9640cdfc0>, {'fr_FR': '<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">Cette vue n\'a pas de version antérieure.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">Cette vue ne provient pas d\'un fichier.</span>\n                        <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">Vous avez besoin de deux vues pour comparer.</span>'})
```
Thus the translated values are NOT updated, keeping the _wrong_
modifiers. This is later fixed during the upgrade in a clumsy way.
C.f. the warnings like this one in runbot:
```
Incomplete conversion for view(id=77, lang=fr_FR) at
<span attrs="{'invisible': [('reset_mode', '!=', 'soft')]}">Cette vue n'a pas de version ant&#233;rieure.</span>
```
Note that such warnings are gone in current PR CI.
The root issue here is that when the fr_FR translation is loaded the
terms are not updated due to a combination of factors:
1. The text content of the term didn't change
2. There is no override flag set for translations

Option 2 is not a valid option during upgrades because we want to keep
custom translations. We could instead of the current patch tweak how
option 1 works and perhaps make the closest term more restricted. This
would lead to the update of the whole translation though while the
actual issue here is _just_ the modifiers. Moreover if the translations
are out of sync the translated terms will still keep the wrong values
that could still be essential for the correct functioning of the record
they belong too (view archs -- for example).

Finally this is a more extreme case (16.0):
https://github.com/odoo/enterprise/blob/1e63b4a8/sale_subscription/views/sale_order_views.xml#L142
In this case during the upgrade we fix the modifier value (refer to
runbot warning above -- it's the same script that fixes it) and set
```
invisible="(subscription_management == 'upsell') or (recurrence_id == False)"
```
for translations, which is wrong. The correct value is (17.0):
```
invisible="not plan_id or subscription_state == '7_upsell'"
```
https://github.com/odoo/enterprise/blob/530ba3ad/sale_subscription/views/sale_order_views.xml#L136

closes odoo/odoo#150152

Signed-off-by: Raphael Collet <rco@odoo.com>
2024-01-30 21:08:04 +00:00
Alvaro Fuentes 86e3c3c72b [FIX] core: fix check for text-only translated terms
`get_text_content` will transform contiguous space chars into single
spaces, plus translate special HTML elements
```
>>> " ".join(html.fromstring(f"a\n    b &amp; c").text_content().split())
'a b & c'
```

In order the correctly verify if a term is text-only we need to use the
HTML parser. Note that to be resilient against bad XML, but valid HTML,
we cannot use the default XML parser.

Part-of: odoo/odoo#150152
2024-01-30 21:08:04 +00:00
Jairo Llopis 6fda467597 [FIX] tests: make sure screencasts dir exists before writing to it
Without this patch, running this command on an environment where the tour will fail, will create massive and useless logs:

    odoo --stop-after-init -i auth_totp --test-enable --test-tags /auth_totp

This is because this method is a callback that can come in a different thread, creating a race condition.

There's no problem on checking wether the directory exists before creating the file, and then safeguarding from the problem.

@moduon MT-1075

closes odoo/odoo#151579

X-original-commit: 7aca8ae8728c66700c3afdca350e99ea78a63d88
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2024-01-30 12:19:57 +00:00
Lucas Perais c0ab464dc7 [FIX] base, web (qweb): image field in raw data mode handles options
Commit[1] implemented a way to output an image as its raw representation
`<img src="data:image/png;base64......." />`
It is useful for integrating an image of a record not accessible publicly.

However the original commit forgot to allow the img node to handle the options
passed to the field. Classes in particular were absent

After this commit, the options are handled correctly, and the image in raw mode
has the right classes.

opw-3517861

[1]: f8b901d04b

closes odoo/odoo#151410

X-original-commit: dbb22351921629aad845e29ebfa8b4083b4e745a
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
2024-01-29 13:44:33 +00:00
Odoo Translation Bot 625dac5a10 [I18N] Update translation terms from Transifex 2024-01-28 00:16:34 +01:00
Victor Feyens 9ea17019f6 [FIX] core: default multi-company domain
of check_company=True fields.

Suppose two models

class A:

    company_id = fields.M2O() # not required

class B:
    _check_company_auto = True

    company_id = fields.M2O() # not required
    a_id = fields.M20(check_company=True)

and the following code:

a = A.create({'company_id': 1})
b = B.create({'a_id': a.id, 'company_id': False})

The creation of B will fail because of the multi-company
checks, which is expected.

Nevertheless, since 0d30cc2bc9, the domain
of the field a_id would be:

(company_id and ['|', ('company_id', '=', False), ('company_id', 'in', [company_id])] or []) + ([])

which means that through the interface, if you create a record b following
the example above (no company_id on b), the evaluated domain would be empty,
allowing to select records of class A, even if they belong to another company.
Of course, this would lead to a multi-company error when trying to save the
record.

This commit makes sure that the right domain is applied on
check_company=True fields, even if the current record has no value
in its `company_id` field.

opw-3629374

closes odoo/odoo#151341

X-original-commit: aaddedc3bab4f16747fb0f71ae626d94f3975ee3
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
2024-01-27 00:01:24 +00:00
Lucas Perais d8993d61e6 [FIX] base: can delete manual models with base fields
Create an ir.model custom (state = "manual" -- for example via studio) that has a mix
of manual fields (named x_...) and of base fields (originating from some mixin).

Unlink all linked views or object, and try to unlink that model eventually.

Before this commit, an error was raised because base fields couldn't be deleted, even though the table was empty.

After this commit, the deletion works.

Note that this commit is a fix of https://github.com/odoo/odoo/pull/130420/ , which added partial support for this
and a backport of 7550bcd61e which fixed the former PR in 17.0

opw-3558590

closes odoo/odoo#151282

X-original-commit: 3e84f3e9b0da397d82d5add0e37be58f0e30c7be
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
2024-01-26 21:08:00 +00:00