Commit Graph
7490 Commits
Author SHA1 Message Date
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
nda e796f13d2a [FIX] base_import_module: set module dependencies
Dependencies and other manifest attributes are not set for data modules.

Note: it's easier to reproduce issue in 17 since we have data module available
on runbot.

steps to reproduce (in 17.0):
- install an industry (ex: bar_and_lounge)
- uninstall a dependency of that module (ex: mrp)

before this commit:
- bar_and_lounge is not uninstalled if you uninstall mrp

after this commit:
- data model dependencies are handled the same way as 'regular' modules

opw-3660052

closes odoo/odoo#151256

X-original-commit: 12256bbc5981b06d7b77c133cc8f282ac03afba9
Signed-off-by: Nicolas Danhier (nda) <nda@odoo.com>
Signed-off-by: Pierre Masereel (pim) <pim@odoo.com>
2024-01-26 21:07:58 +00:00
Antoine Boonen acc6f10ed2 [IMP] base: Add Ugandian tax label
Uganda uses the label TIN on reports and invoices, which stands for
Taxpayer Identification Number. This commit adds this label to the base
module.

task-3340378

closes odoo/odoo#131877

Signed-off-by: Josse Colpaert <jco@odoo.com>
2024-01-26 21:07:50 +00:00
Rahul Prajapati 54639ae134 [FIX] base: autovacuum not working
This bug was introduced from this commit 21ca976

This commit fixes it.

closes odoo/odoo#151067

X-original-commit: a3d1b5b22ec172ca194621ee6a8d577d05aac5d0
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2024-01-25 15:25:00 +00:00
Andrew Gavgavian 6ce294fa52 [FIX] base: swap regen asset bundle to registry cache
Since [1] `model.clear_cache` is no longer recommended.
Most models were changed besides the function responsible
for regenerating asset bundles. This leads to a deprecation warning
when pressing the button in the debug menu in 16.4+

1: #119813
opw-3694331

closes odoo/odoo#150948

X-original-commit: ef0db39416c678a3a3e53ddb97971f87e912f44c
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Signed-off-by: Andrew Gavgavian (andg) <andg@odoo.com>
2024-01-24 23:07:11 +00:00
Julien Castiaux 05fd991389 [FIX] link_tracker: prevent links from linking themselves
It was technically possible to register a link that would loop on itself
by abusing the query and fragment parts of the URL. It was possible to
register a link targetting `#` and get the following HTTP exchange which
enter an infinite loop.

	GET /r/bAd HTTP/1.0

	HTTP/1.0 301 Redirect
	Location: #

	GET /r/bAd# HTTP/1.0

Prevent such links from being registered and highlight flaws inside the
`validate_url` method with unittests.

Part-of: odoo/odoo#150678
2024-01-24 10:44:40 +00:00
AH-Yussef ed95da37dc [FIX] base: translate partner display_name
Steps to reproduce:
- Install Contacts app
- Go to General Settings and add another language
- Add a new contact to a parent.
        - Don't add a specific contact name
        - Assign a contact type (delivery address, invoice address, other address)
- Go to the list or kanban view of the contancts and change the language
- The type of the contact listed next to the parent name is not translated from English.

Investigation:
- When the contact name is not set, the `display_name` displayed in both kanban and list views is set by concatinating the parent name with the contact type.
- The line https://github.com/odoo/odoo/blob/03b7e17faef4075dbbb805bca4e7f40f7fbcc988/odoo/addons/base/models/res_partner.py#L345 in the function `_compute_display_name`, `with_context({})` in particular basically enforce to compute the name in english language regardless of the active language. That actually makes sense as the `display_name` field has `store=True` https://github.com/odoo/odoo/blob/03b7e17faef4075dbbb805bca4e7f40f7fbcc988/odoo/addons/base/models/res_partner.py#L199

Solution:
- add a computed field that is not stored that gets recomputed on changing the language.

opw-3569171

closes odoo/odoo#147650

X-original-commit: 60b3ae846de59b1f6e71df68e99e29758ba734fe
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Signed-off-by: Ali Hassan Youssef (alhy) <alhy@odoo.com>
2024-01-24 10:44:36 +00:00
Nicolas Martinelli 85c06dd3ae [IMP] base: log job duration
Log the job duration of the usual `INFO` level for easier monitoring.

closes odoo/odoo#149881

Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2024-01-23 18:27:42 +00:00
Julien Castiaux 5a14c8d5a6 [FIX] mail: support hebrew charset iso-8859-8-i
One of our customers is receiving emails with headers and attachments
encoded using the "iso-8859-8-i" charset instead of "iso-8859-8" which
is natively supported by Python. Both encoding are using the same
character set[^1] and only differ in the way the text is rendered on
screen[^2][^3] which is not revelant for Python.

Add an alias for iso-8859-8-i so that the emails that this customer
receive stop failing in Odoo. Note that there is a PR opened on
CPython for exactly that, see [bpo-18624].

opw-3653210
[bpo-18624]: https://bugs.python.org/issue18624
[^1]: https://encoding.spec.whatwg.org/#legacy-single-byte-encodings
[^2]: <data:text/html;charset=iso-8859-8,hello%20%E0%E1%E2%E3>
[^3]: <data:text/html;charset=iso-8859-8-i,hello%20%E0%E1%E2%E3>

closes odoo/odoo#150467

X-original-commit: 5a025467a605ca4fa963b79bae254c823518d54c
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
2024-01-23 16:01:43 +00:00
Carsten Wolff (cawo) 683a51bd27 [FIX] http: close request resources when done
Currently, when a worker (process/thread) has finished processing a request, it
will keep handles on resources held by the werkzeug `Request` object. This
includes open filhandles to temporary files, e.g. those of uploaded files. On
platforms supporting `O_TMPFILE`, these files are not visible in the
filesystem, but keep using up space in `TMPDIR` until werkzeug finally closes
the file handles when the next Request is being handled.

In some contexts, e.g. the upgrade platform, it can happen that there are
multiple workers that only handle rare requests that upload big files (multiple
GiB), kept open after the upload has finished:
```shell
lsof -nP | grep -E 'odoo\/tmp.*(deleted)' | grep -vE 'GeoIP'
python3 213853                odoo 13u REG 252,3 1064251 926275 /home/odoo/tmp/#926275 (deleted)
python3 213853 213865 python3 odoo 13u REG 252,3 1064251 926275 /home/odoo/tmp/#926275 (deleted)
```
This can pose problems, because often the filesystem on `TMPDIR` is not very
large and idle workers holding on to large files can increase the chance for
ENOSPC.

This patch changes the behavior such that the resources held by the werkzeug
`Request` object are being closed[^1] after the response has been sent out.
This also has the advantage that this work is done at potentially idle time
instead of within handling the next request.

[^1]: https://werkzeug.palletsprojects.com/en/2.0.x/wrappers/#werkzeug.wrappers.Request.close

closes odoo/odoo#150029

X-original-commit: a920ddca57e7bf9353611396f1c0b1060c8cb044
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
2024-01-23 04:41:40 +00:00
Denis Ledoux ec0cd75328 [IMP] core: disable x2many manipulation as sudo for sensitive models
This revision adds a flag
`_allow_sudo_commands` to which models can opt-in
to protect themselves against malicious
manipulation of one2many or many2many fields
through an environment using `sudo` or a more priviledged user.

Flagging a model `_allow_sudo_commands = False`
disable `sudo` and `with_user(...)`
when manipulating a one2many or many2many
field targeting this model.

task-3695103
2023-11-01 08:05:16 +00:00